You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
9.2 KiB
197 lines
9.2 KiB
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? |
|
|
|
VOWELS = ["A","E","I","O","U"] |
|
|
|
SKILL_LIST = ["acrobatics", "animal_handling", "arcana", "athletics", "deception", "history", "insight", "intimidation", |
|
"investigation", "medicine", "nature", "perception", "performance", "persuasion", "religion", |
|
"sleight_of_hand", "stealth", "survival"] |
|
|
|
ATTRIBUTE_LIST = ["strength", "dexterity", "wisdom", "constitution", "intelligence", "charisma"] |
|
|
|
CLASS_LIST = ["Artificer","Barbarian","Bard","Cleric","Druid","Fighter","Monk","Paladin", |
|
"Ranger","Rogue","Sorcerer","Warlock","Wizard","Blood Hunter"] |
|
|
|
BACKGROUND_LIST = ["Acolyte", "Charlatan", "Criminal / Spy", "Entertainer", "Folk Hero", "Gladiator", |
|
"Guild Artisan / Guild Merchant", "Hermit", "Knight", "Noble", "Outlander", "Pirate", "Sage", |
|
"Sailor", "Soldier", "Urchin",] |
|
|
|
class HeroCreation: |
|
def __init__(self): |
|
self.name_generation() |
|
self.race_selection() |
|
self.race = self.race_string["Race"] |
|
#'job' is used in place of 'class' to avoid a function conflict |
|
self.job = random.choice(CLASS_LIST) |
|
self.job_characteristics() |
|
self.background = random.choice(BACKGROUND_LIST) |
|
self.stat_rolls() |
|
self.racial_bonuses() |
|
self.article = self.grammar() |
|
self.skill_generation() |
|
self.skill_proficiency() |
|
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.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}" |
|
f"\nArcana: {self.arcana}\nAthletics: {self.athletics}\nDeception: {self.deception}" |
|
f"\nHistory: {self.history}\nInsight: {self.insight}\nIntimidation: {self.intimidation}" |
|
f"\nInvestigation: {self.investigation}\nMedicine: {self.medicine}\nNature: {self.nature}" |
|
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}") |
|
|
|
#Assign the correct a/an article in the 'whoami' attr |
|
def grammar(self): |
|
if self.race[0] in VOWELS: |
|
return "an" |
|
else: |
|
return "a" |
|
|
|
def race_selection(self): |
|
with open('races.json') as json_file: |
|
race_data = json.load(json_file) |
|
chosen_race = random.choice(race_data) |
|
setattr(self,"race_string",chosen_race) |
|
|
|
def stat_rolls(self): |
|
# Configured to "Re-roll" 1s |
|
# To include 1s, increase the randint range to 1,6 |
|
for attribute in ATTRIBUTE_LIST: |
|
roll_list = [] |
|
for each in range(4): |
|
roll_list.append(random.randint(2, 6)) |
|
roll_list.remove(min(roll_list)) |
|
stat_total = sum(roll_list) |
|
setattr(self,f"{attribute}", stat_total) |
|
|
|
#Assign racial stat bonuses |
|
def racial_bonuses(self): |
|
self.charisma += self.race_string["Charisma"] |
|
self.constitution += self.race_string["Constitution"] |
|
self.dexterity += self.race_string["Dexterity"] |
|
self.intelligence += self.race_string["Intelligence"] |
|
self.strength += self.race_string["Strength"] |
|
self.wisdom += self.race_string["Wisdom"] |
|
|
|
def name_generation(self): |
|
with open("names.txt","r") as f: |
|
name_list = f.read().splitlines() |
|
first_name = random.choice(name_list) |
|
sur_name = random.choice(name_list) |
|
combined_name = f"{first_name} {sur_name}" |
|
setattr(self,"name",combined_name) |
|
|
|
#Created skill attributes with a base value of +0 to the roll |
|
def skill_generation(self): |
|
for skill in SKILL_LIST: |
|
setattr(self, skill, 0) |
|
if skill == "athletics": |
|
self.apply_skill_modifiers("strength",skill) |
|
elif skill in ["acrobatics", "sleight_of_hand", "stealth"]: |
|
self.apply_skill_modifiers("dexterity",skill) |
|
elif skill in ["arcana", "history", "investigation", "nature", "religion"]: |
|
self.apply_skill_modifiers("intelligence",skill) |
|
elif skill in ["animal_handling", "insight", "medicine", "perception", "survival"]: |
|
self.apply_skill_modifiers("wisdom",skill) |
|
elif skill in ["deception", "intimidation", "performance", "persuasion"]: |
|
self.apply_skill_modifiers("charisma",skill) |
|
|
|
def apply_skill_modifiers(self,attribute_name,skill_name): |
|
attribute = getattr(self,attribute_name) |
|
if attribute == 1: |
|
modifier = -5 |
|
elif attribute in [2, 3]: |
|
modifier = -4 |
|
elif attribute in [4, 5]: |
|
modifier = -3 |
|
elif attribute in [6, 7]: |
|
modifier = -2 |
|
elif attribute in [8, 9]: |
|
modifier = -1 |
|
elif attribute in [10, 11]: |
|
modifier = 0 |
|
elif attribute in [12, 13]: |
|
modifier = 1 |
|
elif attribute in [14, 15]: |
|
modifier = 2 |
|
elif attribute in [16, 17]: |
|
modifier = 3 |
|
elif attribute in [18, 19]: |
|
modifier = 4 |
|
elif attribute in [20, 21]: |
|
modifier = 5 |
|
else: |
|
modifier = 0 |
|
setattr(self,skill_name,modifier) |
|
|
|
def skill_proficiency(self): |
|
with open('backgrounds.json') as json_file: |
|
background_data = json.load(json_file) |
|
# Is this actually a dict? |
|
background_dict = background_data[self.background]["Skills"] |
|
for skill in background_dict: |
|
current_score = getattr(self, skill) |
|
new_score = str(current_score + 2) |
|
setattr(self, skill, f"{new_score} (Prof)") |
|
with open('jobs.json') as json_file: |
|
job_data = json.load(json_file) |
|
# Is this actually a dict? |
|
job_dict = job_data[self.job] |
|
proficiencies = job_dict["Proficiencies"] |
|
job_skill_list = job_dict["Skills"] |
|
for skill in background_dict: |
|
if skill in job_skill_list: |
|
job_skill_list.remove(skill) |
|
for each in range(proficiencies): |
|
proficient_skill = random.choice(job_skill_list) |
|
job_skill_list.remove(proficient_skill) |
|
current_score = getattr(self,proficient_skill) |
|
new_score = str(current_score + 2) |
|
setattr(self,proficient_skill,f"{new_score} (Prof)") |
|
|
|
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"] |
|
setattr(self,"hit_die",hit_die_value) |
|
starting_hp_value = job_data[self.job]["Starting HP"] |
|
setattr(self,"starting_hp",starting_hp_value) |
|
|
|
#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 |
|
# def stat_moves(self): |
|
# finished = False |
|
# while not finished: |
|
# move_request = input("Would you like to move any of these stats around? (y/n)").lower() |
|
# 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_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): |
|
# stat_1_value = getattr(self, stat_1) |
|
# stat_2_value = getattr(self, stat_2) |
|
# setattr(self, stat_1, stat_2_value) |
|
# setattr(self, stat_2, stat_1_value) |
|
# self.update_stat_block() |
|
# print(self.whoami) |
|
# print(self.stat_block) |
|
# elif move_request == "n": |
|
# finished = True |
|
|
|
#Currently only used for the stat_moves functionality. Disabling for now |
|
# def update_stat_block(self): |
|
# 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}") |