Browse Source

Added subclass functionality

main
suzan 2 weeks ago
parent
commit
248f66e4f0
  1. 177
      creation_engine.py
  2. 1
      main.py
  3. 181
      races.json

177
creation_engine.py

@ -1,10 +1,10 @@
import random import random
import json import json
#TODO 5 AC? Or Gold Start no AC? # TODO AC? Or Gold Start no AC?
#TODO 6 Sub Classes? # TODO Feats?
VOWELS = ["A","E","I","O","U"] VOWELS = ["A", "E", "I", "O", "U"]
SKILL_LIST = ["acrobatics", "animal_handling", "arcana", "athletics", "deception", "history", "insight", "intimidation", SKILL_LIST = ["acrobatics", "animal_handling", "arcana", "athletics", "deception", "history", "insight", "intimidation",
"investigation", "medicine", "nature", "perception", "performance", "persuasion", "religion", "investigation", "medicine", "nature", "perception", "performance", "persuasion", "religion",
@ -12,19 +12,21 @@ SKILL_LIST = ["acrobatics", "animal_handling", "arcana", "athletics", "deception
ATTRIBUTE_LIST = ["strength", "dexterity", "wisdom", "constitution", "intelligence", "charisma"] ATTRIBUTE_LIST = ["strength", "dexterity", "wisdom", "constitution", "intelligence", "charisma"]
CLASS_LIST = ["Artificer","Barbarian","Bard","Cleric","Druid","Fighter","Monk","Paladin", CLASS_LIST = ["Artificer", "Barbarian", "Bard", "Cleric", "Druid", "Fighter", "Monk", "Paladin",
"Ranger","Rogue","Sorcerer","Warlock","Wizard","Blood Hunter"] "Ranger", "Rogue", "Sorcerer", "Warlock", "Wizard", "Blood Hunter"]
BACKGROUND_LIST = ["Acolyte", "Charlatan", "Criminal / Spy", "Entertainer", "Folk Hero", "Gladiator", BACKGROUND_LIST = ["Acolyte", "Charlatan", "Criminal / Spy", "Entertainer", "Folk Hero", "Gladiator",
"Guild Artisan / Guild Merchant", "Hermit", "Knight", "Noble", "Outlander", "Pirate", "Sage", "Guild Artisan / Guild Merchant", "Hermit", "Knight", "Noble", "Outlander", "Pirate", "Sage",
"Sailor", "Soldier", "Urchin",] "Sailor", "Soldier", "Urchin", ]
instrument_list = ["Bagpipes", "Birdpipes", "Clarinet", "Drum", "Dulcimer", "Fiddle", "Flute", "Glaur", "Hand Drum", instrument_list = ["Bagpipes", "Birdpipes", "Clarinet", "Drum", "Dulcimer", "Fiddle", "Flute", "Glaur", "Hand Drum",
"Harp", "Horn", "Longhorn", "Lute", "Lyre", "Pan Flute", "Shawm", "Songhorn", "Tantan", "Thelarr", "Harp", "Horn", "Longhorn", "Lute", "Lyre", "Pan Flute", "Shawm", "Songhorn", "Tantan", "Thelarr",
"Tocken", "Trumpet", "Viol", "Wargong", "Yarting", "Zulkoon"] "Tocken", "Trumpet", "Viol", "Wargong", "Yarting", "Zulkoon"]
languages = ["Aarakocra", "Abyssal", "Aquan"," Auran", "Celestial", "Deep Speech", "Draconic", "Dwarvish", "Elvish", "Giant", languages = ["Aarakocra", "Abyssal", "Aquan", "Auran", "Celestial", "Deep Speech", "Draconic", "Dwarvish", "Elvish",
"Gith", "Gnomish", "Goblin", "Halfling", "Infernal", "Orc", "Primordial", "Sylvan", "Undercommon", "Vedalken"] "Giant",
"Gith", "Gnomish", "Goblin", "Halfling", "Infernal", "Orc", "Primordial", "Sylvan", "Undercommon",
"Vedalken"]
known_language_list = ["Common"] known_language_list = ["Common"]
@ -35,17 +37,29 @@ ARTISANS_TOOLS = ["Alchemist's Supplies", "Brewer's Supplies", "Calligrapher's S
"Jeweler's Tools", "Leatherworker's Tools", "Mason's Tools", "Painter's Supplies", "Potter's Tools", "Jeweler's Tools", "Leatherworker's Tools", "Mason's Tools", "Painter's Supplies", "Potter's Tools",
"Smith's Tools", "Tinker's Tools", "Weaver's Tools", "Woodcarver's Tools"] "Smith's Tools", "Tinker's Tools", "Weaver's Tools", "Woodcarver's Tools"]
CLERIC_SUBCLASSES = ["Life Domain", "Knowledge Domain", "Light Domain", "Nature Domain", "Tempest Domain",
"Trickery Domain", "War Domain", "Death Domain", "Arcana Domain", "Forge Domain", "Grave Domain",
"Twilight Domain", "Peace Domain", "Order Domain"]
SORCERER_SUBCLASSES = ["Aberrant Mind", "Clockwork Soul", "Divine Soul", "Draconic Bloodline", "Lunar Sorcery",
"Shadow Magic", "Storm Sorcery", "Wild Magic"]
WIZARD_SUBCLASSES = ["Bladesinging", "Chronurgy Magic", "Graviturgy Magic", "Order of Scribes", "School of Abjuration",
"School of Conjuration", "School of Divination", "School of Enchantment", "School of Evocation",
"School of Illusion", "School of Necromancy", "School of Transmutation", "War Magic"]
class HeroCreation: class HeroCreation:
def __init__(self): def __init__(self):
self.name_generation() self.name_generation()
self.race_selection() self.race_selection()
self.race = self.race_string["Race"] self.race = self.race_string["Race"]
#'job' is used in place of 'class' to avoid a function conflict # 'job' is used in place of 'class' to avoid a function conflict
self.job = random.choice(CLASS_LIST) self.job = random.choice(CLASS_LIST)
self.job_characteristics() self.job_characteristics()
self.background = random.choice(BACKGROUND_LIST) self.background = random.choice(BACKGROUND_LIST)
self.stat_rolls() self.stat_rolls()
self.racial_bonuses() self.racial_bonuses()
self.speed = self.race_string["Speed"]
self.article = self.grammar() self.article = self.grammar()
self.skill_generation() self.skill_generation()
self.skill_proficiency() self.skill_proficiency()
@ -57,9 +71,8 @@ class HeroCreation:
self.job_proficiencies() self.job_proficiencies()
self.background_proficiencies() self.background_proficiencies()
self.finalize_languages() self.finalize_languages()
self.apply_skill_modifiers("dexterity","initiative") self.apply_skill_modifiers("dexterity", "initiative")
self.whoami = (f"Your new character is {self.name}, {self.article} {self.race} {self.job}, with the " self.whoami()
f"{self.background} background.\n")
self.stat_block = (f"Stat Block\n----------\nCharisma: {self.charisma}\nConstitution: {self.constitution}\n" self.stat_block = (f"Stat Block\n----------\nCharisma: {self.charisma}\nConstitution: {self.constitution}\n"
f"Dexterity: {self.dexterity}\nIntelligence: {self.intelligence}\n" f"Dexterity: {self.dexterity}\nIntelligence: {self.intelligence}\n"
f"Strength: {self.strength}\nWisdom: {self.wisdom}\n") f"Strength: {self.strength}\nWisdom: {self.wisdom}\n")
@ -69,23 +82,26 @@ class HeroCreation:
f"Intelligence Save: {self.intelligence_save}\n" f"Intelligence Save: {self.intelligence_save}\n"
f"Strength Save: {self.strength_save}\n" f"Strength Save: {self.strength_save}\n"
f"Wisdom Save: {self.wisdom_save}\n") f"Wisdom Save: {self.wisdom_save}\n")
self.additional_stats = (f"Additional Stats\n----------\nStarting HP: {self.starting_hp}\nHit Die: {self.hit_die}\n" self.additional_stats = (
f"Initiative Bonus: {self.initiative}\n") f"Additional Stats\n----------\nStarting HP: {self.starting_hp}\nHit Die: {self.hit_die}\n"
self.skill_bonuses = (f"Skill Bonuses\n----------\nAcrobatics: {self.acrobatics}\nAnimal Handling: {self.animal_handling}" f"Initiative Bonus: {self.initiative}\nSpeed: {self.speed}\n")
f"\nArcana: {self.arcana}\nAthletics: {self.athletics}\nDeception: {self.deception}" self.skill_bonuses = (
f"\nHistory: {self.history}\nInsight: {self.insight}\nIntimidation: {self.intimidation}" f"Skill Bonuses\n----------\nAcrobatics: {self.acrobatics}\nAnimal Handling: {self.animal_handling}"
f"\nInvestigation: {self.investigation}\nMedicine: {self.medicine}\nNature: {self.nature}" f"\nArcana: {self.arcana}\nAthletics: {self.athletics}\nDeception: {self.deception}"
f"\nPerception: {self.perception}\nPerformance: {self.performance}\nPersuasion: {self.persuasion}" f"\nHistory: {self.history}\nInsight: {self.insight}\nIntimidation: {self.intimidation}"
f"\nReligion: {self.religion}\nSleight of Hand: {self.sleight_of_hand}" f"\nInvestigation: {self.investigation}\nMedicine: {self.medicine}\nNature: {self.nature}"
f"\nStealth: {self.stealth}\nSurvival: {self.survival}\n") f"\nPerception: {self.perception}\nPerformance: {self.performance}\nPersuasion: {self.persuasion}"
f"\nReligion: {self.religion}\nSleight of Hand: {self.sleight_of_hand}"
f"\nStealth: {self.stealth}\nSurvival: {self.survival}\n")
self.other_proficiencies = (f"Additional Proficiencies\n----------\n" self.other_proficiencies = (f"Additional Proficiencies\n----------\n"
f"Languages: {self.languages}\n" f"Languages: {self.languages}\n"
f"Instruments: {self.instruments}\n" f"Instruments: {self.instruments}\n"
f"Artisan's Tools: {self.artisan_tools}\nAdditional Tools: {self.additional_tools}\n" f"Artisan's Tools: {self.artisan_tools}\nAdditional Tools: "
f"{self.additional_tools}\n"
f"Weapon Proficiencies: {self.weapon_proficiency}\n" f"Weapon Proficiencies: {self.weapon_proficiency}\n"
f"Armor Proficiencies: {self.armor_proficiency}\n") f"Armor Proficiencies: {self.armor_proficiency}\n")
#Assign the correct a/an article in the 'whoami' attr # Assign the correct a/an article in the 'whoami' attr
def grammar(self): def grammar(self):
if self.race[0] in VOWELS: if self.race[0] in VOWELS:
return "an" return "an"
@ -96,7 +112,7 @@ class HeroCreation:
with open('races.json') as json_file: with open('races.json') as json_file:
race_data = json.load(json_file) race_data = json.load(json_file)
chosen_race = random.choice(race_data) chosen_race = random.choice(race_data)
setattr(self,"race_string",chosen_race) setattr(self, "race_string", chosen_race)
def stat_rolls(self): def stat_rolls(self):
# Configured to "Re-roll" 1s # Configured to "Re-roll" 1s
@ -107,9 +123,9 @@ class HeroCreation:
roll_list.append(random.randint(2, 6)) roll_list.append(random.randint(2, 6))
roll_list.remove(min(roll_list)) roll_list.remove(min(roll_list))
stat_total = sum(roll_list) stat_total = sum(roll_list)
setattr(self,f"{attribute}", stat_total) setattr(self, f"{attribute}", stat_total)
#Assign racial stat bonuses # Assign racial stat bonuses
def racial_bonuses(self): def racial_bonuses(self):
self.charisma += self.race_string["Charisma"] self.charisma += self.race_string["Charisma"]
self.constitution += self.race_string["Constitution"] self.constitution += self.race_string["Constitution"]
@ -119,35 +135,35 @@ class HeroCreation:
self.wisdom += self.race_string["Wisdom"] self.wisdom += self.race_string["Wisdom"]
def name_generation(self): def name_generation(self):
with open("names.txt","r") as f: with open("names.txt", "r") as f:
name_list = f.read().splitlines() name_list = f.read().splitlines()
first_name = random.choice(name_list) first_name = random.choice(name_list)
sur_name = random.choice(name_list) sur_name = random.choice(name_list)
combined_name = f"{first_name} {sur_name}" combined_name = f"{first_name} {sur_name}"
setattr(self,"name",combined_name) setattr(self, "name", combined_name)
#Created skill attributes and save attributes with a base value of +0 to the roll # Created skill attributes and save attributes with a base value of +0 to the roll
def skill_generation(self): def skill_generation(self):
for skill in SKILL_LIST: for skill in SKILL_LIST:
setattr(self, skill, 0) setattr(self, skill, 0)
if skill == "athletics": if skill == "athletics":
self.apply_skill_modifiers("strength",skill) self.apply_skill_modifiers("strength", skill)
elif skill in ["acrobatics", "sleight_of_hand", "stealth"]: elif skill in ["acrobatics", "sleight_of_hand", "stealth"]:
self.apply_skill_modifiers("dexterity",skill) self.apply_skill_modifiers("dexterity", skill)
elif skill in ["arcana", "history", "investigation", "nature", "religion"]: elif skill in ["arcana", "history", "investigation", "nature", "religion"]:
self.apply_skill_modifiers("intelligence",skill) self.apply_skill_modifiers("intelligence", skill)
elif skill in ["animal_handling", "insight", "medicine", "perception", "survival"]: elif skill in ["animal_handling", "insight", "medicine", "perception", "survival"]:
self.apply_skill_modifiers("wisdom",skill) self.apply_skill_modifiers("wisdom", skill)
elif skill in ["deception", "intimidation", "performance", "persuasion"]: elif skill in ["deception", "intimidation", "performance", "persuasion"]:
self.apply_skill_modifiers("charisma",skill) self.apply_skill_modifiers("charisma", skill)
#Initialization of saving throw modifiers # Initialization of saving throw modifiers
for attribute in ATTRIBUTE_LIST: for attribute in ATTRIBUTE_LIST:
save_name = f"{attribute}_save" save_name = f"{attribute}_save"
setattr(self, save_name, 0) setattr(self, save_name, 0)
self.apply_skill_modifiers(attribute,save_name) self.apply_skill_modifiers(attribute, save_name)
def apply_skill_modifiers(self,attribute_name,skill_name): def apply_skill_modifiers(self, attribute_name, skill_name):
attribute = getattr(self,attribute_name) attribute = getattr(self, attribute_name)
if attribute == 1: if attribute == 1:
modifier = -5 modifier = -5
elif attribute in [2, 3]: elif attribute in [2, 3]:
@ -172,12 +188,12 @@ class HeroCreation:
modifier = 5 modifier = 5
else: else:
modifier = 0 modifier = 0
setattr(self,skill_name,modifier) setattr(self, skill_name, modifier)
def skill_proficiency(self): def skill_proficiency(self):
with open('backgrounds.json') as json_file: with open('backgrounds.json') as json_file:
background_data = json.load(json_file) background_data = json.load(json_file)
#Is this actually a dict? # Is this actually a dict?
background_dict = background_data[self.background]["Skills"] background_dict = background_data[self.background]["Skills"]
for skill in background_dict: for skill in background_dict:
current_score = getattr(self, skill) current_score = getattr(self, skill)
@ -192,37 +208,36 @@ class HeroCreation:
for skill in background_dict: for skill in background_dict:
if skill in job_skill_list: if skill in job_skill_list:
job_skill_list.remove(skill) job_skill_list.remove(skill)
#rogue list for expertise calculation # rogue list for expertise calculation
rogue_proficient_list = [] rogue_proficient_list = []
for each in range(proficiencies): for each in range(proficiencies):
proficient_skill = random.choice(job_skill_list) proficient_skill = random.choice(job_skill_list)
if self.job == "Rogue": if self.job == "Rogue":
rogue_proficient_list.append(proficient_skill) rogue_proficient_list.append(proficient_skill)
job_skill_list.remove(proficient_skill) job_skill_list.remove(proficient_skill)
current_score = getattr(self,proficient_skill) current_score = getattr(self, proficient_skill)
setattr(self,f"{proficient_skill}_base_value",current_score) setattr(self, f"{proficient_skill}_base_value", current_score)
new_score = str(current_score + 2) new_score = str(current_score + 2)
setattr(self,proficient_skill,f"{new_score} (Prof)") setattr(self, proficient_skill, f"{new_score} (Prof)")
if self.job == "Rogue": if self.job == "Rogue":
expertise_skill = random.choice(rogue_proficient_list) expertise_skill = random.choice(rogue_proficient_list)
score_value = getattr(self,f"{expertise_skill}_base_value") score_value = getattr(self, f"{expertise_skill}_base_value")
new_score = score_value + 4 new_score = score_value + 4
setattr(self,expertise_skill,f"{new_score} (Expertise)") setattr(self, expertise_skill, f"{new_score} (Expertise)")
def job_characteristics(self): def job_characteristics(self):
with open('jobs.json') as json_file: with open('jobs.json') as json_file:
job_data = json.load(json_file) job_data = json.load(json_file)
hit_die_value = job_data[self.job]["Hit Die"] hit_die_value = job_data[self.job]["Hit Die"]
setattr(self,"hit_die",hit_die_value) setattr(self, "hit_die", hit_die_value)
starting_hp_value = job_data[self.job]["Starting HP"] starting_hp_value = job_data[self.job]["Starting HP"]
setattr(self,"starting_hp",starting_hp_value) setattr(self, "starting_hp", starting_hp_value)
def job_proficiencies(self): def job_proficiencies(self):
with open('jobs.json') as json_file: with open('jobs.json') as json_file:
job_data = json.load(json_file) job_data = json.load(json_file)
if self.job == "Monk": if self.job == "Monk":
tool_choice = random.randint(0,1) tool_choice = random.randint(0, 1)
if tool_choice == 0: if tool_choice == 0:
instrument_value = 1 instrument_value = 1
else: else:
@ -239,7 +254,7 @@ class HeroCreation:
instrument_prof_list = [] instrument_prof_list = []
artisan_prof_list = [] artisan_prof_list = []
try: try:
for value in range(0,instrument_value): for value in range(0, instrument_value):
new_instrument = random.choice(instrument_list) new_instrument = random.choice(instrument_list)
instrument_list.remove(new_instrument) instrument_list.remove(new_instrument)
instrument_prof_list.append(new_instrument) instrument_prof_list.append(new_instrument)
@ -248,7 +263,7 @@ class HeroCreation:
except UnboundLocalError: except UnboundLocalError:
pass pass
try: try:
for value in range(0,artisan_tool_value): for value in range(0, artisan_tool_value):
new_tool = random.choice(ARTISANS_TOOLS) new_tool = random.choice(ARTISANS_TOOLS)
ARTISANS_TOOLS.remove(new_tool) ARTISANS_TOOLS.remove(new_tool)
artisan_prof_list.append(new_tool) artisan_prof_list.append(new_tool)
@ -267,7 +282,7 @@ class HeroCreation:
setattr(self, "armor_proficiency", "None") setattr(self, "armor_proficiency", "None")
else: else:
armor_prof_string = ", ".join(armor_prof_list) armor_prof_string = ", ".join(armor_prof_list)
setattr(self,"armor_proficiency",armor_prof_string) setattr(self, "armor_proficiency", armor_prof_string)
weapon_prof_list = job_data[self.job]["Weapon Proficiency"] weapon_prof_list = job_data[self.job]["Weapon Proficiency"]
weapon_prof_string = ", ".join(weapon_prof_list) weapon_prof_string = ", ".join(weapon_prof_list)
setattr(self, "weapon_proficiency", weapon_prof_string) setattr(self, "weapon_proficiency", weapon_prof_string)
@ -280,57 +295,57 @@ class HeroCreation:
global known_language_list global known_language_list
with open('backgrounds.json') as json_file: with open('backgrounds.json') as json_file:
background_data = json.load(json_file) background_data = json.load(json_file)
#background instrument proficiencies # background instrument proficiencies
try: try:
instrument_value = background_data[self.background]["Additional Proficiencies"]["Instrument"] instrument_value = background_data[self.background]["Additional Proficiencies"]["Instrument"]
except KeyError or UnboundLocalError: except KeyError or UnboundLocalError:
pass pass
for value in range(0, instrument_value): for value in range(0, instrument_value):
new_instrument = random.choice(instrument_list) new_instrument = random.choice(instrument_list)
current_instruments = getattr(self,"instruments") current_instruments = getattr(self, "instruments")
if current_instruments == "None": if current_instruments == "None":
setattr(self, "instruments", f"{new_instrument}") setattr(self, "instruments", f"{new_instrument}")
else: else:
setattr(self, "instruments", current_instruments + f", {new_instrument}") setattr(self, "instruments", current_instruments + f", {new_instrument}")
#background artisan's tools proficiencies # background artisan's tools proficiencies
try: try:
tool_value = background_data[self.background]["Additional Proficiencies"]["Artisan's Tool"] tool_value = background_data[self.background]["Additional Proficiencies"]["Artisan's Tool"]
except KeyError or UnboundLocalError: except KeyError or UnboundLocalError:
pass pass
for value in range(0, tool_value): for value in range(0, tool_value):
new_tool = random.choice(ARTISANS_TOOLS) new_tool = random.choice(ARTISANS_TOOLS)
current_tools = getattr(self,"artisan_tools") current_tools = getattr(self, "artisan_tools")
if current_tools == "None": if current_tools == "None":
setattr(self, "artisan_tools", f"{new_tool}") setattr(self, "artisan_tools", f"{new_tool}")
else: else:
setattr(self, "artisan_tools", current_tools + f", {new_tool}") setattr(self, "artisan_tools", current_tools + f", {new_tool}")
#language proficiencies # language proficiencies
try: try:
language_value = background_data[self.background]["Additional Proficiencies"]["Languages"] language_value = background_data[self.background]["Additional Proficiencies"]["Languages"]
except UnboundLocalError: except UnboundLocalError:
pass pass
for value in range(0,language_value): for value in range(0, language_value):
try: try:
new_language = random.choice(languages) new_language = random.choice(languages)
known_language_list.append(new_language) known_language_list.append(new_language)
languages.remove(new_language) languages.remove(new_language)
except IndexError: except IndexError:
pass pass
#additional tool proficiencies # additional tool proficiencies
additional_tool_list = background_data[self.background]["Additional Proficiencies"]["Additional Tools"] additional_tool_list = background_data[self.background]["Additional Proficiencies"]["Additional Tools"]
if not additional_tool_list: if not additional_tool_list:
pass pass
else: else:
current_tools = getattr(self,"additional_tools") current_tools = getattr(self, "additional_tools")
if current_tools == "None": if current_tools == "None":
setattr(self, "additional_tools",", ".join(additional_tool_list)) setattr(self, "additional_tools", ", ".join(additional_tool_list))
else: else:
for tool in additional_tool_list: for tool in additional_tool_list:
if tool in current_tools: if tool in current_tools:
pass pass
else: else:
new_tool_list = getattr(self,"additional_tools") + f", {tool}" new_tool_list = getattr(self, "additional_tools") + f", {tool}"
setattr(self,"additional_tools",new_tool_list) setattr(self, "additional_tools", new_tool_list)
def race_proficiencies(self): def race_proficiencies(self):
global known_language_list global known_language_list
@ -338,6 +353,7 @@ class HeroCreation:
known_languages = self.race_string["Languages"] known_languages = self.race_string["Languages"]
for language in known_languages: for language in known_languages:
known_language_list.append(language) known_language_list.append(language)
print(language)
languages.remove(language) languages.remove(language)
except KeyError: except KeyError:
pass pass
@ -354,16 +370,39 @@ class HeroCreation:
language_string = ", ".join(known_language_list) language_string = ", ".join(known_language_list)
setattr(self, "languages", language_string) setattr(self, "languages", language_string)
def whoami(self):
if self.job == "Cleric":
subclass = random.choice(CLERIC_SUBCLASSES)
setattr(self,"subclass",subclass)
print(f"Your new character is {self.name}, {self.article} {self.race} {self.job}, with the "
f"{self.background} background and the {self.subclass} subclass.\n")
elif self.job == "Sorcerer":
subclass = random.choice(SORCERER_SUBCLASSES)
setattr(self, "subclass", subclass)
print(f"Your new character is {self.name}, {self.article} {self.race} {self.job}, with the "
f"{self.background} background and the {self.subclass} subclass.\n")
elif self.job == "Wizard":
subclass = random.choice(WIZARD_SUBCLASSES)
setattr(self, "subclass", subclass)
print(f"Your new character is {self.name}, {self.article} {self.race} {self.job}, with the "
f"{self.background} background and the {self.subclass} subclass.\n")
else:
print(f"Your new character is {self.name}, {self.article} {self.race} {self.job}, with the "
f"{self.background} background.\n")
#Used for interactively moving around stats in case of a bad allocation. # Used for interactively moving around stats in case of a bad allocation.
#Disabling for now, as this project is intended to be one-command and self-contained # Disabling for now, as this project is intended to be one-command and self-contained
# def stat_moves(self): # def stat_moves(self):
# finished = False # finished = False
# while not finished: # while not finished:
# move_request = input("Would you like to move any of these stats around? (y/n)").lower() # move_request = input("Would you like to move any of these stats around? (y/n)").lower()
# if move_request == "y": # if move_request == "y":
# stat_1 = input("What is the first stat you would like to move? Please enter the full stat name.").lower() # stat_1 = input("What is the first stat you would like to move? Please enter the full stat
# stat_2 = input("What is the second stat you would like to move? Please enter the full stat name.").lower() # name.").lower()
# stat_2 = input("What is the second stat you would like to move? Please enter the full stat
# name.").lower()
# if hasattr(self, stat_1) and hasattr(self, stat_2): # if hasattr(self, stat_1) and hasattr(self, stat_2):
# stat_1_value = getattr(self, stat_1) # stat_1_value = getattr(self, stat_1)
# stat_2_value = getattr(self, stat_2) # stat_2_value = getattr(self, stat_2)
@ -375,7 +414,7 @@ class HeroCreation:
# elif move_request == "n": # elif move_request == "n":
# finished = True # finished = True
#Currently only used for the stat_moves functionality. Disabling for now # Currently only used for the stat_moves functionality. Disabling for now
# def update_stat_block(self): # def update_stat_block(self):
# self.stat_block = (f"Stat Block\n---------\nCharisma: {self.charisma}\nConstitution: {self.constitution}\n" # self.stat_block = (f"Stat Block\n---------\nCharisma: {self.charisma}\nConstitution: {self.constitution}\n"
# f"Dexterity: {self.dexterity}\nIntelligence: {self.intelligence}\n" # f"Dexterity: {self.dexterity}\nIntelligence: {self.intelligence}\n"

1
main.py

@ -2,7 +2,6 @@ import creation_engine
hero = creation_engine.HeroCreation() hero = creation_engine.HeroCreation()
print(hero.whoami)
print(hero.stat_block) print(hero.stat_block)
print(hero.saves) print(hero.saves)
print(hero.additional_stats) print(hero.additional_stats)

181
races.json

@ -11,20 +11,8 @@
"Aarakocra", "Aarakocra",
"Auran" "Auran"
], ],
"AdditionalLanguages": 1 "AdditionalLanguages": 1,
}, "Speed": 50
{
"Race": "Aasimar",
"Strength": 0,
"Dexterity": 0,
"Constitution": 0,
"Intelligence": 0,
"Wisdom": 1,
"Charisma": 2,
"Languages": [
"Celestial"
],
"AdditionalLanguages": 1
}, },
{ {
"Race": "Aasimar (Fallen)", "Race": "Aasimar (Fallen)",
@ -37,7 +25,9 @@
"Languages": [ "Languages": [
"Celestial" "Celestial"
], ],
"AdditionalLanguages": 1 "AdditionalLanguages": 1,
"Speed": 30,
"Resistances": ["Radiant Damage", "Necrotic Damage"]
}, },
{ {
"Race": "Aasimar (Protector)", "Race": "Aasimar (Protector)",
@ -50,7 +40,9 @@
"Languages": [ "Languages": [
"Celestial" "Celestial"
], ],
"AdditionalLanguages": 1 "AdditionalLanguages": 1,
"Speed": 30,
"Resistances": ["Radiant Damage", "Necrotic Damage"]
}, },
{ {
"Race": "Aasimar (Scourge)", "Race": "Aasimar (Scourge)",
@ -63,7 +55,9 @@
"Languages": [ "Languages": [
"Celestial" "Celestial"
], ],
"AdditionalLanguages": 1 "AdditionalLanguages": 1,
"Speed": 30,
"Resistances": ["Radiant Damage", "Necrotic Damage"]
}, },
{ {
"Race": "Bugbear", "Race": "Bugbear",
@ -76,7 +70,8 @@
"Languages": [ "Languages": [
"Goblin" "Goblin"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Centaur", "Race": "Centaur",
@ -90,7 +85,8 @@
"Sylvan", "Sylvan",
"Elvish" "Elvish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 40
}, },
{ {
"Race": "Dwarf (Duergar)", "Race": "Dwarf (Duergar)",
@ -104,7 +100,8 @@
"Dwarvish", "Dwarvish",
"Undercommon" "Undercommon"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Dwarf (Hill)", "Race": "Dwarf (Hill)",
@ -117,7 +114,8 @@
"Languages": [ "Languages": [
"Dwarvish" "Dwarvish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Dwarf (Mountain)", "Race": "Dwarf (Mountain)",
@ -130,7 +128,8 @@
"Languages": [ "Languages": [
"Dwarvish" "Dwarvish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Dragonborn", "Race": "Dragonborn",
@ -143,7 +142,8 @@
"Languages": [ "Languages": [
"Draconic" "Draconic"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Elf (Drow)", "Race": "Elf (Drow)",
@ -157,7 +157,8 @@
"Elvish", "Elvish",
"Undercommon" "Undercommon"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Elf (Eladrin)", "Race": "Elf (Eladrin)",
@ -170,7 +171,8 @@
"Languages": [ "Languages": [
"Elvish" "Elvish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Elf (High)", "Race": "Elf (High)",
@ -183,7 +185,8 @@
"Languages": [ "Languages": [
"Elvish" "Elvish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Elf (Sea)", "Race": "Elf (Sea)",
@ -197,7 +200,8 @@
"Elvish", "Elvish",
"Undercommon" "Undercommon"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Elf (Shadar-Kai)", "Race": "Elf (Shadar-Kai)",
@ -211,7 +215,8 @@
"Elvish", "Elvish",
"Undercommon" "Undercommon"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Elf (Wood)", "Race": "Elf (Wood)",
@ -224,7 +229,8 @@
"Languages": [ "Languages": [
"Elvish" "Elvish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 35
}, },
{ {
"Race": "Firbolg", "Race": "Firbolg",
@ -237,7 +243,8 @@
"Languages": [ "Languages": [
"Sylvan" "Sylvan"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Genasi (Air)", "Race": "Genasi (Air)",
@ -250,7 +257,8 @@
"Languages": [ "Languages": [
"Primordial" "Primordial"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Genasi (Earth)", "Race": "Genasi (Earth)",
@ -263,7 +271,8 @@
"Languages": [ "Languages": [
"Primordial" "Primordial"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Genasi (Fire)", "Race": "Genasi (Fire)",
@ -276,7 +285,8 @@
"Languages": [ "Languages": [
"Primordial" "Primordial"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Genasi (Water)", "Race": "Genasi (Water)",
@ -289,7 +299,8 @@
"Languages": [ "Languages": [
"Primordial" "Primordial"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Githyanki", "Race": "Githyanki",
@ -302,7 +313,8 @@
"Languages": [ "Languages": [
"Gith" "Gith"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Githzerai", "Race": "Githzerai",
@ -315,7 +327,8 @@
"Languages": [ "Languages": [
"Gith" "Gith"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Gnome (Deep)", "Race": "Gnome (Deep)",
@ -329,7 +342,8 @@
"Gnomish", "Gnomish",
"Undercommon" "Undercommon"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Gnome (Forest)", "Race": "Gnome (Forest)",
@ -342,7 +356,8 @@
"Languages": [ "Languages": [
"Gnomish" "Gnomish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Gnome (Rock)", "Race": "Gnome (Rock)",
@ -355,7 +370,8 @@
"Languages": [ "Languages": [
"Gnomish" "Gnomish"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Goblin", "Race": "Goblin",
@ -368,7 +384,8 @@
"Languages": [ "Languages": [
"Goblin" "Goblin"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Goliath", "Race": "Goliath",
@ -381,7 +398,8 @@
"Languages": [ "Languages": [
"Giant" "Giant"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Halfling (Lightfoot)", "Race": "Halfling (Lightfoot)",
@ -394,7 +412,8 @@
"Languages": [ "Languages": [
"Halfling" "Halfling"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Halfling (Stout)", "Race": "Halfling (Stout)",
@ -407,7 +426,8 @@
"Languages": [ "Languages": [
"Halfling" "Halfling"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 25
}, },
{ {
"Race": "Half-Orc", "Race": "Half-Orc",
@ -420,7 +440,8 @@
"Languages": [ "Languages": [
"Orc" "Orc"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Hobgoblin", "Race": "Hobgoblin",
@ -433,7 +454,8 @@
"Languages": [ "Languages": [
"Goblin" "Goblin"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Human", "Race": "Human",
@ -443,7 +465,8 @@
"Intelligence": 1, "Intelligence": 1,
"Wisdom": 1, "Wisdom": 1,
"Charisma": 1, "Charisma": 1,
"AdditionalLanguages": 1 "AdditionalLanguages": 1,
"Speed": 30
}, },
{ {
"Race": "Kenku", "Race": "Kenku",
@ -456,7 +479,8 @@
"Languages": [ "Languages": [
"Auran" "Auran"
], ],
"AdditionalLanguages": 1 "AdditionalLanguages": 1,
"Speed": 30
}, },
{ {
"Race": "Kobold", "Race": "Kobold",
@ -469,7 +493,8 @@
"Languages": [ "Languages": [
"Draconic" "Draconic"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Lizardfolk", "Race": "Lizardfolk",
@ -482,7 +507,8 @@
"Languages": [ "Languages": [
"Draconic" "Draconic"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Minotaur", "Race": "Minotaur",
@ -495,7 +521,8 @@
"Languages": [ "Languages": [
"Giant" "Giant"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Orc", "Race": "Orc",
@ -508,7 +535,8 @@
"Languages": [ "Languages": [
"Orc" "Orc"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Shifter (Beasthide)", "Race": "Shifter (Beasthide)",
@ -521,7 +549,8 @@
"Languages": [ "Languages": [
"Sylvan" "Sylvan"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Shifter (Longtooth)", "Race": "Shifter (Longtooth)",
@ -534,7 +563,8 @@
"Languages": [ "Languages": [
"Sylvan" "Sylvan"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Shifter (Swiftstride)", "Race": "Shifter (Swiftstride)",
@ -547,7 +577,8 @@
"Languages": [ "Languages": [
"Sylvan" "Sylvan"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 35
}, },
{ {
"Race": "Shifter (Wildhunt)", "Race": "Shifter (Wildhunt)",
@ -560,7 +591,8 @@
"Languages": [ "Languages": [
"Sylvan" "Sylvan"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tabaxi", "Race": "Tabaxi",
@ -570,7 +602,8 @@
"Intelligence": 0, "Intelligence": 0,
"Wisdom": 0, "Wisdom": 0,
"Charisma": 1, "Charisma": 1,
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tiefling", "Race": "Tiefling",
@ -583,7 +616,8 @@
"Languages": [ "Languages": [
"Infernal" "Infernal"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tiefling (Dispater)", "Race": "Tiefling (Dispater)",
@ -596,7 +630,8 @@
"Languages": [ "Languages": [
"Infernal" "Infernal"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tiefling (Glasya)", "Race": "Tiefling (Glasya)",
@ -609,7 +644,8 @@
"Languages": [ "Languages": [
"Infernal" "Infernal"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tiefling (Feral)", "Race": "Tiefling (Feral)",
@ -622,7 +658,8 @@
"Languages": [ "Languages": [
"Infernal" "Infernal"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tiefling (Fierna)", "Race": "Tiefling (Fierna)",
@ -635,7 +672,8 @@
"Languages": [ "Languages": [
"Infernal" "Infernal"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tiefling (Levistus)", "Race": "Tiefling (Levistus)",
@ -648,7 +686,8 @@
"Languages": [ "Languages": [
"Infernal" "Infernal"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Tiefling (Zariel)", "Race": "Tiefling (Zariel)",
@ -661,7 +700,8 @@
"Languages": [ "Languages": [
"Infernal" "Infernal"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Triton", "Race": "Triton",
@ -674,7 +714,8 @@
"Languages": [ "Languages": [
"Aquan" "Aquan"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Vedalken", "Race": "Vedalken",
@ -688,7 +729,8 @@
"Vedalken", "Vedalken",
"Undercommon" "Undercommon"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Warforged (Juggernaut)", "Race": "Warforged (Juggernaut)",
@ -698,7 +740,8 @@
"Intelligence": 0, "Intelligence": 0,
"Wisdom": 0, "Wisdom": 0,
"Charisma": 0, "Charisma": 0,
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Warforged (Skirmisher)", "Race": "Warforged (Skirmisher)",
@ -708,7 +751,8 @@
"Intelligence": 0, "Intelligence": 0,
"Wisdom": 0, "Wisdom": 0,
"Charisma": 0, "Charisma": 0,
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
}, },
{ {
"Race": "Yuan-Ti Pureblood", "Race": "Yuan-Ti Pureblood",
@ -722,6 +766,7 @@
"Abyssal", "Abyssal",
"Draconic" "Draconic"
], ],
"AdditionalLanguages": 0 "AdditionalLanguages": 0,
"Speed": 30
} }
] ]
Loading…
Cancel
Save