Add Container class with lock/trap detection, corpse drops, and numbered duplicate corpses
This commit is contained in:
139
main.py
139
main.py
@@ -1,4 +1,5 @@
|
||||
import sys
|
||||
from random import randint
|
||||
# Add the current directory to sys.path to allow imports from sibling files
|
||||
sys.path.append('.')
|
||||
from player import Player
|
||||
@@ -36,8 +37,8 @@ class Engine:
|
||||
# Display lootable containers
|
||||
if self.current_scene.lootable_items:
|
||||
print("\nYou also notice:")
|
||||
for container_name, items_in_container in self.current_scene.lootable_items.items():
|
||||
if any(count > 0 for count in items_in_container.values()): # Check if container has any items left
|
||||
for container_name, container in self.current_scene.lootable_items.items():
|
||||
if container.has_items():
|
||||
print(f" - {container_name.title()}")
|
||||
|
||||
def look_around(self):
|
||||
@@ -53,8 +54,8 @@ class Engine:
|
||||
# Display lootable containers
|
||||
if self.current_scene.lootable_items:
|
||||
print("\nYou also notice:")
|
||||
for container_name, items_in_container in self.current_scene.lootable_items.items():
|
||||
if any(count > 0 for count in items_in_container.values()): # Check if container has any items left
|
||||
for container_name, container in self.current_scene.lootable_items.items():
|
||||
if container.has_items():
|
||||
print(f" - {container_name.title()}")
|
||||
|
||||
|
||||
@@ -116,19 +117,45 @@ class Engine:
|
||||
if not found_in_scene:
|
||||
# Check lootable containers in the current scene
|
||||
found_in_loot = False
|
||||
for container_name, items_in_container in self.current_scene.lootable_items.items():
|
||||
if object_name.lower() in container_name.lower(): # If user tries to examine the container itself
|
||||
print(f"\nYou examine the {container_name}. Inside, you see:")
|
||||
if items_in_container:
|
||||
for item_obj, count in items_in_container.items():
|
||||
if count > 0:
|
||||
print(f" - {item_obj.name} (x{count})")
|
||||
else:
|
||||
print("It appears to be empty.")
|
||||
found_in_loot = True
|
||||
break # Exit after examining the container
|
||||
for container_name, container in self.current_scene.lootable_items.items():
|
||||
if object_name.lower() in container_name.lower():
|
||||
print(f"\n--- {container.name.title()} ---")
|
||||
print(container.description)
|
||||
|
||||
for item_obj, count in items_in_container.items():
|
||||
int_mod = self.player.mods["Intelligence"]
|
||||
noticed_something = False
|
||||
|
||||
if container.lock_dc:
|
||||
roll = randint(1, 20) + int_mod
|
||||
print(f"\nInvestigation check: 1d20{int_mod:+} = {roll} vs DC {container.lock_dc}")
|
||||
if roll >= container.lock_dc:
|
||||
print("It appears to be locked.")
|
||||
noticed_something = True
|
||||
elif not container.trap_dc:
|
||||
print("You don't notice anything unusual about it.")
|
||||
|
||||
if container.trap_dc:
|
||||
roll = randint(1, 20) + int_mod
|
||||
print(f"\nInvestigation check: 1d20{int_mod:+} = {roll} vs DC {container.trap_dc}")
|
||||
if roll >= container.trap_dc:
|
||||
print("You notice a trap mechanism on it.")
|
||||
container.trap_detected = True
|
||||
noticed_something = True
|
||||
elif not container.lock_dc and not noticed_something:
|
||||
print("You don't notice anything unusual about it.")
|
||||
|
||||
if not container.is_locked:
|
||||
if container.contents:
|
||||
print("\nInside, you see:")
|
||||
for item_obj, count in container.contents.items():
|
||||
if count > 0:
|
||||
print(f" - {item_obj.name} (x{count})")
|
||||
else:
|
||||
print("It appears to be empty.")
|
||||
found_in_loot = True
|
||||
break
|
||||
|
||||
for item_obj, count in container.contents.items():
|
||||
if object_name.lower() in item_obj.name.lower() and count > 0:
|
||||
print(f"\n--- {item_obj.name} ---")
|
||||
print(item_obj.description)
|
||||
@@ -185,22 +212,32 @@ class Engine:
|
||||
|
||||
def loot_container(self, container_name):
|
||||
"""Allows the player to loot items from a specified container."""
|
||||
container_found = False
|
||||
for current_container_name, items_in_container in list(self.current_scene.lootable_items.items()):
|
||||
if current_container_name.lower() == container_name.lower():
|
||||
container_found = True
|
||||
if not items_in_container:
|
||||
for current_name, container in list(self.current_scene.lootable_items.items()):
|
||||
if current_name.lower() == container_name.lower():
|
||||
if container.is_locked:
|
||||
print(f"The {container_name} is locked.")
|
||||
return
|
||||
|
||||
if container.is_trapped and not container.trap_disarmed:
|
||||
if container.trap_detected:
|
||||
print(f"The {container_name} is trapped. You'll need to disable the trap first.")
|
||||
return
|
||||
else:
|
||||
print(f"You open the {container_name}. A trap is triggered!")
|
||||
# TODO: trap damage/effects
|
||||
return
|
||||
|
||||
if not container.contents:
|
||||
print(f"The {container_name} is empty.")
|
||||
return
|
||||
|
||||
print(f"You look inside the {container_name}. You see:")
|
||||
loot_list = list(items_in_container.items())
|
||||
loot_list = list(container.contents.items())
|
||||
|
||||
while True:
|
||||
for i, (item_obj, count) in enumerate(loot_list, 1):
|
||||
print(f"{i}) {item_obj.name} (x{count})")
|
||||
|
||||
|
||||
take_all_option = len(loot_list) + 1
|
||||
leave_option = len(loot_list) + 2
|
||||
|
||||
@@ -209,13 +246,14 @@ class Engine:
|
||||
|
||||
choice = input("What would you like to take? (number or 'take all'/'leave')\n>> ").lower().strip()
|
||||
|
||||
|
||||
if choice == "take all" or (choice.isdigit() and int(choice) == take_all_option):
|
||||
for item_obj, count in list(items_in_container.items()):
|
||||
for item_obj, count in list(container.contents.items()):
|
||||
self.player.inventory.add_item(item_obj, count)
|
||||
print(f"- Took {count} {item_obj.name}")
|
||||
del items_in_container[item_obj]
|
||||
container.remove_item(item_obj, count)
|
||||
print(f"The {container_name} is now empty.")
|
||||
if not container.has_items():
|
||||
del self.current_scene.lootable_items[current_name]
|
||||
return
|
||||
elif choice == "leave" or (choice.isdigit() and int(choice) == leave_option):
|
||||
print(f"You leave the {container_name} untouched.")
|
||||
@@ -239,18 +277,16 @@ class Engine:
|
||||
|
||||
if 0 < take_count <= current_count:
|
||||
self.player.inventory.add_item(item_obj, take_count)
|
||||
items_in_container[item_obj] -= take_count
|
||||
container.remove_item(item_obj, take_count)
|
||||
print(f"You took {take_count} {item_obj.name}.")
|
||||
|
||||
if items_in_container[item_obj] <= 0:
|
||||
del items_in_container[item_obj]
|
||||
loot_list = list(items_in_container.items())
|
||||
if item_obj not in container.contents:
|
||||
loot_list = list(container.contents.items())
|
||||
|
||||
if not items_in_container:
|
||||
print(f"The {container_name} is now empty.")
|
||||
return
|
||||
elif not loot_list:
|
||||
if not container.contents:
|
||||
print(f"The {container_name} is now empty.")
|
||||
if not container.has_items():
|
||||
del self.current_scene.lootable_items[current_name]
|
||||
return
|
||||
else:
|
||||
print("Invalid amount or not enough items.")
|
||||
@@ -260,8 +296,7 @@ class Engine:
|
||||
print("Invalid selection. Please enter a number, 'take all', or 'leave'.")
|
||||
return
|
||||
|
||||
if not container_found:
|
||||
print(f"You don't see a '{container_name}' here to loot.")
|
||||
print(f"You don't see a '{container_name}' here to loot.")
|
||||
|
||||
|
||||
# Initialize the game engine
|
||||
@@ -272,10 +307,10 @@ def main_game_loop():
|
||||
The main loop for the game, handling character creation and continuous gameplay.
|
||||
"""
|
||||
# Character Creation
|
||||
name, gender, age, race, job, pre_allocated_stats = startGame()
|
||||
name, gender, age, race, class_, pre_allocated_stats = startGame()
|
||||
|
||||
# Create player instance
|
||||
player = Player(name, gender, age, race, job)
|
||||
player = Player(name, gender, age, race, class_)
|
||||
game_engine.set_player(player) # Set the player in the game engine
|
||||
|
||||
# Display initial character summary
|
||||
@@ -286,13 +321,16 @@ def main_game_loop():
|
||||
# For 'Pre-generated Character'
|
||||
game_engine.player.stats = pre_allocated_stats
|
||||
game_engine.player.getModifier()
|
||||
game_engine.player.set_stats_job() # Still need to set HP based on job and Con modifier
|
||||
game_engine.player.set_stats_class() # Still need to set HP based on class and Con modifier
|
||||
game_engine.player.current_stats() # Display stats after setting them
|
||||
print(' ')
|
||||
game_engine.player.inventory.current_equipment()
|
||||
print(' ')
|
||||
game_engine.player.inventory.current_inventory()
|
||||
print(' ')
|
||||
if game_engine.player.class_.is_caster:
|
||||
game_engine.player.print_spellbook()
|
||||
print(' ')
|
||||
|
||||
wait()
|
||||
print("\nYour adventure begins...")
|
||||
@@ -340,6 +378,29 @@ def main_game_loop():
|
||||
elif command == "go":
|
||||
direction = obj1
|
||||
game_engine.move_to_scene(direction)
|
||||
elif command == "spells":
|
||||
game_engine.player.print_spellbook()
|
||||
elif command == "cast":
|
||||
if obj1:
|
||||
game_engine.player.cast_spell(obj1)
|
||||
else:
|
||||
print("What would you like to cast?")
|
||||
elif command == "prepare":
|
||||
if obj1:
|
||||
game_engine.player.prepare_spell(obj1)
|
||||
else:
|
||||
print("What would you like to prepare?")
|
||||
elif command == "unprepare":
|
||||
if obj1:
|
||||
game_engine.player.unprepare_spell(obj1)
|
||||
else:
|
||||
print("What would you like to unprepare?")
|
||||
elif command == "rest":
|
||||
game_engine.player.long_rest()
|
||||
elif command == "weight":
|
||||
game_engine.player.carry_report()
|
||||
elif command == "currency":
|
||||
game_engine.player.currency_report()
|
||||
elif command == "quit":
|
||||
print("Thanks for playing!")
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user