cleaning up code
This commit is contained in:
25
README.md
25
README.md
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
This tool uses the Old School Essentials (OSE) ruleset for tabletop RPGs in order to randomly generate a character.
|
This tool uses the Old School Essentials (OSE) ruleset for tabletop RPGs in order to randomly generate a character.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
### What is Dungeons & Dragons?
|
### What is Dungeons & Dragons?
|
||||||
Dungeons & Dragons, also known as D&D, is a pen and paper table top game. One player is the story teller, the "dungeon master" and the others interact with the story using their "adventurers." An adventurer is a playable character, who has a mixture of abilities and powers, the details of which are often kept on piece of paper called a "character sheet."
|
Dungeons & Dragons, also known as D&D, is a pen and paper table top game. One player is the story teller, the "dungeon master" and the others interact with the story using their "adventurers." An adventurer is a playable character, who has a mixture of abilities and powers, the details of which are often kept on piece of paper called a "character sheet."
|
||||||
|
|
||||||
@@ -20,3 +22,26 @@ This app accomplishes a few things, but mainly it creates a character for you.
|
|||||||
- You can generate a whole party of characters
|
- You can generate a whole party of characters
|
||||||
- Within that party, you can adjust their level, and the number of characters
|
- Within that party, you can adjust their level, and the number of characters
|
||||||
- You can create a single character to edit
|
- You can create a single character to edit
|
||||||
|
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
### Install
|
||||||
|
This is a flask web application, to install:
|
||||||
|
|
||||||
|
1. Clone this repo
|
||||||
|
2. Install requirements, `python3 pip install -r requirements.txt`
|
||||||
|
3. To run the webserver execute `flask run` while in your cloned repository's top folder.
|
||||||
|
|
||||||
|
### To Use
|
||||||
|
There are two main generators, one for a single character and another for a group, or a "party" of characters.
|
||||||
|
1. Character Generator
|
||||||
|
- You may select a class and a level
|
||||||
|
- The re-roll button always starts the character back to level 1
|
||||||
|
2. Party Generator
|
||||||
|
- You may also select the level for this group
|
||||||
|
- You may select the count, between 2 and 5.
|
||||||
|
- If you want to have the party persist across refreshes, level and size changes, keep "cached" on
|
||||||
|
- Otherwise, "not cached" will always generate a new party
|
||||||
|
- If you find a single character interesting, you may "select" them and it will load **this** character in the "charater generator."
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,28 @@ def roll_dice(count, sides):
|
|||||||
|
|
||||||
# Player Character Classes
|
# Player Character Classes
|
||||||
class Adventurer:
|
class Adventurer:
|
||||||
|
ability_score_modifiers = {
|
||||||
|
'strength' : { 3 : { 'melee' : -3, 'open doors': 1 }, 5 : { 'melee' : -2, 'open doors': 1 }, 8 : { 'melee' : -1, 'open doors': 1 },
|
||||||
|
12 : { 'melee' : 0, 'open doors': 2 }, 15 : { 'melee' : 1, 'open doors': 3 }, 17 : { 'melee' : 2, 'open doors': 4 },
|
||||||
|
18 : { 'melee' : 3, 'open doors': 5 } },
|
||||||
|
'intelligence' : { 3 : { 'languages' : 'native, broken speech', 'literacy': 'illiterate' }, 5 : { 'languages' : 'native', 'literacy': 'illiterate' },
|
||||||
|
8 : { 'languages' : 'native', 'literacy': 'basic' }, 12 : { 'languages' :'native', 'literacy': 'literate' },
|
||||||
|
15 : { 'languages' : 'native +1 additional', 'literacy': 'literate'}, 17 : { 'languages' : 'native +2 additional', 'literacy': 'literate' },
|
||||||
|
18 : { 'languages' : 'native +3 additional', 'literacy': 'literate' } },
|
||||||
|
'wisdom' : { 3 : { 'magic saves' : -3 }, 5 : { 'magic saves' : -2 }, 8 : { 'magic saves' : -1 }, 12 : { 'magic saves' : 0,},
|
||||||
|
15 : { 'magic saves' : 1 }, 17 : { 'magic saves' : 2 }, 18 : { 'magic saves' : 3 } },
|
||||||
|
'dexterity' : { 3 : { 'AC' : -3, 'missile': -3, 'initiative' : -2 }, 5 : { 'AC' : -2, 'missile': -2, 'initiative' : -1},
|
||||||
|
8 : { 'AC' : -1, 'missile': -1, 'initiative' : -1 }, 12 : { 'AC' : 0, 'missile': 0, 'initiative' : 0 },
|
||||||
|
15 : { 'AC' : 1, 'missile': 1, 'initiative' : 1 }, 17 : { 'AC' : 2, 'missile': 2, 'initiative' : 1 },
|
||||||
|
18 : { 'AC' : 3, 'missile': 3, 'initiative' : 2 } },
|
||||||
|
'constitution' : { 3 : { 'hit points' : -3 }, 5 : { 'hit points' : -2 }, 8 : { 'hit points' : -1 }, 12 : { 'hit points' : 0 },
|
||||||
|
15 : { 'hit points' : 1 }, 17 : { 'hit points' : 2 }, 18 : { 'hit points' : 3 } },
|
||||||
|
'charisma' : { 3 : { 'npc reactions' : -2, 'max retainers': 1, 'retainer loyalty' : 4 }, 5 : { 'npc reactions' : -2, 'max retainers': 2, 'retainer loyalty' : 5 },
|
||||||
|
8 : { 'npc reactions' : -1, 'max retainers': 3, 'retainer loyalty' : 6 }, 12 : { 'npc reactions' : 0, 'max retainers': 4, 'retainer loyalty' : 7 },
|
||||||
|
15 : { 'npc reactions' : 1, 'max retainers': 5, 'retainer loyalty' : 8 }, 17 : { 'npc reactions' : 1, 'max retainers': 6, 'retainer loyalty' : 9 },
|
||||||
|
18 : { 'npc reactions' : 2, 'max retainers': 7, 'retainer loyalty' : 10 } }
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, c_id: str, level=1, attributes={}) -> None:
|
def __init__(self, c_id: str, level=1, attributes={}) -> None:
|
||||||
# using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get
|
# using a get() method to pull an attribute else use a default value, https://python-academy.org/en/handbook/get
|
||||||
self.identifier = c_id
|
self.identifier = c_id
|
||||||
@@ -27,7 +49,7 @@ class Adventurer:
|
|||||||
self.gold= roll_dice(3,6)
|
self.gold= roll_dice(3,6)
|
||||||
self.torches = roll_dice(1,6)
|
self.torches = roll_dice(1,6)
|
||||||
self.rations = roll_dice(1,6)
|
self.rations = roll_dice(1,6)
|
||||||
self.equipment = self.roll_equipment()
|
self.equipment = self.set_equipment()
|
||||||
# all armor, individual classes may have overrides
|
# all armor, individual classes may have overrides
|
||||||
self.possible_armor = list(armor.keys())
|
self.possible_armor = list(armor.keys())
|
||||||
# all weapons, individual classes may have overrides
|
# all weapons, individual classes may have overrides
|
||||||
@@ -43,21 +65,21 @@ class Adventurer:
|
|||||||
self.thief_skills = None
|
self.thief_skills = None
|
||||||
self.turn_undead = None
|
self.turn_undead = None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self) -> str:
|
||||||
return f"{self.player_class}"
|
return f"{self.player_class}"
|
||||||
|
|
||||||
def get_subclass_dict():
|
def get_subclass_dict() -> dict:
|
||||||
subclasses = {}
|
subclasses = {}
|
||||||
for subclass in Adventurer.__subclasses__():
|
for subclass in Adventurer.__subclasses__():
|
||||||
subclasses[subclass.adv_class] = subclass
|
subclasses[subclass.adv_class] = subclass
|
||||||
return subclasses
|
return subclasses
|
||||||
|
|
||||||
def get_json(self):
|
def get_json(self) -> dict:
|
||||||
char_dict = self.__dict__
|
char_dict = self.__dict__
|
||||||
char_json = json.dumps(char_dict)
|
char_json = json.dumps(char_dict)
|
||||||
return char_dict
|
return char_dict
|
||||||
|
|
||||||
def vertical_sheet(self):
|
def vertical_sheet(self) -> list:
|
||||||
sheet = []
|
sheet = []
|
||||||
sheet.append('{0: <28}'.format(f"| {self.player_class.title()} - Level {self.level}"))
|
sheet.append('{0: <28}'.format(f"| {self.player_class.title()} - Level {self.level}"))
|
||||||
for key, val in self.get_attributes().items():
|
for key, val in self.get_attributes().items():
|
||||||
@@ -89,7 +111,7 @@ class Adventurer:
|
|||||||
sheet = [ line + "|" for line in sheet ]
|
sheet = [ line + "|" for line in sheet ]
|
||||||
return sheet
|
return sheet
|
||||||
|
|
||||||
def full_sheet(self):
|
def full_sheet(self) -> list:
|
||||||
sheet = { 1: [], 2 : [] }
|
sheet = { 1: [], 2 : [] }
|
||||||
sheet[1].append('{0: <60}'.format(f"| Character Name:"))
|
sheet[1].append('{0: <60}'.format(f"| Character Name:"))
|
||||||
sheet[1].append('{0: <60}'.format(f"| Player Name :"))
|
sheet[1].append('{0: <60}'.format(f"| Player Name :"))
|
||||||
@@ -105,26 +127,27 @@ class Adventurer:
|
|||||||
sheet[1].append('{0: <60}'.format(f"| Charisma:\t{self.charisma} SpellMod: {self.ac}"))
|
sheet[1].append('{0: <60}'.format(f"| Charisma:\t{self.charisma} SpellMod: {self.ac}"))
|
||||||
return sheet
|
return sheet
|
||||||
|
|
||||||
def get_attributes(self):
|
def get_attributes(self) -> dict:
|
||||||
attribute_list = ['strength', 'intelligence', 'wisdom', 'dexterity', 'constitution', 'charisma']
|
attribute_list = ['strength', 'intelligence', 'wisdom', 'dexterity', 'constitution', 'charisma']
|
||||||
return {k: self.__dict__[k] for k in attribute_list}
|
return {k: self.__dict__[k] for k in attribute_list}
|
||||||
|
|
||||||
def get_best_prime_attribute(self):
|
def get_best_prime_attribute(self) -> str:
|
||||||
attribute_list = [ 'strength', 'intelligence', 'wisdom', 'dexterity' ]
|
attribute_list = [ 'strength', 'intelligence', 'wisdom', 'dexterity' ]
|
||||||
prime_attributes = {k: self.__dict__[k] for k in attribute_list}
|
prime_attributes = {k: self.__dict__[k] for k in attribute_list}
|
||||||
# return highest, found this at https://stackoverflow.com/a/280156
|
# return highest, found this at https://stackoverflow.com/a/280156
|
||||||
return max(prime_attributes, key=prime_attributes.get)
|
return max(prime_attributes, key=prime_attributes.get)
|
||||||
|
|
||||||
def roll_equipment(self):
|
def set_equipment(self):
|
||||||
equipment = [ 'backpack', 'tinderbox', 'waterskin' ]
|
equipment = [ 'backpack', 'tinderbox', 'waterskin' ]
|
||||||
random_items = [ random.choice(adventuring_gear) for i in range(2) ]
|
for i in range(2):
|
||||||
for item in random_items:
|
item = ""
|
||||||
equipment += item.split("+")
|
while item not in equipment:
|
||||||
while len(equipment) < 7:
|
item = random.choice(adventuring_gear)
|
||||||
equipment.append("")
|
if item not in equipment:
|
||||||
|
equipment.append(item)
|
||||||
return equipment
|
return equipment
|
||||||
|
|
||||||
def select_spells(self, spell_list):
|
def select_spells(self, spell_list) -> list:
|
||||||
spell_book = []
|
spell_book = []
|
||||||
for spell_level, count in self.spells.items():
|
for spell_level, count in self.spells.items():
|
||||||
if count != "-":
|
if count != "-":
|
||||||
@@ -132,10 +155,11 @@ class Adventurer:
|
|||||||
new_spell = ""
|
new_spell = ""
|
||||||
while new_spell not in spell_book:
|
while new_spell not in spell_book:
|
||||||
new_spell = random.choice(spell_list[spell_level])
|
new_spell = random.choice(spell_list[spell_level])
|
||||||
|
if new_spell not in spell_book:
|
||||||
spell_book.append(new_spell)
|
spell_book.append(new_spell)
|
||||||
return spell_book
|
return spell_book
|
||||||
|
|
||||||
def roll_all_hit_points(self):
|
def roll_all_hit_points(self) -> list:
|
||||||
hp_list = []
|
hp_list = []
|
||||||
prev_hit_dice = 0
|
prev_hit_dice = 0
|
||||||
for i in range(self.__class__.max_level):
|
for i in range(self.__class__.max_level):
|
||||||
@@ -151,10 +175,10 @@ class Adventurer:
|
|||||||
hp_list.append(hp_roll)
|
hp_list.append(hp_roll)
|
||||||
return hp_list
|
return hp_list
|
||||||
|
|
||||||
def get_class_progression_for_level(self):
|
def get_class_progression_for_level(self) -> list:
|
||||||
return list(filter(lambda d: d['level'] == self.level, self.__class__.progression))[0]
|
return list(filter(lambda d: d['level'] == self.level, self.__class__.progression))[0]
|
||||||
|
|
||||||
def set_level(self, new_level):
|
def set_level(self, new_level) -> None:
|
||||||
self.level = new_level
|
self.level = new_level
|
||||||
self.hp = sum(self.hp_rolls[:self.level])
|
self.hp = sum(self.hp_rolls[:self.level])
|
||||||
if self.player_class in [ "magic user", "elf" ]:
|
if self.player_class in [ "magic user", "elf" ]:
|
||||||
@@ -163,8 +187,9 @@ class Adventurer:
|
|||||||
if self.player_class == "cleric":
|
if self.player_class == "cleric":
|
||||||
self.spells = Cleric.spells[self.level]
|
self.spells = Cleric.spells[self.level]
|
||||||
self.spell_book = self.select_spells(cleric_spells)
|
self.spell_book = self.select_spells(cleric_spells)
|
||||||
|
self.turn_undead = Cleric.turn_undead[self.level]
|
||||||
|
|
||||||
def set_attack_bonus(self):
|
def set_attack_bonus(self) -> int:
|
||||||
prog = self.get_class_progression_for_level()
|
prog = self.get_class_progression_for_level()
|
||||||
thac0 = prog['thac0']
|
thac0 = prog['thac0']
|
||||||
atk = 19 - thac0
|
atk = 19 - thac0
|
||||||
@@ -321,7 +346,7 @@ class Cleric(Adventurer):
|
|||||||
self.spells = Cleric.spells[self.level]
|
self.spells = Cleric.spells[self.level]
|
||||||
self.spell_book = self.select_spells(cleric_spells)
|
self.spell_book = self.select_spells(cleric_spells)
|
||||||
self.atk = self.set_attack_bonus()
|
self.atk = self.set_attack_bonus()
|
||||||
self.turn_undead = Cleric.turn_undead
|
self.turn_undead = Cleric.turn_undead[self.level]
|
||||||
|
|
||||||
class Thief(Adventurer):
|
class Thief(Adventurer):
|
||||||
adv_class = "thief"
|
adv_class = "thief"
|
||||||
|
|||||||
13
app.py
13
app.py
@@ -18,7 +18,7 @@ def compress_character(adventurer):
|
|||||||
def return_character_from_cookie(cookie):
|
def return_character_from_cookie(cookie):
|
||||||
cookie_decompressed = base64.urlsafe_b64decode(cookie)
|
cookie_decompressed = base64.urlsafe_b64decode(cookie)
|
||||||
adventurer_dict = json.loads(zlib.decompress(cookie_decompressed).decode())
|
adventurer_dict = json.loads(zlib.decompress(cookie_decompressed).decode())
|
||||||
adventurer = createCharacterWithDict(adventurer_dict)
|
adventurer = AdventurerGen.create_from_dict(adventurer_dict)
|
||||||
return adventurer
|
return adventurer
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
@@ -47,7 +47,7 @@ def party():
|
|||||||
if count < 2 or count > 5:
|
if count < 2 or count > 5:
|
||||||
count = 4
|
count = 4
|
||||||
# generate an adventuring party
|
# generate an adventuring party
|
||||||
adv_party = returnParty(count, level)
|
adv_party = PartyGen.get_new_party(count, level)
|
||||||
# check for cookies present
|
# check for cookies present
|
||||||
if request.cookies:
|
if request.cookies:
|
||||||
stored_count = len(request.cookies)
|
stored_count = len(request.cookies)
|
||||||
@@ -65,7 +65,7 @@ def party():
|
|||||||
adv_party.set_party(stored_adv_party, count, level)
|
adv_party.set_party(stored_adv_party, count, level)
|
||||||
if count > stored_count:
|
if count > stored_count:
|
||||||
extension = count - stored_count
|
extension = count - stored_count
|
||||||
more_party_members = returnParty(extension,level).adventurers
|
more_party_members = PartyGen.get_new_party(extension,level).adventurers
|
||||||
extended_party = stored_adv_party + more_party_members
|
extended_party = stored_adv_party + more_party_members
|
||||||
adv_party.set_party(extended_party, count, level)
|
adv_party.set_party(extended_party, count, level)
|
||||||
if count < stored_count:
|
if count < stored_count:
|
||||||
@@ -103,17 +103,14 @@ def character():
|
|||||||
# reroll until we get our class
|
# reroll until we get our class
|
||||||
while character.player_class != role.replace("-"," "):
|
while character.player_class != role.replace("-"," "):
|
||||||
new_char = Adventurer(c_id, level)
|
new_char = Adventurer(c_id, level)
|
||||||
selected_class = ClassSelector(new_char).selection()
|
selected_class = AdventurerGen(new_char).selection()
|
||||||
character = selected_class(new_char.identifier, new_char.level, new_char.get_attributes())
|
character = selected_class(new_char.identifier, new_char.level, new_char.get_attributes())
|
||||||
else:
|
else:
|
||||||
new_char = Adventurer(c_id, level)
|
new_char = Adventurer(c_id, level)
|
||||||
selected_class = ClassSelector(new_char).selection()
|
selected_class = AdventurerGen(new_char).selection()
|
||||||
character = selected_class(new_char.identifier, new_char.level, new_char.get_attributes())
|
character = selected_class(new_char.identifier, new_char.level, new_char.get_attributes())
|
||||||
role = character.player_class
|
role = character.player_class
|
||||||
level = character.level
|
level = character.level
|
||||||
# bug fix for cleric issues
|
|
||||||
if character.player_class == "cleric":
|
|
||||||
character.turn_undead = { int(k) : v for k,v in character.turn_undead.items() }
|
|
||||||
response = make_response(render_template("character.html", character=character, level=level, cache=cache,role=role))
|
response = make_response(render_template("character.html", character=character, level=level, cache=cache,role=role))
|
||||||
cookie_string, cookie_data = compress_character(character)
|
cookie_string, cookie_data = compress_character(character)
|
||||||
response.set_cookie(cookie_string, cookie_data)
|
response.set_cookie(cookie_string, cookie_data)
|
||||||
|
|||||||
77
main.py
77
main.py
@@ -5,7 +5,7 @@ import json
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
# Player Class Selector
|
# Player Class Selector
|
||||||
class ClassSelector():
|
class AdventurerGen():
|
||||||
def __init__(self, player: Adventurer) -> None:
|
def __init__(self, player: Adventurer) -> None:
|
||||||
self.player = player
|
self.player = player
|
||||||
# https://stackoverflow.com/questions/3862310/how-to-find-all-the-subclasses-of-a-class-given-its-name
|
# https://stackoverflow.com/questions/3862310/how-to-find-all-the-subclasses-of-a-class-given-its-name
|
||||||
@@ -16,11 +16,11 @@ class ClassSelector():
|
|||||||
# run function to randomly select an adventurer class
|
# run function to randomly select an adventurer class
|
||||||
self.selected_class = self.selection()
|
self.selected_class = self.selection()
|
||||||
|
|
||||||
def return_class_by_best_attribute(self):
|
def return_class_by_best_attribute(self) -> Adventurer:
|
||||||
# for adventurer classes in available classes, return the one where that classes' prime requisite is equal to the players best attribute
|
# for adventurer classes in available classes, return the one where that classes' prime requisite is equal to the players best attribute
|
||||||
return [adv_class for adv_class in self.available_classes if adv_class.prime_requisite == self.player.get_best_prime_attribute()][0]
|
return [adv_class for adv_class in self.available_classes if adv_class.prime_requisite == self.player.get_best_prime_attribute()][0]
|
||||||
|
|
||||||
def return_classes_with_requirements(self):
|
def return_classes_with_requirements(self) -> list:
|
||||||
p_attrs = self.player.get_attributes()
|
p_attrs = self.player.get_attributes()
|
||||||
possible_classes = []
|
possible_classes = []
|
||||||
for c in self.classes_with_reqs:
|
for c in self.classes_with_reqs:
|
||||||
@@ -32,7 +32,7 @@ class ClassSelector():
|
|||||||
possible_classes.append(c)
|
possible_classes.append(c)
|
||||||
return possible_classes
|
return possible_classes
|
||||||
|
|
||||||
def selection(self):
|
def selection(self) -> Adventurer:
|
||||||
best_prime_attribute = self.player.get_best_prime_attribute()
|
best_prime_attribute = self.player.get_best_prime_attribute()
|
||||||
# create an array of possible player classes, add the best choice per player's best core attributes
|
# create an array of possible player classes, add the best choice per player's best core attributes
|
||||||
possible_classes = [ self.return_class_by_best_attribute() ]
|
possible_classes = [ self.return_class_by_best_attribute() ]
|
||||||
@@ -41,7 +41,18 @@ class ClassSelector():
|
|||||||
selected_class = random.choice(possible_classes)
|
selected_class = random.choice(possible_classes)
|
||||||
return selected_class
|
return selected_class
|
||||||
|
|
||||||
class PartyGenerator():
|
def create_from_dict(character_dict) -> Adventurer:
|
||||||
|
chosen_class = character_dict['player_class']
|
||||||
|
c_id = character_dict['identifier']
|
||||||
|
level = character_dict['level']
|
||||||
|
adv_dict = Adventurer.get_subclass_dict()
|
||||||
|
chosen_class = adv_dict[chosen_class]
|
||||||
|
new_char = chosen_class(c_id=c_id, level=level)
|
||||||
|
for k, v in character_dict.items():
|
||||||
|
setattr(new_char,k, v)
|
||||||
|
return new_char
|
||||||
|
|
||||||
|
class PartyGen():
|
||||||
def __init__(self, party_size: int, party_level: int) -> None:
|
def __init__(self, party_size: int, party_level: int) -> None:
|
||||||
self.size = party_size
|
self.size = party_size
|
||||||
self.level = party_level
|
self.level = party_level
|
||||||
@@ -56,7 +67,7 @@ class PartyGenerator():
|
|||||||
attempts = 0
|
attempts = 0
|
||||||
while new_player.player_class not in self.adventurer_types:
|
while new_player.player_class not in self.adventurer_types:
|
||||||
attempts += 1
|
attempts += 1
|
||||||
selected_class = ClassSelector(new_player).selection()
|
selected_class = AdventurerGen(new_player).selection()
|
||||||
new_player = selected_class(new_player.identifier, new_player.level, new_player.get_attributes())
|
new_player = selected_class(new_player.identifier, new_player.level, new_player.get_attributes())
|
||||||
# i couldnt randomly generate a scenario where a character couldn't be added, but it seems possible, so this is the hard cut off
|
# i couldnt randomly generate a scenario where a character couldn't be added, but it seems possible, so this is the hard cut off
|
||||||
if (new_player.player_class not in self.adventurer_types) or (attempts > 10):
|
if (new_player.player_class not in self.adventurer_types) or (attempts > 10):
|
||||||
@@ -70,6 +81,24 @@ class PartyGenerator():
|
|||||||
self.adventurers = adventurers
|
self.adventurers = adventurers
|
||||||
self.adventurer_types = []
|
self.adventurer_types = []
|
||||||
|
|
||||||
|
def get_new_party(party_size, party_level):
|
||||||
|
# keep variables within expected ranges
|
||||||
|
if party_size <= 0 or party_size > 5:
|
||||||
|
party_size = 1
|
||||||
|
if party_level < 1 or party_level > 5:
|
||||||
|
party_level = 1
|
||||||
|
# generate an aventuring party per size and level
|
||||||
|
new_party = PartyGen(party_size, party_level)
|
||||||
|
# for adventurers select classes
|
||||||
|
new_party.gen_party()
|
||||||
|
# return the created adventurer party
|
||||||
|
return new_party
|
||||||
|
|
||||||
|
def get_character(self, identifer):
|
||||||
|
for adv in self.adventurers:
|
||||||
|
if adv.identifier == identifier:
|
||||||
|
return adv
|
||||||
|
|
||||||
def get_character_sheets(self):
|
def get_character_sheets(self):
|
||||||
sheet_string = ""
|
sheet_string = ""
|
||||||
character_sheets = []
|
character_sheets = []
|
||||||
@@ -87,47 +116,15 @@ class PartyGenerator():
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.adventurers}"
|
return f"{self.adventurers}"
|
||||||
|
|
||||||
def returnParty(party_size, party_level):
|
|
||||||
# keep variables within expected ranges
|
|
||||||
if party_size <= 0 or party_size > 5:
|
|
||||||
party_size = 1
|
|
||||||
if party_level < 1 or party_level > 5:
|
|
||||||
party_level = 1
|
|
||||||
# generate an aventuring party per size and level
|
|
||||||
new_party = PartyGenerator(party_size, party_level)
|
|
||||||
# for adventurers select classes
|
|
||||||
new_party.gen_party()
|
|
||||||
# return the created adventurer party
|
|
||||||
return new_party
|
|
||||||
|
|
||||||
def returnCharacter(identifer):
|
|
||||||
for adv in new_party.adventurers:
|
|
||||||
if adv.identifier == identifier:
|
|
||||||
return adv
|
|
||||||
|
|
||||||
def createCharacterWithDict(character_dict) -> Adventurer:
|
|
||||||
chosen_class = character_dict['player_class']
|
|
||||||
c_id = character_dict['identifier']
|
|
||||||
level = character_dict['level']
|
|
||||||
adv_dict = Adventurer.get_subclass_dict()
|
|
||||||
chosen_class = adv_dict[chosen_class]
|
|
||||||
new_char = chosen_class(c_id=c_id, level=level)
|
|
||||||
for k, v in character_dict.items():
|
|
||||||
setattr(new_char,k, v)
|
|
||||||
return new_char
|
|
||||||
|
|
||||||
# used for local testing
|
# used for local testing
|
||||||
def main():
|
def main():
|
||||||
adv_dict = Adventurer.get_subclass_dict()
|
adv_dict = Adventurer.get_subclass_dict()
|
||||||
test_class = adv_dict['cleric']
|
test_class = adv_dict['cleric']
|
||||||
new_char = test_class(c_id="adv-1",level=2)
|
new_char = test_class(c_id="adv-1",level=2)
|
||||||
print(new_char.adv_class)
|
for line in new_char.vertical_sheet():
|
||||||
print(new_char.level)
|
print(line)
|
||||||
print(new_char.hp_rolls)
|
|
||||||
print(new_char.hp)
|
|
||||||
print(new_char.atk)
|
|
||||||
for k,v in new_char.turn_undead[new_char.level].items():
|
|
||||||
print(k, v)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
flask
|
Flask==3.1.3
|
||||||
flask-session
|
|
||||||
|
|||||||
@@ -132,7 +132,7 @@
|
|||||||
<h5>Turn Undead</h5>
|
<h5>Turn Undead</h5>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead><tr><th>Monster Hit Die</th><th>Roll to Turn</th><th></th><th></th></thead>
|
<thead><tr><th>Monster Hit Die</th><th>Roll to Turn</th><th></th><th></th></thead>
|
||||||
{%for k,v in character.turn_undead[character.level].items() %}
|
{%for k,v in character.turn_undead.items() %}
|
||||||
<tbody><tr><th>{{k}} Hit Die</th><td>{{v}}</td><th></th><td></td></tr></tbody>
|
<tbody><tr><th>{{k}} Hit Die</th><td>{{v}}</td><th></th><td></td></tr></tbody>
|
||||||
{%endfor%}
|
{%endfor%}
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Reference in New Issue
Block a user