Files
dungeon-sheets/dungeonsheets/character.py
T

174 lines
4.3 KiB
Python

"""Tools for describing a player character."""
import re
from .stats import Ability, Skill
from .dice import read_dice_str
dice_re = re.compile('(\d+)d(\d+)')
class Character():
"""A generic player character. Intended to be subclasses by the
various classes.
"""
# General attirubtes
name = ""
class_name = ""
player_name = ""
background = ""
level = 1
alignment = "Neutral"
race = "Human"
xp = 0
speed = 30 # In feet
# Hit points
hp_max = 10
hit_dice_faces = 2
# Base stats (ability scores)
strength = Ability()
dexterity = Ability()
constitution = Ability()
intelligence = Ability()
wisdom = Ability()
charisma = Ability()
saving_throw_proficiencies = []
# Skills
acrobatics = Skill(ability='dexterity')
animal_handling = Skill(ability='wisdom')
arcana = Skill(ability='intelligence')
athletics = Skill(ability='strength')
deception = Skill(ability='charisma')
history = Skill(ability='intelligence')
insight = Skill(ability='wisdom')
intimidation = Skill(ability='charisma')
investigation = Skill(ability='intelligence')
medicine = Skill(ability='wisdom')
nature = Skill(ability='intelligence')
perception = Skill(ability='wisdom')
performance = Skill(ability='charisma')
persuasian = Skill(ability='charisma')
religion = Skill(ability='intelligence')
sleight_of_hand = Skill(ability='dexterity')
stealth = Skill(ability='dexterity')
survival = Skill(ability='wisdom')
# Characteristics
personality_traits = ""
ideals = ""
bonds = ""
flaws = ""
# Inventory
cp = 0
sp = 0
ep = 0
gp = 0
pp = 0
def __init__(self, **attrs):
"""Takes a bunch of attrs and passes them to ``set_attrs``"""
self.set_attrs(**attrs)
def set_attrs(self, **attrs):
"""Bulk setting of attributes. Useful for loading a character from a
dictionary."""
for attr, val in attrs.items():
setattr(self, attr, val)
@property
def hit_dice(self):
"""What type and how many dice to use for re-gaining hit points.
To change, set hit_dice_num and hit_dice_faces."""
return f"{self.level}d{self.hit_dice_faces}"
@property
def proficiency_bonus(self):
if self.level < 5:
prof = 2
elif 5 <= self.level < 9:
prof = 3
elif 9 <= self.level < 13:
prof = 4
elif 13 <= self.level < 17:
prof = 5
elif 17 <= self.level:
prof = 6
return prof
@property
def armor_class(self):
"""Armor class, without items."""
return 10 + self.dexterity.modifier
class Barbarian(Character):
class_name = 'Barbarian'
hit_dice_faces = 12
saving_throw_proficiencies = ['strength', 'constitution']
class Bard(Character):
class_name = 'Bard'
hit_dice_faces = 8
saving_throw_proficiencies = ['dexterity', 'charisma']
class Cleric(Character):
class_name = 'Cleric'
hit_dice_faces = 8
saving_throw_proficiencies = ['wisdom', 'charisma']
class Druid(Character):
class_name = 'Druid'
hit_dice_faces = 8
saving_throw_proficiencies = ['intelligence', 'wisdom']
class Fighter(Character):
class_name = 'Fighter'
hit_dice_faces = 10
saving_throw_proficiencies = ['strength', 'constitution']
class Monk(Character):
class_name = 'Monk'
hit_dice_faces = 8
saving_throw_proficiencies = ['strength', 'dexterity']
class Paladin(Character):
class_name = 'Paladin'
hit_dice_faces = 10
saving_throw_proficiencies = ['wisdom', 'charisma']
class Ranger(Character):
class_name = 'Ranger'
hit_dice_faces = 10
saving_throw_proficiencies = ['strength', 'dexterity']
class Rogue(Character):
class_name = 'Rogue'
hit_dice_faces = 8
saving_throw_proficiencies = ['dexterity', 'intelligence']
class Sorceror(Character):
class_name = 'Sorceror'
hit_dice_faces = 6
saving_throw_proficiencies = ['constitution', 'charisma']
class Warlock(Character):
class_name = 'Warlock'
hit_dice_faces = 8
saving_throw_proficiencies = ['wisdom', 'charisma']
class Wizard(Character):
class_name = 'Wizard'
hit_dice_faces = 6
saving_throw_proficiencies = ['intelligence', 'wisdom']