Add Container class with lock/trap detection, corpse drops, and numbered duplicate corpses
This commit is contained in:
90
scene.py
90
scene.py
@@ -5,6 +5,36 @@ sys.path.append('.')
|
||||
from player import Item, Weapon, Armor, rock, dagger, polearm, tornRags, paper, GP1, SP1, CP1
|
||||
from enum_list import *
|
||||
|
||||
class Container:
|
||||
def __init__(self, name, description, lock_dc=None, trap_dc=None):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.lock_dc = lock_dc
|
||||
self.trap_dc = trap_dc
|
||||
self.trap_disarmed = False
|
||||
self.contents = {}
|
||||
|
||||
@property
|
||||
def is_locked(self):
|
||||
return self.lock_dc is not None
|
||||
|
||||
@property
|
||||
def is_trapped(self):
|
||||
return self.trap_dc is not None
|
||||
|
||||
def add_item(self, item_obj, count=1):
|
||||
self.contents[item_obj] = self.contents.get(item_obj, 0) + count
|
||||
|
||||
def remove_item(self, item_obj, count=1):
|
||||
if item_obj in self.contents:
|
||||
self.contents[item_obj] -= count
|
||||
if self.contents[item_obj] <= 0:
|
||||
del self.contents[item_obj]
|
||||
|
||||
def has_items(self):
|
||||
return bool(self.contents)
|
||||
|
||||
|
||||
class Scene:
|
||||
"""
|
||||
Represents a single location or area in the game.
|
||||
@@ -45,15 +75,12 @@ class Scene:
|
||||
return self.exits.get(direction.lower())
|
||||
|
||||
def add_lootable_item(self, container_name, item_obj, count=1):
|
||||
"""
|
||||
Adds an item to a lootable container within the scene.
|
||||
:param container_name: The name of the container (e.g., "chest", "goblin corpse").
|
||||
:param item_obj: The Item object to add.
|
||||
:param count: The quantity of the item.
|
||||
"""
|
||||
if container_name not in self.lootable_items:
|
||||
self.lootable_items[container_name] = {}
|
||||
self.lootable_items[container_name][item_obj] = self.lootable_items[container_name].get(item_obj, 0) + count
|
||||
self.lootable_items[container_name] = Container(container_name, "")
|
||||
self.lootable_items[container_name].add_item(item_obj, count)
|
||||
|
||||
def add_container(self, container):
|
||||
self.lootable_items[container.name] = container
|
||||
|
||||
def add_available_item(self, item_obj, count=1):
|
||||
"""
|
||||
@@ -75,18 +102,31 @@ class Scene:
|
||||
del self.available_items[item_obj]
|
||||
|
||||
def remove_lootable_item(self, container_name, item_obj, count=1):
|
||||
if container_name in self.lootable_items:
|
||||
self.lootable_items[container_name].remove_item(item_obj, count)
|
||||
if not self.lootable_items[container_name].has_items():
|
||||
del self.lootable_items[container_name]
|
||||
|
||||
def add_corpse(self, enemy_name, items):
|
||||
"""Creates a lootable corpse from a defeated enemy.
|
||||
Multiple corpses of the same enemy are numbered: 'spider corpse', 'spider corpse 2', etc.
|
||||
items: dict of {item_obj: count} or iterable of (item_obj, count) pairs.
|
||||
"""
|
||||
Removes a specified count of an item from a lootable container in the scene.
|
||||
:param container_name: The name of the container.
|
||||
:param item_obj: The Item object to remove.
|
||||
:param count: The quantity to remove.
|
||||
"""
|
||||
if container_name in self.lootable_items and item_obj in self.lootable_items[container_name]:
|
||||
self.lootable_items[container_name][item_obj] -= count
|
||||
if self.lootable_items[container_name][item_obj] <= 0:
|
||||
del self.lootable_items[container_name][item_obj]
|
||||
if not self.lootable_items[container_name]: # If container is empty, remove it
|
||||
del self.lootable_items[container_name]
|
||||
base_name = f"{enemy_name.lower()} corpse"
|
||||
name = base_name
|
||||
counter = 1
|
||||
while name in self.lootable_items:
|
||||
counter += 1
|
||||
name = f"{base_name} {counter}"
|
||||
|
||||
corpse = Container(name, f"The lifeless body of a {enemy_name}.")
|
||||
if isinstance(items, dict):
|
||||
for item_obj, count in items.items():
|
||||
corpse.add_item(item_obj, count)
|
||||
else:
|
||||
for item_obj, count in items:
|
||||
corpse.add_item(item_obj, count)
|
||||
self.lootable_items[name] = corpse
|
||||
|
||||
|
||||
# --- Default Scenes ---
|
||||
@@ -112,9 +152,9 @@ tutorial = Scene(
|
||||
)
|
||||
tutorial.add_available_item(rock, 1)
|
||||
tutorial.add_available_item(paper, 2)
|
||||
tutorial.add_lootable_item("suspicious tree trunk", Item("Test Item",
|
||||
"This is for testing purposes", None,
|
||||
False, ItemType.Item, False), 1)
|
||||
tutorial_trunk = Container("suspicious tree trunk", "A hollow tree trunk with a small gap in the bark.")
|
||||
tutorial_trunk.add_item(Item("Test Item", "This is for testing purposes", None, False, ItemType.Item, False), 1)
|
||||
tutorial.add_container(tutorial_trunk)
|
||||
|
||||
# Scene 1: Starting Clearing
|
||||
starting_clearing = Scene(
|
||||
@@ -125,8 +165,10 @@ starting_clearing = Scene(
|
||||
"You notice a small, weathered wooden chest near a fallen log."
|
||||
)
|
||||
starting_clearing.add_available_item(rock, 3) # Rocks lying on the ground
|
||||
starting_clearing.add_lootable_item("small wooden chest", GP1, 15)
|
||||
starting_clearing.add_lootable_item("small wooden chest", SP1, 20)
|
||||
starting_clearing_chest = Container("small wooden chest", "A small, weathered wooden chest with rusty iron bands.")
|
||||
starting_clearing_chest.add_item(GP1, 15)
|
||||
starting_clearing_chest.add_item(SP1, 20)
|
||||
starting_clearing.add_container(starting_clearing_chest)
|
||||
|
||||
|
||||
# Scene 2: Forest Path
|
||||
|
||||
Reference in New Issue
Block a user