diff --git a/VERSION b/VERSION index 7deb86f..d5cc44d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.1 \ No newline at end of file +0.7.2 \ No newline at end of file diff --git a/dungeonsheets/character.py b/dungeonsheets/character.py index 6d600bb..d6db77a 100644 --- a/dungeonsheets/character.py +++ b/dungeonsheets/character.py @@ -108,6 +108,7 @@ class Character(): spellcasting_ability = None spells = tuple() spells_prepared = tuple() + # MISC def __init__(self, **attrs): """Takes a bunch of attrs and passes them to ``set_attrs``""" @@ -120,14 +121,6 @@ class Character(): 'race': race, 'background': background}) self.set_attrs(**attrs) - for c in self.class_list: - if isinstance(c, classes.Druid): - ws = self.wild_shapes - c.wild_shapes = ws - c.circle = self.circle - self.all_wild_shapes = c.all_wild_shapes - self.wild_shapes = c.wild_shapes - self.can_assume_shape = c.can_assume_shape # instantiate any spells not listed properly for S in self.spells_prepared: if S not in [type(spl) for spl in self.spells]: @@ -233,6 +226,20 @@ class Character(): self.wear_armor(val) elif attr == 'shield': self.wield_shield(val) + elif attr == 'wild_shapes': + for c in self.class_list: + if isinstance(c, classes.Druid): + c.wild_shapes = val + self.all_wild_shapes = c.all_wild_shapes + self.wild_shapes = c.wild_shapes + self.can_assume_shape = c.can_assume_shape + break + elif attr == 'circle': + for c in self.class_list: + if isinstance(c, classes.Druid) and (c.circle == ''): + c.circle = val + self.circle = val + break elif (attr == 'spells') or (attr == 'spells_prepared'): # Create a list of actual spell objects _spells = [] diff --git a/dungeonsheets/classes.py b/dungeonsheets/classes.py index f56d863..e736536 100644 --- a/dungeonsheets/classes.py +++ b/dungeonsheets/classes.py @@ -145,7 +145,7 @@ class Cleric(CharClass): class Druid(CharClass): class_name = 'Druid' - circle = "" # Moon, land + circle = "" # moon, land _wild_shapes = () hit_dice_faces = 8 saving_throw_proficiencies = ('intelligence', 'wisdom') @@ -185,7 +185,18 @@ class Druid(CharClass): 19: (4, 4, 3, 3, 3, 3, 2, 1, 1, 1), 20: (4, 4, 3, 3, 3, 3, 2, 2, 1, 1), } - + + def __init__(self, level, subclass=None, **params): + if subclass is not None: + sc = str(subclass).lower() + if 'moon' in sc: + self.circle = 'moon' + params.pop('circle', '') + elif 'land' in sc: + self.circle = 'land' + params.pop('circle', '') + super().__init__(level, **params) + @property def all_wild_shapes(self): """Return all wild shapes, regardless of validity.""" diff --git a/dungeonsheets/make_sheets.py b/dungeonsheets/make_sheets.py index 64417f9..2ba6060 100644 --- a/dungeonsheets/make_sheets.py +++ b/dungeonsheets/make_sheets.py @@ -107,14 +107,21 @@ def create_latex_pdf(char, basename, template): raise exceptions.LatexError(f'Processing of {basename}.tex failed.') -def create_spells_pdf(char, spell_class, basename, flatten=False): - class_level = (spell_class.class_name + ' ' + str(spell_class.class_level)) +def create_spells_pdf(char, basename, flatten=False): + class_level = ' / '.join([c.class_name + ' ' + str(c.class_level) + for c in char.spellcasting_classes]) + abilities = ' / '.join([c.spellcasting_ability.upper()[:3] + for c in char.spellcasting_classes]) + DCs = ' / '.join([str(char.spell_save_dc(c)) + for c in char.spellcasting_classes]) + bonuses = ' / '.join([mod_str(char.spell_attack_bonus(c)) + for c in char.spellcasting_classes]) spell_level = lambda x : (x or '') fields = { 'Spellcasting Class 2': class_level, - 'SpellcastingAbility 2': spell_class.spellcasting_ability.upper()[:3], - 'SpellSaveDC 2': char.spell_save_dc(spell_class), - 'SpellAtkBonus 2': mod_str(char.spell_attack_bonus(spell_class)), + 'SpellcastingAbility 2': abilities, + 'SpellSaveDC 2': DCs, + 'SpellAtkBonus 2': bonuses, # Number of spell slots 'SlotsTotal 19': spell_level(char.spell_slots(1)), 'SlotsTotal 20': spell_level(char.spell_slots(2)), @@ -428,17 +435,12 @@ def make_sheet(character_file, char=None, flatten=False): char_pdf = create_character_pdf(char=char, basename=char_base, flatten=flatten) pages.append(char_pdf) - for spell_class in char.spellcasting_classes: - # Create spell sheet (one for each class) - # Even though each sheet will include same spells, - # this will list all modifiers - spell_base = '{:s}_{:s}_spells'.format( - os.path.splitext(character_file)[0], - spell_class.class_name) - create_spells_pdf(char=char, spell_class=spell_class, - basename=spell_base, flatten=flatten) - sheets.append(spell_base + '.pdf') if char.is_spellcaster: + # Create spell sheet + spell_base = '{:s}_spells'.format( + os.path.splitext(character_file)[0]) + create_spells_pdf(char=char, basename=spell_base, flatten=flatten) + sheets.append(spell_base + '.pdf') # Create spell book spellbook_base = os.path.splitext(character_file)[0] + '_spellbook' try: diff --git a/examples/druid.pdf b/examples/druid.pdf index 776422a..a0e5bb6 100644 Binary files a/examples/druid.pdf and b/examples/druid.pdf differ diff --git a/examples/multiclass.pdf b/examples/multiclass.pdf index 0090d16..b7cb5a3 100644 Binary files a/examples/multiclass.pdf and b/examples/multiclass.pdf differ diff --git a/examples/multiclass_2.pdf b/examples/multiclass_2.pdf index a0ee2bf..af43935 100644 Binary files a/examples/multiclass_2.pdf and b/examples/multiclass_2.pdf differ diff --git a/examples/multiclass_2.py b/examples/multiclass_2.py index 94fa274..3d72797 100644 --- a/examples/multiclass_2.py +++ b/examples/multiclass_2.py @@ -12,7 +12,7 @@ name = 'Inara Serradon' # multiclass example classes_levels = ['wizard 3', 'druid 2'] # 4th level total subclasses = ['Necromancer', 'moon'] -circle = 'moon' +circle = 'land' player_name = 'Mark' background = "Acolyte" @@ -56,18 +56,18 @@ equipment = ( wild_shapes = ["wolf", "crocodile", "giant eagle", 'ape', 'ankylosaurus'] -druid_spells_prepared = ('shillelagh', 'poison spray', 'druidcraft', - 'speak with animals', 'entangle', 'cure wounds', - 'create or destroy water') +__druid_spells_prepared = ('shillelagh', 'poison spray', 'druidcraft', + 'speak with animals', 'entangle', 'cure wounds', + 'create or destroy water') # List of known spells spells = ('blindness deafness', 'burning hands', 'detect magic', 'false life', 'mage armor', 'mage hand', 'magic missile', 'prestidigitation', 'ray of frost', 'ray of sickness', 'shield', - 'shocking grasp', 'sleep',) + druid_spells_prepared + 'shocking grasp', 'sleep',) + __druid_spells_prepared # Which spells have been prepared (not including cantrips) spells_prepared = ('blindness deafness', 'false life', 'mage armor', - 'ray of sickness', 'shield', 'sleep',) + druid_spells_prepared + 'ray of sickness', 'shield', 'sleep',) + __druid_spells_prepared # Backstory personality_traits = """I use polysyllabic words that convey the impression of diff --git a/examples/rogue.pdf b/examples/rogue.pdf index 9a0a3a7..4ae5269 100644 Binary files a/examples/rogue.pdf and b/examples/rogue.pdf differ diff --git a/examples/warlock.pdf b/examples/warlock.pdf index 9f6e339..0f0e6f5 100644 Binary files a/examples/warlock.pdf and b/examples/warlock.pdf differ diff --git a/examples/wizard.pdf b/examples/wizard.pdf index 8b76d51..ba0538c 100644 Binary files a/examples/wizard.pdf and b/examples/wizard.pdf differ