|
|
@ -1,8 +1,8 @@ |
|
|
|
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"] |
|
|
|
|
|
|
|
|
|
|
@ -23,8 +23,10 @@ instrument_list = ["Bagpipes", "Birdpipes", "Clarinet", "Drum", "Dulcimer", "Fid |
|
|
|
"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,6 +37,17 @@ 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() |
|
|
@ -46,6 +59,7 @@ class HeroCreation: |
|
|
|
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() |
|
|
@ -58,8 +72,7 @@ class HeroCreation: |
|
|
|
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,9 +82,11 @@ 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") |
|
|
|
|
|
|
|
self.skill_bonuses = ( |
|
|
|
|
|
|
|
f"Skill Bonuses\n----------\nAcrobatics: {self.acrobatics}\nAnimal Handling: {self.animal_handling}" |
|
|
|
f"\nArcana: {self.arcana}\nAthletics: {self.athletics}\nDeception: {self.deception}" |
|
|
|
f"\nArcana: {self.arcana}\nAthletics: {self.athletics}\nDeception: {self.deception}" |
|
|
|
f"\nHistory: {self.history}\nInsight: {self.insight}\nIntimidation: {self.intimidation}" |
|
|
|
f"\nHistory: {self.history}\nInsight: {self.insight}\nIntimidation: {self.intimidation}" |
|
|
|
f"\nInvestigation: {self.investigation}\nMedicine: {self.medicine}\nNature: {self.nature}" |
|
|
|
f"\nInvestigation: {self.investigation}\nMedicine: {self.medicine}\nNature: {self.nature}" |
|
|
@ -81,7 +96,8 @@ class HeroCreation: |
|
|
|
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") |
|
|
|
|
|
|
|
|
|
|
@ -217,7 +233,6 @@ class HeroCreation: |
|
|
|
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) |
|
|
@ -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,6 +370,27 @@ 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 |
|
|
@ -362,8 +399,10 @@ class HeroCreation: |
|
|
|
# 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) |
|
|
|