diff --git a/dungeonsheets/character.py b/dungeonsheets/character.py index 3ecb6c9..b641f02 100644 --- a/dungeonsheets/character.py +++ b/dungeonsheets/character.py @@ -392,7 +392,7 @@ class Character: @property def subclasses(self): - return list([c.subclass or "" for c in self.class_list]) + return [c.subclass for c in self.class_list if c.subclass is not None] @property def level(self): diff --git a/dungeonsheets/classes/classes.py b/dungeonsheets/classes/classes.py index 5348669..4d58556 100644 --- a/dungeonsheets/classes/classes.py +++ b/dungeonsheets/classes/classes.py @@ -133,6 +133,7 @@ class SubClass: """ name = "" + character_class = CharClass features_by_level = defaultdict(list) weapon_proficiencies = () _proficiencies_text = () diff --git a/dungeonsheets/features/races.py b/dungeonsheets/features/races.py index b0f8e9e..4e82d68 100644 --- a/dungeonsheets/features/races.py +++ b/dungeonsheets/features/races.py @@ -77,7 +77,7 @@ class DwarvenToughness(Feature): """ - name = "DwarvenToughness" + name = "Dwarven Toughness" source = "Race (Hill Dwarf)" needs_implementation = True diff --git a/dungeonsheets/forms/druid_shapes_template.tex b/dungeonsheets/forms/druid_shapes_template.tex index 38c1251..7986113 100644 --- a/dungeonsheets/forms/druid_shapes_template.tex +++ b/dungeonsheets/forms/druid_shapes_template.tex @@ -1,10 +1,9 @@ -\newpage \section*{Known Beasts} [% if use_dnd_decorations %] [% for shape in character.all_wild_shapes|sort(attribute='challenge_rating') %] [% if not character.can_assume_shape(shape) %] - \subsection*{Cannot assume form} + \subsection*{Cannot assume form} [% endif %] \begin{DndMonster}{[[ shape.name ]]} \DndMonsterType{[[ shape.description ]]} diff --git a/dungeonsheets/forms/features_template.tex b/dungeonsheets/forms/features_template.tex index abdc8b8..3923343 100644 --- a/dungeonsheets/forms/features_template.tex +++ b/dungeonsheets/forms/features_template.tex @@ -1,44 +1,23 @@ -\section*{Subclasses} - -[% for sc in character.subclasses if sc not in ['', None, 'None', 'none']%] + \section*{Features} +[% if use_dnd_decorations %] + [% for feat in character.features %] + \DndFeatHeader{[[ feat.name ]]}[Source: [[ feat.source ]]] - \subsection*{Subclass: [[ sc.name ]]} + [[ feat.__doc__|rst_to_latex ]] + [% endfor %] +[% else %] + [% for feat in character.features %] - [[ sc.__doc__ | rst_to_latex(top_heading_level=2) ]] + \subsection*{[[ feat.name ]]} -[% endfor %] - -\section*{Features} + \noindent + \textbf{Source:} [[ feat.source ]] \\ -[% for feat in character.features %] + [% if feat.needs_implementation %] % + \textbf{**Not included in stats on Character Sheet} % + [% endif %] % + + [[ feat.__doc__|rst_to_latex ]] - \subsection*{[[ feat.name ]]} - - \noindent - \textbf{Source:} [[ feat.source ]] \\ - - [% if feat.needs_implementation %] % - \textbf{**Not included in stats on Character Sheet} % - [% endif %] % - - [[ feat.__doc__|rst_to_latex ]] - -[% endfor %] - -\section*{Magic Items} - -[% for mitem in character.magic_items %] - - \subsection*{[[ mitem.name ]]} - - \noindent - \textbf{Requires Attunement:} [[ mitem.requires_attunement ]] \\ - \textbf{Rarity:} [[ mitem.rarity ]] \\ - - [% if mitem.needs_implementation %] % - \textbf{**Not included in stats on Character Sheet} % - [% endif %] % - - [[ mitem.__doc__|rst_to_latex ]] - - [% endfor %] \ No newline at end of file + [% endfor %] +[% endif %] \ No newline at end of file diff --git a/dungeonsheets/forms/magic_items_template.tex b/dungeonsheets/forms/magic_items_template.tex new file mode 100644 index 0000000..501be38 --- /dev/null +++ b/dungeonsheets/forms/magic_items_template.tex @@ -0,0 +1,28 @@ +\section*{Magic Items} + +[% if use_dnd_decorations %] + [% for mitem in character.magic_items %] + \DndItemHeader{[[ mitem.name ]]}{[% if mitem.item_type %][[ mitem.item_type ]], [[ mitem.rarity.lower() ]][% else %][[ mitem.rarity ]] item[% endif %][% if mitem.requires_attunement %] (requires attunement)[% endif %]} + [% if mitem.needs_implementation %] % + \textbf{**Not included in stats on Character Sheet} % + [% endif %] % + + [[ mitem.__doc__|rst_to_latex ]] + [% endfor %] +[% else %] + [% for mitem in character.magic_items %] + + \subsection*{[[ mitem.name ]]} + + \noindent + \textbf{Requires Attunement:} [[ mitem.requires_attunement ]] \\ + \textbf{Rarity:} [[ mitem.rarity ]] \\ + + [% if mitem.needs_implementation %] % + \textbf{**Not included in stats on Character Sheet} % + [% endif %] % + + [[ mitem.__doc__|rst_to_latex ]] + + [% endfor %] +[% endif %] \ No newline at end of file diff --git a/dungeonsheets/forms/preamble.tex b/dungeonsheets/forms/preamble.tex index 2add68d..f2f543c 100644 --- a/dungeonsheets/forms/preamble.tex +++ b/dungeonsheets/forms/preamble.tex @@ -1,4 +1,4 @@ -\documentclass[10pt,twocolumn,lettersize]{article} +\documentclass[10pt,twocolumn,lettersize]{book} % For parsed docstrings \usepackage[T1]{fontenc} @@ -50,4 +50,5 @@ } [% endraw %] -\begin{document} \ No newline at end of file +\begin{document} +\chapter*{Features, Magical Items and Spells} \ No newline at end of file diff --git a/dungeonsheets/forms/subclasses_template.tex b/dungeonsheets/forms/subclasses_template.tex new file mode 100644 index 0000000..7fbf0ee --- /dev/null +++ b/dungeonsheets/forms/subclasses_template.tex @@ -0,0 +1,17 @@ +\section*{Subclasses} +[% if use_dnd_decorations %] + [% for sc in character.subclasses if sc not in ['', None, 'None', 'none']%] + \DndFeatHeader{[[ sc.name ]]} + + [[ sc.__doc__ | rst_to_latex(top_heading_level=2) ]] + + [% endfor %] +[% else %] + [% for sc in character.subclasses if sc not in ['', None, 'None', 'none']%] + + \subsection*{[[ sc.name ]]} + + [[ sc.__doc__ | rst_to_latex(top_heading_level=2) ]] + + [% endfor %] +[% endif %] \ No newline at end of file diff --git a/dungeonsheets/latex.py b/dungeonsheets/latex.py index b221cb4..b277dd3 100644 --- a/dungeonsheets/latex.py +++ b/dungeonsheets/latex.py @@ -65,7 +65,7 @@ def create_latex_pdf( "-interaction=nonstopmode", tex_file, ] - passes = 2 if use_dnd_decorations else 1 + passes = 3 if use_dnd_decorations else 1 try: for i in range(passes): result = subprocess.run( diff --git a/dungeonsheets/magic_items.py b/dungeonsheets/magic_items.py index 5d1280b..dea46a1 100644 --- a/dungeonsheets/magic_items.py +++ b/dungeonsheets/magic_items.py @@ -9,6 +9,7 @@ class MagicItem: requires_attunement = False needs_implementation = False rarity = "" + item_type = "" def __init__(self, owner=None): self.owner = owner @@ -42,6 +43,7 @@ class RingOfProtection(MagicItem): ac_bonus = 1 requires_attunement = True rarity = "Rare" + item_type = "Ring" class DecanterOfEndlessWater(MagicItem): @@ -70,6 +72,7 @@ class DecanterOfEndlessWater(MagicItem): name = "Decanter of Endless Water" rarity = "Uncommon" + item_type = "Wondrous item" class ToothOfAnimalFriendship(MagicItem): diff --git a/dungeonsheets/make_sheets.py b/dungeonsheets/make_sheets.py index e4c815b..46bc989 100755 --- a/dungeonsheets/make_sheets.py +++ b/dungeonsheets/make_sheets.py @@ -134,22 +134,26 @@ jinja_env.filters["mod_str"] = mod_str PDFTK_CMD = "pdftk" -def create_druid_shapes_tex( +def create_subclasses_tex( character: Character, use_dnd_decorations: bool = False, ) -> str: - template = jinja_env.get_template("druid_shapes_template.tex") + template = jinja_env.get_template("subclasses_template.tex") return template.render(character=character, use_dnd_decorations=use_dnd_decorations) - - -def create_infusions_tex( +def create_features_tex( character: Character, use_dnd_decorations: bool = False, ) -> str: - template = jinja_env.get_template("infusions_template.tex") + template = jinja_env.get_template("features_template.tex") return template.render(character=character, use_dnd_decorations=use_dnd_decorations) +def create_magic_items_tex( + character: Character, + use_dnd_decorations: bool = False, +) -> str: + template = jinja_env.get_template("magic_items_template.tex") + return template.render(character=character, use_dnd_decorations=use_dnd_decorations) def create_spellbook_tex( character: Character, @@ -158,12 +162,18 @@ def create_spellbook_tex( template = jinja_env.get_template("spellbook_template.tex") return template.render(character=character, ordinals=ORDINALS, use_dnd_decorations=use_dnd_decorations) - -def create_features_tex( +def create_infusions_tex( character: Character, use_dnd_decorations: bool = False, ) -> str: - template = jinja_env.get_template("features_template.tex") + template = jinja_env.get_template("infusions_template.tex") + return template.render(character=character, use_dnd_decorations=use_dnd_decorations) + +def create_druid_shapes_tex( + character: Character, + use_dnd_decorations: bool = False, +) -> str: + template = jinja_env.get_template("druid_shapes_template.tex") return template.render(character=character, use_dnd_decorations=use_dnd_decorations) @@ -217,23 +227,35 @@ def make_sheet( sheets.append(spell_base + ".pdf") # end of PDF gen + features_base = "{:s}_features".format(os.path.splitext(character_file)[0]) + # Create a list of subcasses + if character.subclasses: + tex.append(create_subclasses_tex(character, use_dnd_decorations=fancy_decorations)) + + # Create a list of features + if character.features: + tex.append(create_features_tex(character, use_dnd_decorations=fancy_decorations)) + + if character.magic_items: + tex.append(create_magic_items_tex(character, use_dnd_decorations=fancy_decorations)) + + # Create a list of spells if character.is_spellcaster: tex.append(create_spellbook_tex(character, use_dnd_decorations=fancy_decorations)) # Create a list of Artificer infusions - infusions = getattr(character, "infusions", []) - if len(infusions) > 0: + if getattr(character, "infusions", []): tex.append(create_infusions_tex(character, use_dnd_decorations=fancy_decorations)) + # Create a list of Druid wild_shapes - wild_shapes = getattr(character, "wild_shapes", []) - if len(wild_shapes) > 0: + if getattr(character, "wild_shapes", []): tex.append(create_druid_shapes_tex(character, use_dnd_decorations=fancy_decorations)) tex.append(jinja_env.get_template("postamble.tex").render(use_dnd_decorations=fancy_decorations)) - latex.create_latex_pdf("".join(tex), "name", keep_temp_files=debug) + latex.create_latex_pdf("".join(tex), features_base, keep_temp_files=debug) if len(tex) > 2: - sheets.append("name.pdf") + sheets.append(features_base + ".pdf") # Typeset combined LaTeX file """