From 944099f1a48a04bfcedbbf8948724721f037ae35 Mon Sep 17 00:00:00 2001 From: suzan Date: Mon, 16 Jun 2025 22:59:35 -0500 Subject: [PATCH] Updated racial language proficiencies. Changed workflow to allow the racial languages to claim from the language list first before moving to background. --- creation_engine.py | 184 ++++++++++-- jobs.json | 5 +- main.py | 4 +- races.json | 680 ++++++++++++++++++++------------------------- 4 files changed, 464 insertions(+), 409 deletions(-) diff --git a/creation_engine.py b/creation_engine.py index d5da427..a65a7e4 100644 --- a/creation_engine.py +++ b/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. diff --git a/jobs.json b/jobs.json index f186b3a..5b2ffbc 100644 --- a/jobs.json +++ b/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", diff --git a/main.py b/main.py index d7c826f..d49a815 100644 --- a/main.py +++ b/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) \ No newline at end of file diff --git a/races.json b/races.json index eb2230b..cfb71af 100644 --- a/races.json +++ b/races.json @@ -6,7 +6,12 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 1, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Aarakocra", + "Auran" + ], + "AdditionalLanguages": 1 }, { "Race": "Aasimar", @@ -15,7 +20,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 1, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Celestial" + ], + "AdditionalLanguages": 1 }, { "Race": "Aasimar (Fallen)", @@ -24,7 +33,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Celestial" + ], + "AdditionalLanguages": 1 }, { "Race": "Aasimar (Protector)", @@ -33,7 +46,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 1, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Celestial" + ], + "AdditionalLanguages": 1 }, { "Race": "Aasimar (Scourge)", @@ -42,34 +59,11 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 2 - }, - { - "Race": "Alseid", - "Strength": 0, - "Dexterity": 2, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Aven (Hawk)", - "Strength": 0, - "Dexterity": 2, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 2, - "Charisma": 0 - }, - { - "Race": "Aven (Ibis)", - "Strength": 0, - "Dexterity": 2, - "Constitution": 0, - "Intelligence": 1, - "Wisdom": 0, - "Charisma": 0 + "Charisma": 2, + "Languages": [ + "Celestial" + ], + "AdditionalLanguages": 1 }, { "Race": "Bugbear", @@ -78,7 +72,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Goblin" + ], + "AdditionalLanguages": 0 }, { "Race": "Centaur", @@ -87,7 +85,12 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 1, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Sylvan", + "Elvish" + ], + "AdditionalLanguages": 0 }, { "Race": "Dwarf (Duergar)", @@ -96,7 +99,12 @@ "Constitution": 2, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Dwarvish", + "Undercommon" + ], + "AdditionalLanguages": 0 }, { "Race": "Dwarf (Hill)", @@ -105,16 +113,11 @@ "Constitution": 2, "Intelligence": 0, "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Dwarf (Kaladesh)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 2, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Dwarvish" + ], + "AdditionalLanguages": 0 }, { "Race": "Dwarf (Mountain)", @@ -123,7 +126,11 @@ "Constitution": 2, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Dwarvish" + ], + "AdditionalLanguages": 0 }, { "Race": "Dragonborn", @@ -132,52 +139,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 1 - }, - { - "Race": "Dragonkin (Edjet/Soldier)", - "Strength": 0, - "Dexterity": 1, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 2 - }, - { - "Race": "Dragonkin (Flame/Fire)", - "Strength": 1, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 2 - }, - { - "Race": "Dragonkin (Stone/Cave)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 1, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 2 - }, - { - "Race": "Dragonkin (Wave/Tide)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 2 - }, - { - "Race": "Dragonkin (Wind/Storm)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 1, - "Wisdom": 0, - "Charisma": 2 + "Charisma": 1, + "Languages": [ + "Draconic" + ], + "AdditionalLanguages": 0 }, { "Race": "Elf (Drow)", @@ -186,43 +152,66 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 1 + "Charisma": 1, + "Languages": [ + "Elvish", + "Undercommon" + ], + "AdditionalLanguages": 0 }, { - "Race": "Elf (Eladrin, High)", + "Race": "Elf (Eladrin)", "Strength": 0, "Dexterity": 2, "Constitution": 0, "Intelligence": 1, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Elvish" + ], + "AdditionalLanguages": 0 }, { - "Race": "Elf (Kaladesh)", + "Race": "Elf (High)", "Strength": 0, "Dexterity": 2, "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 + "Intelligence": 1, + "Wisdom": 0, + "Charisma": 0, + "Languages": [ + "Elvish" + ], + "AdditionalLanguages": 0 }, { - "Race": "Elf (Sea, Shadar-Kai)", + "Race": "Elf (Sea)", "Strength": 0, "Dexterity": 2, "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Elvish", + "Undercommon" + ], + "AdditionalLanguages": 0 }, { - "Race": "Elf (Shadow Fey)", + "Race": "Elf (Shadar-Kai)", "Strength": 0, "Dexterity": 2, - "Constitution": 0, + "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 1 + "Charisma": 0, + "Languages": [ + "Elvish", + "Undercommon" + ], + "AdditionalLanguages": 0 }, { "Race": "Elf (Wood)", @@ -231,34 +220,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Elf (Zendikar Joraga)", - "Strength": 0, - "Dexterity": 1, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 2, - "Charisma": 0 - }, - { - "Race": "Elf (Zendikar Mul Daya)", - "Strength": 1, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 2, - "Charisma": 0 - }, - { - "Race": "Elf (Zendikar Tajuru)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 2, - "Charisma": 1 + "Charisma": 0, + "Languages": [ + "Elvish" + ], + "AdditionalLanguages": 0 }, { "Race": "Firbolg", @@ -267,7 +233,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 2, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Sylvan" + ], + "AdditionalLanguages": 0 }, { "Race": "Genasi (Air)", @@ -276,7 +246,11 @@ "Constitution": 2, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Primordial" + ], + "AdditionalLanguages": 0 }, { "Race": "Genasi (Earth)", @@ -285,7 +259,11 @@ "Constitution": 2, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Primordial" + ], + "AdditionalLanguages": 0 }, { "Race": "Genasi (Fire)", @@ -294,7 +272,11 @@ "Constitution": 2, "Intelligence": 1, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Primordial" + ], + "AdditionalLanguages": 0 }, { "Race": "Genasi (Water)", @@ -303,7 +285,11 @@ "Constitution": 2, "Intelligence": 0, "Wisdom": 1, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Primordial" + ], + "AdditionalLanguages": 0 }, { "Race": "Githyanki", @@ -312,7 +298,11 @@ "Constitution": 0, "Intelligence": 1, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Gith" + ], + "AdditionalLanguages": 0 }, { "Race": "Githzerai", @@ -321,34 +311,38 @@ "Constitution": 0, "Intelligence": 1, "Wisdom": 2, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Gith" + ], + "AdditionalLanguages": 0 }, { - "Race": "Gnoll (Civilized)", - "Strength": 2, - "Dexterity": 0, - "Constitution": 1, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 0 - }, - { - "Race": "Gnoll (Savage)", - "Strength": 2, - "Dexterity": 0, + "Race": "Gnome (Deep)", + "Strength": 0, + "Dexterity": 1, "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 + "Intelligence": 2, + "Wisdom": 0, + "Charisma": 0, + "Languages": [ + "Gnomish", + "Undercommon" + ], + "AdditionalLanguages": 0 }, { - "Race": "Gnome (Deep, Forest)", + "Race": "Gnome (Forest)", "Strength": 0, "Dexterity": 1, "Constitution": 0, "Intelligence": 2, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Gnomish" + ], + "AdditionalLanguages": 0 }, { "Race": "Gnome (Rock)", @@ -357,7 +351,11 @@ "Constitution": 1, "Intelligence": 2, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Gnomish" + ], + "AdditionalLanguages": 0 }, { "Race": "Goblin", @@ -366,16 +364,11 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 - }, - { - "Race": "Goblin (Ixalan, Zendikar)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 2, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Goblin" + ], + "AdditionalLanguages": 0 }, { "Race": "Goliath", @@ -384,7 +377,11 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Giant" + ], + "AdditionalLanguages": 0 }, { "Race": "Halfling (Lightfoot)", @@ -393,7 +390,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 1 + "Charisma": 1, + "Languages": [ + "Halfling" + ], + "AdditionalLanguages": 0 }, { "Race": "Halfling (Stout)", @@ -402,7 +403,11 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Halfling" + ], + "AdditionalLanguages": 0 }, { "Race": "Half-Orc", @@ -411,7 +416,11 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Orc" + ], + "AdditionalLanguages": 0 }, { "Race": "Hobgoblin", @@ -420,7 +429,11 @@ "Constitution": 2, "Intelligence": 1, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Goblin" + ], + "AdditionalLanguages": 0 }, { "Race": "Human", @@ -429,7 +442,8 @@ "Constitution": 1, "Intelligence": 1, "Wisdom": 1, - "Charisma": 1 + "Charisma": 1, + "AdditionalLanguages": 1 }, { "Race": "Kenku", @@ -438,16 +452,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Khenra", - "Strength": 1, - "Dexterity": 2, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Auran" + ], + "AdditionalLanguages": 1 }, { "Race": "Kobold", @@ -456,115 +465,37 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 - }, - { - "Race": "Kobold (Midgard)", - "Strength": 0, - "Dexterity": 2, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Draconic" + ], + "AdditionalLanguages": 0 }, { - "Race": "Kor", - "Strength": 0, - "Dexterity": 2, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Lizardfolk (Southlands)", - "Strength": 2, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Lizardfolk (Volo’s)", + "Race": "Lizardfolk", "Strength": 0, "Dexterity": 0, "Constitution": 2, "Intelligence": 0, "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Merfolk (Cosi/Trickster)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 1, - "Wisdom": 0, - "Charisma": 2 + "Charisma": 0, + "Languages": [ + "Draconic" + ], + "AdditionalLanguages": 0 }, { - "Race": "Merfolk (Emeria/Wind)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 2, - "Charisma": 1 - }, - { - "Race": "Merfolk (Ula/Water)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 2, - "Wisdom": 0, - "Charisma": 1 - }, - { - "Race": "Merfolk (Ixalan Blue)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 2, - "Wisdom": 0, - "Charisma": 1 - }, - { - "Race": "Merfolk (Ixalan Green)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 2, - "Charisma": 1 - }, - { - "Race": "Minotaur (Amonkhet)", - "Strength": 2, - "Dexterity": 0, - "Constitution": 1, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 0 - }, - { - "Race": "Minotaur (Midgard, Southlands)", + "Race": "Minotaur", "Strength": 2, "Dexterity": 0, "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 - }, - { - "Race": "Naga", - "Strength": 0, - "Dexterity": 0, - "Constitution": 2, - "Intelligence": 1, - "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Giant" + ], + "AdditionalLanguages": 0 }, { "Race": "Orc", @@ -573,25 +504,11 @@ "Constitution": 1, "Intelligence": -2, "Wisdom": 0, - "Charisma": 0 - }, - { - "Race": "Orc (Ixalan)", - "Strength": 2, - "Dexterity": 0, - "Constitution": 1, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 0 - }, - { - "Race": "Ravenfolk", - "Strength": 0, - "Dexterity": 0, - "Constitution": 1, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 1 + "Charisma": 0, + "Languages": [ + "Orc" + ], + "AdditionalLanguages": 0 }, { "Race": "Shifter (Beasthide)", @@ -600,7 +517,11 @@ "Constitution": 2, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Sylvan" + ], + "AdditionalLanguages": 0 }, { "Race": "Shifter (Longtooth)", @@ -609,7 +530,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Sylvan" + ], + "AdditionalLanguages": 0 }, { "Race": "Shifter (Swiftstride)", @@ -618,7 +543,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 1 + "Charisma": 1, + "Languages": [ + "Sylvan" + ], + "AdditionalLanguages": 0 }, { "Race": "Shifter (Wildhunt)", @@ -627,16 +556,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 2, - "Charisma": 0 - }, - { - "Race": "Siren", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 2 + "Charisma": 0, + "Languages": [ + "Sylvan" + ], + "AdditionalLanguages": 0 }, { "Race": "Tabaxi", @@ -645,7 +569,8 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 1 + "Charisma": 1, + "AdditionalLanguages": 0 }, { "Race": "Tiefling", @@ -654,25 +579,50 @@ "Constitution": 0, "Intelligence": 1, "Wisdom": 0, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Infernal" + ], + "AdditionalLanguages": 0 + }, + { + "Race": "Tiefling (Dispater)", + "Strength": 0, + "Dexterity": 1, + "Constitution": 0, + "Intelligence": 0, + "Wisdom": 0, + "Charisma": 2, + "Languages": [ + "Infernal" + ], + "AdditionalLanguages": 0 }, { - "Race": "Tiefling (Dispater, Glasya)", + "Race": "Tiefling (Glasya)", "Strength": 0, "Dexterity": 1, "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Infernal" + ], + "AdditionalLanguages": 0 }, { - "Race": "Tiefling (Feral Variant)", + "Race": "Tiefling (Feral)", "Strength": 0, "Dexterity": 2, "Constitution": 0, "Intelligence": 1, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "Languages": [ + "Infernal" + ], + "AdditionalLanguages": 0 }, { "Race": "Tiefling (Fierna)", @@ -681,7 +631,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 1, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Infernal" + ], + "AdditionalLanguages": 0 }, { "Race": "Tiefling (Levistus)", @@ -690,7 +644,11 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Infernal" + ], + "AdditionalLanguages": 0 }, { "Race": "Tiefling (Zariel)", @@ -699,16 +657,11 @@ "Constitution": 0, "Intelligence": 0, "Wisdom": 0, - "Charisma": 2 - }, - { - "Race": "Tiefling (all other MTF)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 1, - "Wisdom": 0, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Infernal" + ], + "AdditionalLanguages": 0 }, { "Race": "Triton", @@ -717,25 +670,11 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 1 - }, - { - "Race": "Trollkin (Night Whisper)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 2, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Trollkin (Stonehide)", - "Strength": 1, - "Dexterity": 0, - "Constitution": 2, - "Intelligence": 0, - "Wisdom": 0, - "Charisma": 0 + "Charisma": 1, + "Languages": [ + "Aquan" + ], + "AdditionalLanguages": 0 }, { "Race": "Vedalken", @@ -744,34 +683,12 @@ "Constitution": 0, "Intelligence": 2, "Wisdom": 1, - "Charisma": 0 - }, - { - "Race": "Werelion", - "Strength": 1, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 2, - "Charisma": 0 - }, - { - "Race": "Vampire (Ixalan)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 0, - "Wisdom": 1, - "Charisma": 2 - }, - { - "Race": "Vampire (Zendikar)", - "Strength": 0, - "Dexterity": 0, - "Constitution": 0, - "Intelligence": 1, - "Wisdom": 0, - "Charisma": 2 + "Charisma": 0, + "Languages": [ + "Vedalken", + "Undercommon" + ], + "AdditionalLanguages": 0 }, { "Race": "Warforged (Juggernaut)", @@ -780,7 +697,8 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "AdditionalLanguages": 0 }, { "Race": "Warforged (Skirmisher)", @@ -789,7 +707,8 @@ "Constitution": 1, "Intelligence": 0, "Wisdom": 0, - "Charisma": 0 + "Charisma": 0, + "AdditionalLanguages": 0 }, { "Race": "Yuan-Ti Pureblood", @@ -798,6 +717,11 @@ "Constitution": 0, "Intelligence": 1, "Wisdom": 0, - "Charisma": 2 + "Charisma": 2, + "Languages": [ + "Abyssal", + "Draconic" + ], + "AdditionalLanguages": 0 } ] \ No newline at end of file