687 lines
34 KiB
Python
687 lines
34 KiB
Python
import time
|
|
import sys
|
|
sys.path.append('.')
|
|
|
|
from player import Player # Only import what's necessary
|
|
from enum_list import ItemType, Slots
|
|
from race_list import RACES
|
|
from class_list import CLASSES
|
|
|
|
|
|
def wait():
|
|
input("Press enter to continue...")
|
|
|
|
pre_generated_characters = {
|
|
"1": {
|
|
"name": "Arion", # Example Name
|
|
"gender": "Male",
|
|
"age": 25,
|
|
"race": RACES["Elf"],
|
|
"class_": CLASSES["Wizard"], # Based on the High Elf sheet
|
|
"alignment": "lawful good",
|
|
"description": "A scholarly High Elf skilled in the arcane arts.",
|
|
"stats": {
|
|
"Strength": 10, "Dexterity": 16, "Constitution": 12,
|
|
"Intelligence": 16, "Wisdom": 13, "Charisma": 8
|
|
},
|
|
"armor_class": "13 or 16 (mage armor)",
|
|
"hit_points": "7 (Hit Dice 1d6 + Con modifier)",
|
|
"speed": "30 ft.",
|
|
"proficiencies": {
|
|
"bonus": "+2",
|
|
"saving_throws": {"Int": "+5", "Wis": "+3"},
|
|
"advantage_on_saves": ["charmed"],
|
|
"skills": {"Arcana": "+5", "History": "+5", "Investigation": "+5", "Perception": "+3", "Persuasion": "+1"},
|
|
"armor": [], # None listed, just "None"
|
|
"weapons": ["Daggers", "darts", "slings", "quarterstaffs", "longswords", "shortswords", "shortbows", "longbows"],
|
|
"tools": []
|
|
}
|
|
},
|
|
"2": {
|
|
"name": "Brundle", # Example Name
|
|
"gender": "Female",
|
|
"age": 35,
|
|
"race": RACES["Human"],
|
|
"class_": CLASSES["Barbarian"], # Based on the Human sheet
|
|
"alignment": "chaotic good",
|
|
"description": "A robust Human warrior, charging into battle.",
|
|
"stats": {
|
|
"Strength": 16, "Dexterity": 9, "Constitution": 15,
|
|
"Intelligence": 13, "Wisdom": 11, "Charisma": 14
|
|
},
|
|
"armor_class": "18",
|
|
"hit_points": "12 (Hit Dice 1d10 + Con modifier))",
|
|
"speed": "30 ft.",
|
|
"proficiencies": {
|
|
"bonus": "+2",
|
|
"saving_throws": {"Str": "+5", "Con": "+4"},
|
|
"skills": {"Athletics": "+5", "History": "+3", "Intimidation": "+4", "Perception": "+2"},
|
|
"armor": ["All", "shields"],
|
|
"weapons": ["Simple", "martial"],
|
|
"tools": ["Gaming dice", "vehicles (land)"],
|
|
"senses": {"Passive Perception": "12"},
|
|
"languages": ["Common", "Orc"]
|
|
}
|
|
},
|
|
"3": {
|
|
"name": "Drok", # Example Name
|
|
"gender": "Other",
|
|
"age": 75, # Dwarves live longer
|
|
"race": RACES["Dwarf"],
|
|
"class_": CLASSES["Cleric"], # Based on the Hill Dwarf sheet (Life Domain implied by "healing" focus)
|
|
"alignment": "lawful good",
|
|
"description": "A stout Hill Dwarf cleric, a pillar of his community.",
|
|
"stats": {
|
|
"Strength": 14, "Dexterity": 8, "Constitution": 15,
|
|
"Intelligence": 10, "Wisdom": 16, "Charisma": 12
|
|
},
|
|
"armor_class": "18 (chain mail, shield)",
|
|
"hit_points": "10 (Hit Dice 1d8 + Con modifier))",
|
|
"speed": "25 ft.",
|
|
"proficiencies": {
|
|
"bonus": "+2",
|
|
"saving_throws": {"Wis": "+5", "Cha": "+3"},
|
|
"advantage_on_saves": ["poisoned"],
|
|
"skills": {"Insight": "+5", "Medicine": "+5", "Persuasion": "+3", "Religion": "+2"},
|
|
"armor": ["all armor", "shields"],
|
|
"weapons": ["battleaxe", "simple weapons", "warhammer"],
|
|
"tools": ["brewer's supplies", "jeweler's tools"],
|
|
"damage_resistances": ["poison"],
|
|
"senses": {"darkvision": "60 ft.", "passive_perception": "13"},
|
|
"languages": ["Common", "Dwarvish", "Giant"]
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
def startGame():
|
|
print("Welcome stranger, to the world of Kanjin!.")
|
|
# Loop for initial choice: Create or Pre-generated
|
|
while True:
|
|
start = input("Would you like to create your own character or use pre-generated stats?"
|
|
"\n 1) Create a new character\n 2) Quick Setup\n 3) Pre-Gen Character\n >> ")
|
|
if start in ("1", "Create"):
|
|
# --- Character Basic Info (Name, Gender, Age) ---
|
|
name, gender, age = None, None, None # Initialize
|
|
# Loop until basic info is confirmed
|
|
while True:
|
|
# Name
|
|
name = input('What is your name?\n >> ').title()
|
|
while len(name) < 2:
|
|
name = input('Name must be longer than one character. Try again.\nWhat is your name?\n >> ')
|
|
# Gender
|
|
while True:
|
|
gender_select = input("What is your gender?\n"
|
|
"1) Male\n2) Female\n3) Other\n >> ").lower()
|
|
if gender_select not in ("male", "female", "other", "1", "2", "3"):
|
|
print("Sorry I didn't recognise that gender. Please try again.")
|
|
continue
|
|
else:
|
|
break
|
|
if gender_select in ("1", "male"):
|
|
gender = "Male"
|
|
elif gender_select in ("2", "female"):
|
|
gender = "Female"
|
|
elif gender_select in ("3", "other"):
|
|
gender = "Other"
|
|
# Age
|
|
while True:
|
|
try:
|
|
age = int(input('How old are you?\n >> '))
|
|
break
|
|
except ValueError:
|
|
print("Sorry I didn't recognise that age. Please type in a whole number.")
|
|
continue
|
|
# Double check responses
|
|
correct = input(f"Hello, {name}.\nYou are a {age} year old {gender.lower()}.\nIs this correct? Y/N\n >> ")
|
|
if correct.lower() in ['y', 'yes']:
|
|
break # Exit basic info confirmation loop
|
|
elif correct.lower() in ['n', 'no']:
|
|
continue # Restart basic info input
|
|
else:
|
|
print("Sorry, I didn't catch that. Please try again.\n")
|
|
continue
|
|
|
|
# --- Race and Class Selection ---
|
|
race = None
|
|
class_ = None
|
|
# Loop until Race and Class are confirmed
|
|
while True:
|
|
# Race Selection
|
|
selected_race_obj = None
|
|
# Loop for selecting and viewing race
|
|
while True:
|
|
race_choice = input("Please select a race to learn more about it:\n"
|
|
"1) Elf\n2) Dwarf\n3) Human\n >> ").title()
|
|
if race_choice in ['Elf', '1']:
|
|
selected_race_obj = RACES["Elf"]
|
|
elif race_choice in ['Dwarf', '2']:
|
|
selected_race_obj = RACES["Dwarf"]
|
|
elif race_choice in ['Human', '3']:
|
|
selected_race_obj = RACES["Human"]
|
|
else:
|
|
print("Sorry I didn't recognise that race. Please select 'Elf', 'Dwarf', or 'Human'.\n")
|
|
continue
|
|
|
|
if selected_race_obj:
|
|
print(f"\n--- {selected_race_obj.name} ---")
|
|
print(selected_race_obj.__repr__())
|
|
print('Would you like to proceed with this race or view another?')
|
|
proceed = input('1) Proceed\n2) View another race\n >> ')
|
|
if proceed.lower() in ('1', 'proceed'):
|
|
race = selected_race_obj # Assign race object
|
|
break # Exit race selection loop
|
|
elif proceed.lower() in ('2', 'view', 'view another', 'view another race'):
|
|
continue # Restart race selection
|
|
else:
|
|
print("Sorry, I didn't catch that. Please try again.\n")
|
|
continue
|
|
|
|
# Class Selection
|
|
selected_class_obj = None
|
|
# Loop for selecting and viewing class
|
|
while True:
|
|
class_choice = input("Please select a class to learn more about it:\n"
|
|
"1) Barbarian\n2) Cleric\n3) Wizard\n >> ").title()
|
|
if class_choice in ['Barbarian', '1']:
|
|
selected_class_obj = CLASSES["Barbarian"]
|
|
elif class_choice in ['Cleric', '2']:
|
|
selected_class_obj = CLASSES["Cleric"]
|
|
elif class_choice in ['Wizard', '3']:
|
|
selected_class_obj = CLASSES["Wizard"]
|
|
else:
|
|
print("Sorry I didn't recognise that class. Please select 'Barbarian', 'Cleric', or 'Wizard'.\n")
|
|
continue
|
|
|
|
if selected_class_obj:
|
|
print(f"\n--- {selected_class_obj.name} ---")
|
|
print(selected_class_obj.__repr__())
|
|
|
|
print('Would you like to proceed with this class or view another?')
|
|
proceed = input('1) Proceed\n2) View another class\n >> ')
|
|
if proceed.lower() in ('1', 'proceed'):
|
|
class_ = selected_class_obj # Assign class object
|
|
break # Exit class selection loop
|
|
elif proceed.lower() in ('2', 'view', 'view another', 'view another class'):
|
|
continue # Restart class selection
|
|
else:
|
|
print("Sorry, I didn't catch that. Please try again.\n")
|
|
continue
|
|
|
|
# Final confirmation for both Race and Class
|
|
while True:
|
|
# This safeguard should ideally not be hit if inner loops work correctly
|
|
if race is None or class_ is None:
|
|
print("Error: Race or Class not selected. Restarting Race/Class selection.")
|
|
break # Break out of this inner loop to restart the outer race/class loop
|
|
correct = input(f"\n{name}, you are a {race.name_adjective} {class_.name}.\nIs this correct? Y/N\n >> ")
|
|
if correct.lower() in ['y', 'yes']:
|
|
return name, gender, age, race, class_, None# All confirmed, return values
|
|
elif correct.lower() in ['n', 'no']:
|
|
# If not correct, break this loop to re-enter race/class selection
|
|
break
|
|
else:
|
|
print("Sorry, I didn't catch that. Please try again.\n")
|
|
continue
|
|
|
|
elif start in ("2", "Quick Setup"):
|
|
print("Please be prepared to enter a name, gender, age, race, and class, from those available in the game."
|
|
"\nIf you are unsure what the options are, please go back and create a new character.")
|
|
create = input("Do you wish to continue? Y/N\n >> ").lower()
|
|
if create in ("y", "yes"):
|
|
name = input("Name: ")
|
|
gender = input("Gender (Male, Female, Other): ")
|
|
age = int(input("Age: "))
|
|
race_str = input("Race (Elf, Dwarf, Human): ")
|
|
class_str = input("Class (Barbarian, Cleric, Wizard): ")
|
|
|
|
# Map string inputs to actual Race/Class objects for consistency
|
|
race_map = {'elf': RACES["Elf"], 'dwarf': RACES["Dwarf"], 'human': RACES["Human"]}
|
|
class_map = {'barbarian': CLASSES["Barbarian"], 'cleric': CLASSES["Cleric"], 'wizard': CLASSES["Wizard"]}
|
|
|
|
actual_race = race_map.get(race_str.lower())
|
|
actual_class = class_map.get(class_str.lower())
|
|
|
|
if actual_race and actual_class:
|
|
return name, gender, age, actual_race, actual_class, None
|
|
else:
|
|
print("Invalid race or class entered for pre-generated character. Please try again.")
|
|
start = "1"
|
|
continue
|
|
return None
|
|
elif create in ("n", "no"):
|
|
# If 'n', re-prompt the initial choice.
|
|
start = input("Would you like to create your own character or use pre-generated stats?"
|
|
"\n 1) Create a new character\n 2) Quick Setup\n 3) Pre-Gen Character\n >> ")
|
|
continue
|
|
return None
|
|
else:
|
|
print("Invalid input. Please enter Y or N.")
|
|
# If invalid, re-prompt the initial choice.
|
|
start = input("Would you like to create your own character or use pre-generated stats?"
|
|
"\n 1) Create a new character\n 2) Quick Setup\n 3) Pre-Gen Character\n >> ")
|
|
continue
|
|
return None
|
|
elif start in ("3", "Pre-generated Character"):
|
|
while True:
|
|
print("Who would you like to to play?")
|
|
for key, char_data in pre_generated_characters.items():
|
|
print(
|
|
f"{key}) {char_data['name']} ({char_data['race'].name_adjective} {char_data['class_'].name}, {char_data['alignment']})")
|
|
print("Type 'back' to return to character creation options.")
|
|
|
|
char_choice = input(">> ").strip().lower()
|
|
|
|
if char_choice == "back":
|
|
break
|
|
|
|
if char_choice in pre_generated_characters:
|
|
selected_char_data = pre_generated_characters[char_choice]
|
|
|
|
# --- Display Character Details for Confirmation ---
|
|
print(f"\n--- {selected_char_data['name']}'s Details ---")
|
|
print(f"Name: {selected_char_data['name']}")
|
|
print(f"Gender: {selected_char_data['gender']}")
|
|
print(f"Age: {selected_char_data['age']}")
|
|
print(f"Race: {selected_char_data['race'].name_adjective}")
|
|
print(f"Class: {selected_char_data['class_'].name}")
|
|
print(f"Alignment: {selected_char_data['alignment']}")
|
|
print(f"Description: {selected_char_data['description']}")
|
|
print(f"Age: {selected_char_data['age']}")
|
|
print(f"\nArmor Class: {selected_char_data['armor_class']}")
|
|
print(f"Hit Points: {selected_char_data['hit_points']}")
|
|
print(f"Speed: {selected_char_data['speed']}")
|
|
|
|
print("\n--- Stats ---")
|
|
for stat_name, value in selected_char_data['stats'].items():
|
|
# Calculate modifier for display (assuming standard D&D rules)
|
|
modifier = (value - 10) // 2
|
|
modifier_sign = "+" if modifier >= 0 else ""
|
|
print(f"{stat_name}: {value} ({modifier_sign}{modifier})")
|
|
|
|
print("\n--- Proficiencies & Abilities ---")
|
|
print(f"Proficiency Bonus: {selected_char_data['proficiencies']['bonus']}")
|
|
print(
|
|
f"Saving Throws: {', '.join([f'{stat} {val}' for stat, val in selected_char_data['proficiencies']['saving_throws'].items()])}")
|
|
if selected_char_data['proficiencies'].get('advantage_on_saves'):
|
|
print(
|
|
f" Advantage on saves against: {', '.join(selected_char_data['proficiencies']['advantage_on_saves'])}")
|
|
print(
|
|
f"Skills: {', '.join([f'{skill} {val}' for skill, val in selected_char_data['proficiencies']['skills'].items()])}")
|
|
if selected_char_data['proficiencies'].get('armor'):
|
|
print(f"Armor Proficiencies: {', '.join(selected_char_data['proficiencies']['armor'])}")
|
|
if selected_char_data['proficiencies'].get('weapons'):
|
|
print(f"Weapon Proficiencies: {', '.join(selected_char_data['proficiencies']['weapons'])}")
|
|
if selected_char_data['proficiencies'].get('tools'):
|
|
print(f"Tool Proficiencies: {', '.join(selected_char_data['proficiencies']['tools'])}")
|
|
if selected_char_data['proficiencies'].get('damage_resistances'):
|
|
print(
|
|
f"Damage Resistances: {', '.join(selected_char_data['proficiencies']['damage_resistances'])}")
|
|
if selected_char_data['proficiencies'].get('senses'):
|
|
senses_str = []
|
|
if 'darkvision' in selected_char_data['proficiencies']['senses']:
|
|
senses_str.append(
|
|
f"Darkvision {selected_char_data['proficiencies']['senses']['darkvision']}")
|
|
if 'passive_perception' in selected_char_data['proficiencies']['senses']:
|
|
senses_str.append(
|
|
f"Passive Perception {selected_char_data['proficiencies']['senses']['passive_perception']}")
|
|
print(f"Senses: {', '.join(senses_str)}")
|
|
if selected_char_data['proficiencies'].get('languages'):
|
|
print(f"Languages: {', '.join(selected_char_data['proficiencies']['languages'])}")
|
|
|
|
while True:
|
|
print("\nDo you want to select this character?")
|
|
print("1) Yes, select this character")
|
|
print("2) No, go back to character selection")
|
|
confirm_choice = input(">> ").strip().lower()
|
|
|
|
if confirm_choice in ("1", "yes"):
|
|
name = selected_char_data['name']
|
|
gender = selected_char_data['gender']
|
|
age = selected_char_data['age']
|
|
race = selected_char_data['race']
|
|
class_ = selected_char_data['class_']
|
|
pre_allocated_stats = selected_char_data['stats']
|
|
|
|
print(f"\nYou have selected: {name}, a {age} year old {race.name_adjective} {class_.name}.")
|
|
return name, gender, age, race, class_, pre_allocated_stats # Exit all loops and function
|
|
|
|
elif confirm_choice in ("2", "no"):
|
|
print("\nReturning to pre-generated character selection.")
|
|
break # Break out of confirmation loop, go back to char_choice loop
|
|
else:
|
|
print("Invalid choice. Please enter '1', '2', 'yes', or 'no'.")
|
|
|
|
else:
|
|
print("Invalid selection. Please choose a number from the list or 'back'.")
|
|
continue
|
|
|
|
|
|
def query_equip(player: Player):
|
|
"""Allows the player to view or change equipped items."""
|
|
while True:
|
|
print("Do you want to:\n"
|
|
"1) View your equipped items\n"
|
|
"2) Change your equipped items\n"
|
|
"3) Return")
|
|
response = input(">> ")
|
|
if response == "1":
|
|
player.inventory.current_equipment()
|
|
elif response == "2":
|
|
change_equip(player)
|
|
elif response == "3":
|
|
break
|
|
|
|
def change_equip(player: Player):
|
|
"""Handles the process of changing equipped items."""
|
|
player.inventory.update_attunement() # Ensure attunement is up-to-date
|
|
while True:
|
|
response = input("Which equipment slot would you like to change?\n"
|
|
"1) Weapon\n"
|
|
"2) Armor\n"
|
|
"3) Other\n"
|
|
"4) Return\n"
|
|
">> ").title()
|
|
|
|
if response in ("1", "Weapon"):
|
|
# Filter weapons from inventory that are not currently equipped in weapon slots
|
|
itemlist = [item_obj for item_obj, item_data in player.inventory.items.items()
|
|
if item_data["object"] == ItemType.Weapon and
|
|
item_obj not in [player.inventory.equipped_items[Slots.MainHand],
|
|
player.inventory.equipped_items[Slots.OffHand],
|
|
player.inventory.equipped_items[Slots.TwoHanded]]]
|
|
itemlist.append("Return") # Add return option last
|
|
|
|
if not itemlist or (len(itemlist) == 1 and itemlist[0] == "Return"):
|
|
print("You have no unequipped weapons available in your inventory.\n")
|
|
else:
|
|
print("What would you like to equip?\n")
|
|
for i, item_obj in enumerate(itemlist, start=1):
|
|
if item_obj == "Return":
|
|
print(f'{i}) {item_obj}')
|
|
else:
|
|
print(f'{i}) {item_obj.name}')
|
|
|
|
try:
|
|
selection = int(input(">> "))
|
|
if 1 <= selection <= len(itemlist):
|
|
chosen_item = itemlist[selection - 1]
|
|
if chosen_item == "Return":
|
|
break
|
|
else:
|
|
# Determine the correct slot based on weapon type
|
|
if chosen_item.slot == Slots.TwoHanded:
|
|
player.inventory.equip_item(chosen_item, Slots.TwoHanded)
|
|
elif chosen_item.versatile: # For versatile, equip to main hand
|
|
player.inventory.equip_item(chosen_item, Slots.MainHand)
|
|
else: # Default to main hand for 1H weapons
|
|
player.inventory.equip_item(chosen_item, Slots.MainHand)
|
|
player.inventory.current_equipment()
|
|
else:
|
|
print("Invalid selection.")
|
|
except ValueError:
|
|
print("Invalid input. Please enter a number.")
|
|
|
|
elif response in ("2", "Armor"):
|
|
itemlist = [item_obj for item_obj, item_data in player.inventory.items.items()
|
|
if item_data["object"] == ItemType.Armor and
|
|
item_obj not in [player.inventory.equipped_items[Slots.Helm],
|
|
player.inventory.equipped_items[Slots.Armor],
|
|
player.inventory.equipped_items[Slots.Wrists],
|
|
player.inventory.equipped_items[Slots.Feet]]]
|
|
itemlist.append("Return")
|
|
|
|
if not itemlist or (len(itemlist) == 1 and itemlist[0] == "Return"):
|
|
print("You have no unequipped armor available in your inventory.\n")
|
|
else:
|
|
print("What would you like to equip?\n")
|
|
for i, item_obj in enumerate(itemlist, start=1):
|
|
if item_obj == "Return":
|
|
print(f'{i}) {item_obj}')
|
|
else:
|
|
print(f'{i}) {item_obj.name}')
|
|
|
|
try:
|
|
selection = int(input(">> "))
|
|
if 1 <= selection <= len(itemlist):
|
|
chosen_item = itemlist[selection - 1]
|
|
if chosen_item == "Return":
|
|
break
|
|
else:
|
|
# Logic for equipping armor based on its intended slot
|
|
if chosen_item.slot == Slots.Helm:
|
|
player.inventory.equip_item(chosen_item, Slots.Helm)
|
|
elif chosen_item.slot == Slots.Armor:
|
|
player.inventory.equip_item(chosen_item, Slots.Armor)
|
|
elif chosen_item.slot == Slots.Wrists:
|
|
player.inventory.equip_item(chosen_item, Slots.Wrists)
|
|
elif chosen_item.slot == Slots.Feet:
|
|
player.inventory.equip_item(chosen_item, Slots.Feet)
|
|
else:
|
|
print(f"This armor ({chosen_item.name}) doesn't seem to fit a standard slot.")
|
|
player.inventory.current_equipment()
|
|
else:
|
|
print("Invalid selection.")
|
|
except ValueError:
|
|
print("Invalid input. Please enter a number.")
|
|
|
|
elif response in ("3", "Other"):
|
|
itemlist = [item_obj for item_obj, item_data in player.inventory.items.items()
|
|
if item_data["object"] == ItemType.Item and
|
|
item_obj not in [player.inventory.equipped_items[Slots.Neck],
|
|
player.inventory.equipped_items[Slots.Cloak],
|
|
player.inventory.equipped_items[Slots.LeftRing],
|
|
player.inventory.equipped_items[Slots.RightRing],
|
|
player.inventory.equipped_items[Slots.Other]]]
|
|
itemlist.append("Return")
|
|
|
|
if not itemlist or (len(itemlist) == 1 and itemlist[0] == "Return"):
|
|
print("You have no other unequipped items available in your inventory.\n")
|
|
else:
|
|
print("What would you like to equip?\n")
|
|
for i, item_obj in enumerate(itemlist, start=1):
|
|
if item_obj == "Return":
|
|
print(f'{i}) {item_obj}')
|
|
else:
|
|
print(f'{i}) {item_obj.name}')
|
|
|
|
try:
|
|
selection = int(input(">> "))
|
|
if 1 <= selection <= len(itemlist):
|
|
chosen_item = itemlist[selection - 1]
|
|
if chosen_item == "Return":
|
|
break
|
|
else:
|
|
# Logic for equipping other items based on their intended slot
|
|
if chosen_item.slot == Slots.Neck:
|
|
player.inventory.equip_item(chosen_item, Slots.Neck)
|
|
elif chosen_item.slot == Slots.Cloak:
|
|
player.inventory.equip_item(chosen_item, Slots.Cloak)
|
|
elif chosen_item.slot == Slots.LeftRing:
|
|
player.inventory.equip_item(chosen_item, Slots.LeftRing)
|
|
elif chosen_item.slot == Slots.RightRing:
|
|
player.inventory.equip_item(chosen_item, Slots.RightRing)
|
|
elif chosen_item.slot == Slots.Other:
|
|
player.inventory.equip_item(chosen_item, Slots.Other)
|
|
else:
|
|
print(f"This item ({chosen_item.name}) doesn't seem to fit a standard 'other' slot.")
|
|
player.inventory.current_equipment()
|
|
else:
|
|
print("Invalid selection.")
|
|
except ValueError:
|
|
print("Invalid input. Please enter a number.")
|
|
|
|
elif response in ("4", "Return"):
|
|
break
|
|
else:
|
|
print("That wasn't an option.")
|
|
|
|
|
|
def get_instructions():
|
|
descrip1 = ("There are certain commands that will be available almost anytime you are able to type\n"
|
|
"such as viewing your inventory, checking your equipped items, and also changing them.\n"
|
|
"You can also view your stats including your current and max hp.\n")
|
|
descrip2 = ("Help - Prints this help message.\n"
|
|
"Check inventory | bag | backpack - Lists items you are carrying.\n"
|
|
" Can also just enter 'inventory | bag | backpack\n"
|
|
"Check equipment | equipped | items - Lists items you have equipped\n"
|
|
" Can also just enter 'equipment | equipped | items\n"
|
|
"Check stats or Check hitpoints | hp | health - Shows your stat block or current health details\n"
|
|
" Can also just enter 'stats | health | hitpoints | hp\n"
|
|
"Go *direction* - Each scene will give you available directions i.e North\n"
|
|
"Enter cave | house | room - maybe... TBC\n"
|
|
"Scene or Location - Replays the current area's details\n"
|
|
"Look around - lists the available items in your scene without displaying the scene description.\n"
|
|
"Examine | Open | Loot *object* - Provides details of an item, opens a container, or takes an object.\n"
|
|
"Spells | Spellbook - Lists your cantrips, known/preparable spells, prepared spells, and slots.\n"
|
|
"Cast *spell name* - Casts a cantrip or prepared spell.\n"
|
|
"Prepare | Unprepare *spell name* - Moves a spell in/out of your prepared list.\n"
|
|
"Rest - Long rest: restores HP and spell slots.\n"
|
|
"Check weight | carry | encumbrance - Shows carrying weight vs capacity.\n"
|
|
"Check currency | coins | gold - Shows coinage held and total gp value.")
|
|
print(descrip1)
|
|
time.sleep(3) # Reduced sleep for faster testing
|
|
print(descrip2)
|
|
|
|
|
|
def error_message():
|
|
print("That command was not recognised. Please try again.")
|
|
|
|
|
|
def parse(input_text):
|
|
command = input_text.lower()
|
|
object1 = None
|
|
remaining_words_index = None
|
|
words = input_text.split()
|
|
|
|
if not words: # Handle empty input
|
|
return "error", None
|
|
|
|
# Check for multi-word commands first to avoid partial matches
|
|
if len(words) >= 2:
|
|
if words[0] == "check" and words[1] in ("inventory", "bag", "backpack"):
|
|
command = "inventory"
|
|
return command, object1
|
|
elif words[0] == "check" and words[1] in ("equipment", "equipped", "items"):
|
|
command = "equipment"
|
|
return command, object1
|
|
elif words[0] == "check" and words[1] == "stats":
|
|
command = "stats"
|
|
return command, object1
|
|
elif words[0] == "check" and words[1] in ("hp", "hitpoints", "health"):
|
|
command = "hp"
|
|
return command, object1
|
|
elif words[0] in ("go", "enter", "exit"):
|
|
command = "go"
|
|
object1 = " ".join(words[1:]) # The rest of the words are the direction
|
|
return command, object1
|
|
elif words[0] == "pick" and words[1] == "up" and len(words) > 2:
|
|
command = "take"
|
|
object1 = " ".join(words[2:])
|
|
return command, object1
|
|
elif words[0] == "look" and words[1] == "around" and len(words) == 2:
|
|
command = "look_around"
|
|
return command, object1
|
|
elif words[0] == "exit" and words[1] == "tutorial" and len(words) == 2:
|
|
command = "go"
|
|
object1 = " ".join(words[1:])
|
|
return command, object1
|
|
elif words[0] == "cast":
|
|
command = "cast"
|
|
object1 = " ".join(words[1:])
|
|
return command, object1
|
|
elif words[0] == "prepare":
|
|
command = "prepare"
|
|
object1 = " ".join(words[1:])
|
|
return command, object1
|
|
elif words[0] == "unprepare":
|
|
command = "unprepare"
|
|
object1 = " ".join(words[1:])
|
|
return command, object1
|
|
elif words[0] == "check" and words[1] in ("weight", "carry", "encumbrance"):
|
|
command = "weight"
|
|
return command, object1
|
|
elif words[0] == "check" and words[1] in ("currency", "coins", "gold", "money"):
|
|
command = "currency"
|
|
return command, object1
|
|
|
|
# Single-word commands
|
|
if words[0] == "help":
|
|
command = "help"
|
|
elif words[0] in ("scene", "location"):
|
|
command = "scene"
|
|
elif words[0] in ("inventory", "bag", "backpack"):
|
|
command = "inventory"
|
|
elif words[0] in ("equipped", "equipment"):
|
|
command = "equipment"
|
|
elif words[0] == "stats":
|
|
command = "stats"
|
|
elif words[0] in ("hp", "hitpoints", "health"):
|
|
command = "hp"
|
|
elif words[0] == "examine":
|
|
if len(words) > 1:
|
|
command = "examine"
|
|
object1 = " ".join(words[1:])
|
|
else:
|
|
command = "examine" # User needs to specify what to examine
|
|
object1 = None
|
|
elif words[0] == "take":
|
|
if len(words) > 1:
|
|
command = "take"
|
|
object1 = " ".join(words[1:])
|
|
else:
|
|
command = "take" # User needs to specify what to take
|
|
object1 = None
|
|
elif words[0] == "loot":
|
|
if len(words) > 1:
|
|
command = "loot"
|
|
object1 = " ".join(words[1:])
|
|
else:
|
|
command = "loot" # User needs to specify what to loot
|
|
object1 = None
|
|
elif words[0] == "open":
|
|
if len(words) > 1:
|
|
command = "open"
|
|
object1 = " ".join(words[1:])
|
|
else:
|
|
command = "open" # User needs to specify what to open
|
|
object1 = None
|
|
elif words[0] == "drop":
|
|
if len(words) > 1:
|
|
command = "drop"
|
|
object1 = " ".join(words[1:])
|
|
else:
|
|
command = "drop" # User needs to specify what to drop
|
|
object1 = None
|
|
|
|
elif words[0] in ("spells", "spellbook"):
|
|
command = "spells"
|
|
elif words[0] == "rest":
|
|
command = "rest"
|
|
elif words[0] in ("weight", "carry", "encumbrance"):
|
|
command = "weight"
|
|
elif words[0] in ("currency", "coins", "gold", "money"):
|
|
command = "currency"
|
|
elif words[0] == "quit":
|
|
command = "quit"
|
|
else:
|
|
command = "error" # Default for unrecognized commands
|
|
|
|
return command, object1
|
|
|
|
# def skill_check(skill):
|
|
# """Roll a d20 and add modifier
|
|
# Return value to compare vs a hardcoded DC"""
|
|
#
|
|
#
|
|
# def roll_dice(num_dice):
|
|
# roll_results = []
|
|
# for _ in range(num_dice):
|
|
# roll = randint(*user.hitDie)
|
|
# roll_results.append(roll)
|
|
# return roll_results
|
|
|
|
|
|
def calc_weight():
|
|
pass # Placeholder for future weight calculation
|