diff --git a/dungeonsheets/background.py b/dungeonsheets/background.py index c0be244..3786658 100644 --- a/dungeonsheets/background.py +++ b/dungeonsheets/background.py @@ -6,6 +6,8 @@ class Background(): skill_proficiencies = () weapon_proficiencies = () proficiencies_text = () + skill_choices = () + num_skill_choices = 0 features = () languages = () @@ -35,7 +37,7 @@ class Spy(Criminal): class Entertainer(Background): name = "Entertainer" - skill_proficiencies = ('acrobatic', 'performance') + skill_proficiencies = ('acrobatics', 'performance') class Gladiator(Entertainer): @@ -106,10 +108,20 @@ class Urchin(Background): class UrbanBountyHunter(Background): name = 'Urban Bounty Hunter' - skill_proficiencies = ('[choose one]', '[choose one]') + skill_proficiencies = () + skill_choices = ('Deception', 'Insight', 'Persuasion', 'Stealth') + num_skill_choices = 2 class FarTraveler(Background): name = 'Far Traveler' skill_proficiencies = ('insight', 'perception') languages = ('[choose one]',) + + +available_backgrounds = [Acolyte, Charlatan, Criminal, Spy, Entertainer, + Gladiator, FolkHero, GuildArtisan, GuildMerchant, + Hermit, Noble, Knight, Outlander, Sage, Sailor, + Pirate, Soldier, Urchin, UrbanBountyHunter, + FarTraveler] + diff --git a/dungeonsheets/character.py b/dungeonsheets/character.py index 8c3b85a..f43608e 100644 --- a/dungeonsheets/character.py +++ b/dungeonsheets/character.py @@ -74,24 +74,24 @@ class Character(): proficiencies_extra = tuple() languages = "" # 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') - persuasion = Skill(ability='charisma') - religion = Skill(ability='intelligence') - sleight_of_hand = Skill(ability='dexterity') - stealth = Skill(ability='dexterity') - survival = Skill(ability='wisdom') + acrobatics = Skill(ability='dexterity', name='acrobatics') + animal_handling = Skill(ability='wisdom', name='animal handling') + arcana = Skill(ability='intelligence', name='arcana') + athletics = Skill(ability='strength', name='athletics') + deception = Skill(ability='charisma', name='deception') + history = Skill(ability='intelligence', name='history') + insight = Skill(ability='wisdom', name='insight') + intimidation = Skill(ability='charisma', name='intimidation') + investigation = Skill(ability='intelligence', name='investigation') + medicine = Skill(ability='wisdom', name='medicine') + nature = Skill(ability='intelligence', name='nature') + perception = Skill(ability='wisdom', name='perception') + performance = Skill(ability='charisma', name='performance') + persuasion = Skill(ability='charisma', name='persuasion') + religion = Skill(ability='intelligence', name='religion') + sleight_of_hand = Skill(ability='dexterity', name='sleight of hand') + stealth = Skill(ability='dexterity', name='stealth') + survival = Skill(ability='wisdom', name='survival') # Characteristics attacks_and_spellcasting = "" personality_traits = "" @@ -255,11 +255,13 @@ class Character(): self.other_weapon_proficiencies = tuple([findattr(weapons, w) for w in val]) elif attr == 'race': - MyRace = findattr(race, val) - self.race = MyRace() + if val is not None: + MyRace = findattr(race, val) + self.race = MyRace() elif attr == 'background': - MyBackground = findattr(background, val) - self.background = MyBackground() + if val is not None: + MyBackground = findattr(background, val) + self.background = MyBackground() elif attr == 'armor': self.wear_armor(val) elif attr == 'shield': @@ -397,7 +399,7 @@ class Character(): directly. """ - if new_armor not in ('', None): + if new_armor not in ('', 'None', None): if isinstance(new_armor, armor.Armor): new_armor = new_armor else: diff --git a/dungeonsheets/classes/classes.py b/dungeonsheets/classes/classes.py index f08cdb9..40b3466 100644 --- a/dungeonsheets/classes/classes.py +++ b/dungeonsheets/classes/classes.py @@ -18,11 +18,15 @@ class CharClass(): spellcasting_ability = None spell_slots_by_level = None subclass = None + subclasses_available = () features_by_level = defaultdict(list) def __init__(self, level, subclass=None, **params): self.class_level = level - self.subclass = subclass + if subclass in [None, '', 'None']: + self.subclass = None + else: + self.subclass = subclass for k, v in params.items(): setattr(self, k, v) diff --git a/dungeonsheets/classes/monk.py b/dungeonsheets/classes/monk.py index 6bbd587..a0e2c2e 100644 --- a/dungeonsheets/classes/monk.py +++ b/dungeonsheets/classes/monk.py @@ -15,7 +15,7 @@ class Monk(CharClass): weapon_proficiencies = (weapons.Shortsword, weapons.Unarmed) + weapons.simple_weapons class_skill_choices = ('Acrobatics', 'Athletics', 'History', 'Insight', 'Religion', 'Stealth') - + subclasses_available = ('SunSoul', 'OpenHand') features_by_level = defaultdict(list) martial_arts = features.MartialArts() features_by_level[1] = [features.UnarmoredDefense(), diff --git a/dungeonsheets/create_character.py b/dungeonsheets/create_character.py index 9704558..523f60f 100755 --- a/dungeonsheets/create_character.py +++ b/dungeonsheets/create_character.py @@ -58,15 +58,7 @@ races = { } -backgrounds = (background.Acolyte, background.Charlatan, - background.Criminal, background.Spy, - background.Entertainer, background.Gladiator, - background.FolkHero, background.GuildArtisan, - background.GuildMerchant, background.Hermit, - background.Noble, background.Knight, - background.Outlander, background.Sage, - background.Sailor, background.Pirate, - background.Soldier, background.Urchin) +backgrounds = background.available_backgrounds backgrounds = {bg.name: bg for bg in backgrounds} @@ -75,119 +67,240 @@ class App(npyscreen.NPSAppManaged): character = None def save_character(self): - # Create the template context - context = dict( - char=self.character, - dungeonsheets_version=read_version(), - ) - # Render the template - src_path = os.path.dirname(__file__) - src_filename = 'character_template.txt' - text = jinja2.Environment( - loader=jinja2.FileSystemLoader(src_path or './') - ).get_template(src_filename).render(context) # Save the file filename = self.getForm("SAVE").filename.value - with open(filename, mode='w') as f: - f.write(text) + self.character.save(filename) # Create the PDF character sheet if self.getForm('SAVE').make_pdf.value: log.debug("Creating PDF") subprocess.call(['makesheets', filename]) - - @property - def character_class(self, *args, **kwargs): - return self.character_class - - @character_class.setter - def character_class(self, NewClass): - log.debug("Replacing character") - basic_info = self.getForm('MAIN') - self.character = NewClass( - name=basic_info.name.value, - player_name=basic_info.player_name.value, - level=int(basic_info.level.value), - strength=-1, dexterity=-1, constitution=-1, - intelligence=-1, wisdom=-1, charisma=-1) + + def add_class(self, NewClass): + log.debug("Adding Class: {:s}".format(NewClass.class_name)) + # basic_info = self.getForm('MAIN') + # self.character = NewClass( + # name=basic_info.name.value, + # player_name=basic_info.player_name.value, + # level=int(basic_info.level.value), + # strength=-1, dexterity=-1, constitution=-1, + # intelligence=-1, wisdom=-1, charisma=-1) + self.character.class_list.append(NewClass) self.update_max_hp() # Reset form widgets log.debug("Resetting forms") self.getForm('ABILITIES').reset() + + # @property + # def character_class(self, *args, **kwargs): + # return self.character_class + + # @character_class.setter + # def character_class(self, NewClass): + # log.debug("Adding Class: {:s}".format(NewClass.class_name)) + # # basic_info = self.getForm('MAIN') + # # self.character = NewClass( + # # name=basic_info.name.value, + # # player_name=basic_info.player_name.value, + # # level=int(basic_info.level.value), + # # strength=-1, dexterity=-1, constitution=-1, + # # intelligence=-1, wisdom=-1, charisma=-1) + # self.character.class_list.append(NewClass) + # self.update_max_hp() + # # Reset form widgets + # log.debug("Resetting forms") + # self.getForm('ABILITIES').reset() def update_max_hp(self): # Update max HP based on the class max_hp_fld = self.getForm('ABILITIES').max_hp if max_hp_fld.value == '': # Calculate the new value - hit_dice = dice.read_dice_str(self.character.hit_dice) + hit_dice = [dice.read_dice_str(d) + for d in self.character.hit_dice.split(' + ')] const = self.character.constitution.modifier - max_hp = hit_dice.faces + const - for d in range(hit_dice.num - 1): - max_hp += math.ceil(hit_dice.faces/2) + const + # Assume first hd given is from primary class + max_hp = math.floor(hit_dice[0].faces/2) + const + for hd in hit_dice: + for d in range(hd.num - 1): + max_hp += math.ceil(hd.faces/2) + const log.debug("Updating max hp: %d", max_hp) max_hp_fld.value = str(max_hp) def onStart(self): self.character = character.Character() self.addForm("MAIN", BasicInfoForm, name="Basic Info:") - self.addForm("CLASS", CharacterClassForm, name="Select your character's class:") self.addForm("RACE", RaceForm, name="Select your character's race:") + self.addForm("CLASS", CharacterClassForm, name="Select your character's primary class:") + self.addForm("SUBCLASS", SubclassForm, name="Select your subclass:") + self.addForm("BACKGROUND", BackgroundForm, name="Choose background:") self.addForm("ALIGNMENT", AlignmentForm, name="Select your character's alignment:") self.addForm("ABILITIES", AbilityScoreForm, name="Choose ability scores:") - self.addForm("BACKGROUND", BackgroundForm, name="Choose background:") self.addForm("SKILLS", SkillForm, name="Choose skill proficiencies") self.addForm("SAVE", SaveForm, name="Save character:") -class SkillForm(npyscreen.ActionForm): - def while_editing(self): - # Update the static skills for race and background - bg_skills = self.parentApp.character.background.skill_proficiencies - self.bg_skills.value = str(bg_skills)[1:-1].replace("'", "") - race_skills = self.parentApp.character.race.skill_proficiencies - self.race_skills.value = str(race_skills)[1:-1].replace("'", "") - # Now set the available discretionary choices - choices = self.parentApp.character.class_skill_choices - static_skills = bg_skills + race_skills - choices = (c for c in choices if c.lower() not in static_skills) - self.skill_proficiencies.set_values(tuple(choices)) - self.update_remaining() - - def update_remaining(self, widget=None): - num_choices = self.parentApp.character.num_skill_choices - num_selected = len(self.skill_proficiencies.value) - remaining = num_choices - num_selected - log.debug(f'Remaining: {remaining}') - self.remaining.value = str(remaining) - self.display() - +class BasicInfoForm(npyscreen.ActionForm): def create(self): - self.bg_skills = self.add( - npyscreen.TitleText, name="Background:", - value="", editable=False) - self.race_skills = self.add( - npyscreen.TitleText, name="Racial:", - value="", editable=False) - self.remaining = self.add( - npyscreen.TitleText, name="Remaining:", - value=0, editable=False) - self.skill_proficiencies = self.add( - npyscreen.TitleMultiSelect, name="Skill Proficiencies:", - values=self.parentApp.character.class_skill_choices, - value_changed_callback=self.update_remaining) + self.name = self.add( + npyscreen.TitleText, name="Character Name:", use_two_lines=False) + self.player_name = self.add( + npyscreen.TitleText, name="Player Name:", use_two_lines=False) def on_ok(self): - new_skills = self.skill_proficiencies.get_selected_objects() - if new_skills is not None: - new_skills = tuple(s.lower() for s in new_skills) + # Update the default filename + name = self.name.value + if name == '': + filename = 'new_character.py' else: - new_skills = () - bg_skills = tuple(self.parentApp.character.background.skill_proficiencies) - race_skills = tuple(self.parentApp.character.race.skill_proficiencies) - all_skills = new_skills + bg_skills + race_skills - self.parentApp.character.skill_proficiencies = all_skills - log.debug(f"Skill proficiencies: {all_skills}") - self.parentApp.setNextForm('SAVE') + filename = f'{name.split(" ")[0].lower()}.py' + save_form = self.parentApp.getForm('SAVE') + save_form.filename.value = filename + # Move to the next form + self.parentApp.setNextForm('RACE') + + def on_cancel(self): + raise KeyboardInterrupt + + +class RaceForm(npyscreen.ActionForm): + def create(self): + self.race = self.add( + npyscreen.TitleMultiLine, name="Race:", values=tuple(races.keys())) + + def on_ok(self): + if self.race.value is not None: + selected_race = self.race.values[self.race.value] + SelectedRace = races[selected_race] + log.debug('Selected character race: %s', SelectedRace.name) + self.parentApp.character.race = SelectedRace() + self.parentApp.setNextForm('CLASS') + + def on_cancel(self): + self.parentApp.setNextForm('MAIN') + + +class CharacterClassForm(npyscreen.ActionForm): + char_options = list(char_classes.keys()) + + def create(self): + self.level = self.add( + npyscreen.TitleText, name='Level:', value="1", use_two_lines=False) + self.subclass = self.add(npyscreen.Checkbox, name="Choose a Subclass?", value=False) + self.multiclass = self.add(npyscreen.Checkbox, name="Multiclass?", value=False) + self.character_class = self.add( + npyscreen.TitleMultiLine, name="Class:", values=tuple(self.char_options)) + + def setup_multiclass(self): + self.character_class.values = self.char_options + self.name = "Select your character's class #{:d}".format(1 + self.parentApp.character.num_classes) + self.multiclass.name = "Add another class?" + self.level.value = '1' + self.subclass.value = False + self.multiclass.value = False + self.character_class.value = None + + def on_ok(self): + if self.character_class.value is not None: + # make sure this option can't be selected again + selected_class = self.character_class.values[self.character_class.value] + self.char_options.remove(selected_class) + selected_class = char_classes[selected_class] + log.debug('Selected character class %s', selected_class.class_name) + if self.subclass.value: + sc = self.parentApp.getForm('SUBCLASS') + sc.when_done = 'CLASS' if self.multiclass.value else 'BACKGROUND' + if self.multiclass: + self.setup_multiclass() + sc.prepare_for_class(selected_class, int(self.level.value)) + self.parentApp.setNextForm('SUBCLASS') + else: + self.parentApp.add_class(selected_class(level=int(self.level.value), + subclass=None)) + if self.multiclass.value: + self.setup_multiclass() + self.parentApp.setNextForm('CLASS') + else: + self.parentApp.setNextForm('BACKGROUND') + + def on_cancel(self): + if self.parentApp.character.num_classes > 1: + self.parentApp.setNextForm('BACKGROUND') + self.parentApp.setNextForm('RACE') + + +class SubclassForm(npyscreen.ActionForm): + subclass_options = ('None',) + parent_class = None + level = 1 + when_done = 'BACKGROUND' + name_formatter = "Select your {:s} subclass:" + + def create(self): + self.subclass = self.add( + npyscreen.TitleMultiLine, name="Subclass:", + values=tuple(self.subclass_options)) + + def prepare_for_class(self, parent_class, level): + self.subclass_options = parent_class.subclasses_available or ('None',) + self.parent_class = parent_class + self.level = level + self.name = self.name_formatter.format(parent_class.class_name) + self._clear_all_widgets() + self.create() + + def on_ok(self): + if self.subclass.value in [None, '', 'None']: + newclass = self.parent_class(level=self.level, + subclass=None) + else: + newclass = self.parent_class(level=self.level, + subclass=self.subclass.value) + self.parentApp.add_class(newclass) + self.parentApp.setNextForm(self.when_done) + + def on_cancel(self): + self.parentApp.setNextForm('CLASS') + + +class BackgroundForm(npyscreen.ActionForm): + + def create(self): + self.background = self.add( + npyscreen.TitleMultiLine, + name="Background:", values=tuple(backgrounds.keys())) + + def on_ok(self): + if self.background.value is not None: + selected_bg = self.background.values[self.background.value] + Background = backgrounds[selected_bg] + self.parentApp.character.background = Background() + # Update the languages based on background and race + race_languages = self.parentApp.character.race.languages + languages = Background.languages + race_languages + self.parentApp.character.languages = ', '.join(languages) + log.debug("Selected character background: %s", Background.name) + self.parentApp.setNextForm('ALIGNMENT') + + def on_cancel(self): + self.parentApp.setNextForm('CLASS') + + +class AlignmentForm(npyscreen.ActionForm): + """Choose your character's alignment.""" + alignments = ('Lawful good', 'Neutral good', 'Chaotic good', + 'Lawful neutral', 'True neutral', 'Chaotic neutral', + 'Lawful evil', 'Neutral evil', 'Chaotic evil', ) + + def create(self): + self.alignment = self.add( + npyscreen.TitleMultiLine, name="Alignment:", values=self.alignments) + + def on_ok(self): + if self.alignment.value is not None: + selected_alignment = self.alignment.values[self.alignment.value] + log.debug('Selected character alignment %s', selected_alignment) + self.parentApp.character.alignment = selected_alignment + self.parentApp.setNextForm('ABILITIES') def on_cancel(self): self.parentApp.setNextForm('BACKGROUND') @@ -255,116 +368,70 @@ class AbilityScoreForm(npyscreen.ActionForm): self.max_hp = self.add(npyscreen.TitleText, name="Max HP:") def on_ok(self): - self.parentApp.setNextForm('BACKGROUND') + self.parentApp.setNextForm('SKILLS') def on_cancel(self): self.parentApp.setNextForm('ALIGNMENT') -class CharacterClassForm(npyscreen.ActionForm): +class SkillForm(npyscreen.ActionForm): + def while_editing(self): + # Update the static skills for race and background + bg_skills = self.parentApp.character.background.skill_proficiencies + self.bg_skills.value = str(bg_skills)[1:-1].replace("'", "") + race_skills = self.parentApp.character.race.skill_proficiencies + self.race_skills.value = str(race_skills)[1:-1].replace("'", "") + # Now set the available discretionary choices + choices = (self.parentApp.character.primary_class.class_skill_choices + + self.parentApp.character.race.skill_choices + + self.parentApp.character.background.skill_choices) + static_skills = bg_skills + race_skills + choices = set([c for c in choices if c.lower() not in static_skills]) + self.skill_proficiencies.set_values(tuple(choices)) + self.update_remaining() + + def update_remaining(self, widget=None): + num_choices = (self.parentApp.character.num_skill_choices + + self.parentApp.character.race.num_skill_choices + + self.parentApp.character.background.num_skill_choices) + num_selected = len(self.skill_proficiencies.value) + remaining = num_choices - num_selected + log.debug(f'Remaining: {remaining}') + self.remaining.value = str(remaining) + self.display() + def create(self): - self.character_class = self.add( - npyscreen.TitleMultiLine, name="Class:", values=tuple(char_classes.keys())) + self.bg_skills = self.add( + npyscreen.TitleText, name="Background:", + value="", editable=False) + self.race_skills = self.add( + npyscreen.TitleText, name="Racial:", + value="", editable=False) + self.remaining = self.add( + npyscreen.TitleText, name="Remaining:", + value=0, editable=False) + self.skill_proficiencies = self.add( + npyscreen.TitleMultiSelect, name="Skill Proficiencies:", + values=self.parentApp.character.class_skill_choices, + value_changed_callback=self.update_remaining) def on_ok(self): - if self.character_class.value is not None: - selected_class = self.character_class.values[self.character_class.value] - selected_class = char_classes[selected_class] - log.debug('Selected character class %s', selected_class.class_name) - self.parentApp.character_class = selected_class - self.parentApp.setNextForm('RACE') - - def on_cancel(self): - self.parentApp.setNextForm('MAIN') - - -class BackgroundForm(npyscreen.ActionForm): - - def create(self): - self.background = self.add( - npyscreen.TitleMultiLine, - name="Background:", values=tuple(backgrounds.keys())) - - def on_ok(self): - if self.background.value is not None: - selected_bg = self.background.values[self.background.value] - Background = backgrounds[selected_bg] - self.parentApp.character.background = Background() - # Update the languages based on background and race - race_languages = self.parentApp.character.race.languages - languages = Background.languages + race_languages - self.parentApp.character.languages = ', '.join(languages) - log.debug("Selected character background: %s", Background.name) - self.parentApp.setNextForm('SKILLS') + new_skills = self.skill_proficiencies.get_selected_objects() + if new_skills is not None: + new_skills = tuple(s.lower() for s in new_skills) + else: + new_skills = () + bg_skills = tuple(self.parentApp.character.background.skill_proficiencies) + race_skills = tuple(self.parentApp.character.race.skill_proficiencies) + all_skills = new_skills + bg_skills + race_skills + self.parentApp.character.skill_proficiencies = all_skills + log.debug(f"Skill proficiencies: {all_skills}") + self.parentApp.setNextForm('SAVE') def on_cancel(self): self.parentApp.setNextForm('ABILITIES') -class RaceForm(npyscreen.ActionForm): - def create(self): - self.race = self.add( - npyscreen.TitleMultiLine, name="Race:", values=tuple(races.keys())) - - def on_ok(self): - if self.race.value is not None: - selected_race = self.race.values[self.race.value] - SelectedRace = races[selected_race] - log.debug('Selected character race: %s', SelectedRace.name) - self.parentApp.character.race = SelectedRace() - self.parentApp.setNextForm('ALIGNMENT') - - def on_cancel(self): - self.parentApp.setNextForm('CLASS') - - - -class AlignmentForm(npyscreen.ActionForm): - """Choose your character's alignment.""" - alignments = ('Lawful good', 'Neutral good', 'Chaotic good', - 'Lawful neutral', 'True neutral', 'Chaotic neutral', - 'Lawful evil', 'Neutral evil', 'Chaotic evil', ) - - def create(self): - self.alignment = self.add( - npyscreen.TitleMultiLine, name="Alignment:", values=self.alignments) - - def on_ok(self): - if self.alignment.value is not None: - selected_alignment = self.alignment.values[self.alignment.value] - log.debug('Selected character alignment %s', selected_alignment) - self.parentApp.character.alignment = selected_alignment - self.parentApp.setNextForm('ABILITIES') - - def on_cancel(self): - self.parentApp.setNextForm('RACE') - - -class BasicInfoForm(npyscreen.ActionForm): - def create(self): - self.name = self.add( - npyscreen.TitleText, name="Character Name:", use_two_lines=False) - self.player_name = self.add( - npyscreen.TitleText, name="Player Name:", use_two_lines=False) - self.level = self.add( - npyscreen.TitleText, name='Level:', value="1") - - def on_ok(self): - # Update the default filename - name = self.name.value - if name == '': - filename = 'new_character.py' - else: - filename = f'{name.split(" ")[0].lower()}.py' - save_form = self.parentApp.getForm('SAVE') - save_form.filename.value = filename - # Move to the next form - self.parentApp.setNextForm('CLASS') - - def on_cancel(self): - raise KeyboardInterrupt - - class SaveForm(npyscreen.ActionForm): def create(self): self.filename = self.add( diff --git a/dungeonsheets/make_sheets.py b/dungeonsheets/make_sheets.py index 3dcfc54..1a8e624 100644 --- a/dungeonsheets/make_sheets.py +++ b/dungeonsheets/make_sheets.py @@ -33,12 +33,13 @@ def rst_to_latex(rst): tex = "" else: tex = rst + for c in ['\\']: + tex = tex.replace(c, '\\' + c) tex = bold_re.sub(r'\\textbf{\1}', tex) tex = it_re.sub(r'\\textit{\1}', tex) tex = dice_re.sub(r'\\texttt{\1}', tex) tex = tt_re.sub(r'\\texttt{\1}', tex) - for c in ['\\', '#', '$', '%', '&', '~', '_', '^', - '{', '}', '(', ')', '[', ']']: + for c in ['#', '$', '%', '&', '~', '_', '^']: tex = tex.replace(c, '\\' + c) return tex diff --git a/dungeonsheets/race.py b/dungeonsheets/race.py index c1a352f..91da60f 100644 --- a/dungeonsheets/race.py +++ b/dungeonsheets/race.py @@ -17,6 +17,8 @@ class Race(): proficiencies_text = tuple() weapon_proficiences = tuple() skill_proficiencies = () + skill_choices = () + num_skill_choices = 0 features = tuple() strength_bonus = 0 dexterity_bonus = 0 diff --git a/dungeonsheets/stats.py b/dungeonsheets/stats.py index 52d1706..d957233 100644 --- a/dungeonsheets/stats.py +++ b/dungeonsheets/stats.py @@ -74,12 +74,13 @@ class Ability(): class Skill(): """An ability-based skill, such as athletics.""" - def __init__(self, ability): + def __init__(self, ability, name): self.ability_name = ability - - def __set_name__(self, character, name): self.skill_name = name - self.character = character + + # def __set_name__(self, character, name): + # self.skill_name = name + # self.character = character def __get__(self, character, owner): ability = getattr(character, self.ability_name)