Browse Source

Updated racial language proficiencies. Changed workflow to allow the racial languages to claim from the language list first before moving to background.

main
suzan 2 weeks ago
parent
commit
944099f1a4
  1. 184
      creation_engine.py
  2. 5
      jobs.json
  3. 4
      main.py
  4. 680
      races.json

184
creation_engine.py

@ -1,10 +1,6 @@
import random
import json
#TODO 1 Languages
#TODO 2 Tool Proficiencies
#TODO 3 Weapon Proficiencies
#TODO 4 Rogue Expertise
#TODO 5 AC? Or Gold Start no AC?
#TODO 6 Sub Classes?
@ -23,12 +19,14 @@ BACKGROUND_LIST = ["Acolyte", "Charlatan", "Criminal / Spy", "Entertainer", "Fol
"Guild Artisan / Guild Merchant", "Hermit", "Knight", "Noble", "Outlander", "Pirate", "Sage",
"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",
"Tocken", "Trumpet", "Viol", "Wargong", "Yarting", "Zulkoon"]
LANGUAGES = ["Abyssal", "Celestial", "Deep Speech", "Draconic", "Dwarvish", "Elvish", "Giant", "Gnomish", "Goblin",
"Halfling", "Infernal", "Orc", "Primordial", "Sylvan", "Undercommon"]
languages = ["Aarakocra", "Abyssal", "Aquan"," Auran", "Celestial", "Deep Speech", "Draconic", "Dwarvish", "Elvish", "Giant",
"Gith", "Gnomish", "Goblin", "Halfling", "Infernal", "Orc", "Primordial", "Sylvan", "Undercommon", "Vedalken"]
known_language_list = ["Common"]
GAMING_SETS = ["Bowls", "Darts", "Dice Set", "Dragonchess Set", "Playing Card Set", "Quoits", "Three-Dragon Ante Set"]
@ -52,15 +50,25 @@ class HeroCreation:
self.skill_generation()
self.skill_proficiency()
self.instruments = "None"
self.instrument_proficiencies()
self.artisan_tools = "None"
self.artisan_tool_proficiencies()
self.additional_tools = "None"
self.armor_proficiency = "None"
self.race_proficiencies()
self.job_proficiencies()
self.background_proficiencies()
self.finalize_languages()
self.apply_skill_modifiers("dexterity","initiative")
self.whoami = (f"Your new character is {self.name}, {self.article} {self.race} {self.job}, with the "
f"{self.background} background.\n")
self.stat_block = (f"Stat Block\n----------\nCharisma: {self.charisma}\nConstitution: {self.constitution}\n"
f"Dexterity: {self.dexterity}\nIntelligence: {self.intelligence}\n"
f"Strength: {self.strength}\nWisdom: {self.wisdom}\n")
self.saves = (f"Saving Throws\n----------\nCharisma Save: {self.charisma_save}\n"
f"Constitution Save: {self.constitution_save}\n"
f"Dexterity Save: {self.dexterity_save}\n"
f"Intelligence Save: {self.intelligence_save}\n"
f"Strength Save: {self.strength_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"
f"Initiative Bonus: {self.initiative}\n")
self.skill_bonuses = (f"Skill Bonuses\n----------\nAcrobatics: {self.acrobatics}\nAnimal Handling: {self.animal_handling}"
@ -70,8 +78,12 @@ class HeroCreation:
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----------\nInstruments: {self.instruments}\n"
f"Artisan's Tools: {self.artisan_tools}")
self.other_proficiencies = (f"Additional Proficiencies\n----------\n"
f"Languages: {self.languages}\n"
f"Instruments: {self.instruments}\n"
f"Artisan's Tools: {self.artisan_tools}\nAdditional Tools: {self.additional_tools}\n"
f"Weapon Proficiencies: {self.weapon_proficiency}\n"
f"Armor Proficiencies: {self.armor_proficiency}\n")
#Assign the correct a/an article in the 'whoami' attr
def grammar(self):
@ -114,7 +126,7 @@ class HeroCreation:
combined_name = f"{first_name} {sur_name}"
setattr(self,"name",combined_name)
#Created skill 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):
for skill in SKILL_LIST:
setattr(self, skill, 0)
@ -128,6 +140,11 @@ class HeroCreation:
self.apply_skill_modifiers("wisdom",skill)
elif skill in ["deception", "intimidation", "performance", "persuasion"]:
self.apply_skill_modifiers("charisma",skill)
#Initialization of saving throw modifiers
for attribute in ATTRIBUTE_LIST:
save_name = f"{attribute}_save"
setattr(self, save_name, 0)
self.apply_skill_modifiers(attribute,save_name)
def apply_skill_modifiers(self,attribute_name,skill_name):
attribute = getattr(self,attribute_name)
@ -160,7 +177,7 @@ class HeroCreation:
def skill_proficiency(self):
with open('backgrounds.json') as 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"]
for skill in background_dict:
current_score = getattr(self, skill)
@ -175,15 +192,24 @@ class HeroCreation:
for skill in background_dict:
if skill in job_skill_list:
job_skill_list.remove(skill)
#rogue list for expertise calculation
rogue_proficient_list = []
for each in range(proficiencies):
proficient_skill = random.choice(job_skill_list)
if self.job == "Rogue":
rogue_proficient_list.append(proficient_skill)
job_skill_list.remove(proficient_skill)
current_score = getattr(self,proficient_skill)
setattr(self,f"{proficient_skill}_base_value",current_score)
new_score = str(current_score + 2)
setattr(self,proficient_skill,f"{new_score} (Prof)")
if self.job == "Rogue":
expertise_skill = random.choice(rogue_proficient_list)
score_value = getattr(self,f"{expertise_skill}_base_value")
new_score = score_value + 4
setattr(self,expertise_skill,f"{new_score} (Expertise)")
def job_characteristics(self):
with open('jobs.json') as json_file:
job_data = json.load(json_file)
hit_die_value = job_data[self.job]["Hit Die"]
@ -192,33 +218,141 @@ class HeroCreation:
setattr(self,"starting_hp",starting_hp_value)
def instrument_proficiencies(self):
def job_proficiencies(self):
with open('jobs.json') as json_file:
job_data = json.load(json_file)
if self.job == "Monk":
tool_choice = random.randint(0,1)
if tool_choice == 0:
instrument_value = 1
else:
artisan_tool_value = 1
else:
try:
instrument_value = job_data[self.job]["Instruments"]
except KeyError:
pass
try:
artisan_tool_value = job_data[self.job]["Artisan's Tools"]
except KeyError:
pass
instrument_prof_list = []
artisan_prof_list = []
try:
for value in range(job_data[self.job]["Instruments"]):
new_instrument = random.choice(INSTRUMENT_LIST)
INSTRUMENT_LIST.remove(new_instrument)
for value in range(0,instrument_value):
new_instrument = random.choice(instrument_list)
instrument_list.remove(new_instrument)
instrument_prof_list.append(new_instrument)
instrument_string = ", ".join(instrument_prof_list)
setattr(self, "instruments", str(instrument_string))
except KeyError:
except UnboundLocalError:
pass
def artisan_tool_proficiencies(self):
with open('jobs.json') as json_file:
job_data = json.load(json_file)
artisan_prof_list = []
try:
for value in range(job_data[self.job]["Artisan's Tools"]):
for value in range(0,artisan_tool_value):
new_tool = random.choice(ARTISANS_TOOLS)
ARTISANS_TOOLS.remove(new_tool)
artisan_prof_list.append(new_tool)
artisan_tool_string = ", ".join(artisan_prof_list)
setattr(self, "artisan_tools", str(artisan_tool_string))
except UnboundLocalError:
pass
try:
additional_tool_list = job_data[self.job]["Additional Tools"]
additional_tool_string = ", ".join(additional_tool_list)
setattr(self, "additional_tools", str(additional_tool_string))
except KeyError:
pass
armor_prof_list = job_data[self.job]["Armor Proficiency"]
if not armor_prof_list:
setattr(self, "armor_proficiency", "None")
else:
armor_prof_string = ", ".join(armor_prof_list)
setattr(self,"armor_proficiency",armor_prof_string)
weapon_prof_list = job_data[self.job]["Weapon Proficiency"]
weapon_prof_string = ", ".join(weapon_prof_list)
setattr(self, "weapon_proficiency", weapon_prof_string)
for attribute in job_data[self.job]["Saving Throws"]:
current_score = getattr(self, f"{attribute}_save")
new_score = str(current_score + 2)
setattr(self, f"{attribute}_save", f"{new_score} (Prof)")
def background_proficiencies(self):
global known_language_list
with open('backgrounds.json') as json_file:
background_data = json.load(json_file)
#background instrument proficiencies
try:
instrument_value = background_data[self.background]["Additional Proficiencies"]["Instrument"]
except KeyError or UnboundLocalError:
pass
for value in range(0, instrument_value):
new_instrument = random.choice(instrument_list)
current_instruments = getattr(self,"instruments")
if current_instruments == "None":
setattr(self, "instruments", f"{new_instrument}")
else:
setattr(self, "instruments", current_instruments + f", {new_instrument}")
#background artisan's tools proficiencies
try:
tool_value = background_data[self.background]["Additional Proficiencies"]["Artisan's Tool"]
except KeyError or UnboundLocalError:
pass
for value in range(0, tool_value):
new_tool = random.choice(ARTISANS_TOOLS)
current_tools = getattr(self,"artisan_tools")
if current_tools == "None":
setattr(self, "artisan_tools", f"{new_tool}")
else:
setattr(self, "artisan_tools", current_tools + f", {new_tool}")
#language proficiencies
try:
language_value = background_data[self.background]["Additional Proficiencies"]["Languages"]
except UnboundLocalError:
pass
for value in range(0,language_value):
try:
new_language = random.choice(languages)
known_language_list.append(new_language)
languages.remove(new_language)
except IndexError:
pass
#additional tool proficiencies
additional_tool_list = background_data[self.background]["Additional Proficiencies"]["Additional Tools"]
if not additional_tool_list:
pass
else:
current_tools = getattr(self,"additional_tools")
if current_tools == "None":
setattr(self, "additional_tools",", ".join(additional_tool_list))
else:
for tool in additional_tool_list:
if tool in current_tools:
pass
else:
new_tool_list = getattr(self,"additional_tools") + f", {tool}"
setattr(self,"additional_tools",new_tool_list)
def race_proficiencies(self):
global known_language_list
try:
known_languages = self.race_string["Languages"]
for language in known_languages:
known_language_list.append(language)
languages.remove(language)
except KeyError:
pass
for value in range(0, self.race_string["AdditionalLanguages"]):
try:
new_language = random.choice(languages)
known_language_list.append(new_language)
languages.remove(new_language)
except IndexError:
pass
def finalize_languages(self):
global known_language_list
language_string = ", ".join(known_language_list)
setattr(self, "languages", language_string)
#Used for interactively moving around stats in case of a bad allocation.

5
jobs.json

@ -198,9 +198,6 @@
],
"Hit Die": "1d8",
"Starting HP": 8,
"Additional Tools": [
"one artisan tool or one musical instrument"
],
"Armor Proficiency": [],
"Weapon Proficiency": [
"Simple Weapons",
@ -391,7 +388,7 @@
"Hit Die": "1d8",
"Starting HP": 8,
"Additional Tools": [
"alchemist's supplies"
"Alchemist's Supplies"
],
"Armor Proficiency": [
"Light Armor",

4
main.py

@ -4,8 +4,8 @@ hero = creation_engine.HeroCreation()
print(hero.whoami)
print(hero.stat_block)
print(hero.saves)
print(hero.additional_stats)
print(hero.skill_bonuses)
print(hero.other_proficiencies)
print(hero.job)

680
races.json

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save