mirror of
https://github.com/Threnklyn/dungeon-sheets.git
synced 2026-05-18 20:23:27 +02:00
Merge pull request #67 from rkubosz/artificer
Added the Artificer character class
This commit is contained in:
@@ -6,11 +6,13 @@ import os
|
||||
import re
|
||||
import subprocess
|
||||
import warnings
|
||||
import math
|
||||
|
||||
import jinja2
|
||||
|
||||
from dungeonsheets import (armor, background, classes, exceptions, features,
|
||||
magic_items, monsters, race, spells, weapons)
|
||||
infusions, magic_items, monsters, race, spells,
|
||||
weapons)
|
||||
from dungeonsheets.armor import Armor, NoArmor, NoShield, Shield
|
||||
from dungeonsheets.dice import read_dice_str
|
||||
from dungeonsheets.stats import (Ability, ArmorClass, Initiative, Skill, Speed,
|
||||
@@ -27,7 +29,7 @@ __version__ = read('../VERSION').strip()
|
||||
|
||||
dice_re = re.compile('(\d+)d(\d+)')
|
||||
|
||||
__all__ = ('Barbarian', 'Bard', 'Cleric', 'Druid', 'Fighter', 'Monk',
|
||||
__all__ = ('Artificer', 'Barbarian', 'Bard', 'Cleric', 'Druid', 'Fighter', 'Monk',
|
||||
'Paladin', 'Ranger', 'Rogue', 'Sorcerer', 'Warlock', 'Wizard', )
|
||||
|
||||
multiclass_spellslots_by_level = {
|
||||
@@ -128,6 +130,7 @@ class Character():
|
||||
spellcasting_ability = None
|
||||
_spells = list()
|
||||
_spells_prepared = list()
|
||||
infusions = list()
|
||||
# Features IN MAJOR DEVELOPMENT
|
||||
custom_features = list()
|
||||
feature_choices = list()
|
||||
@@ -171,6 +174,7 @@ class Character():
|
||||
self._proficiencies_text = list()
|
||||
self._spells = list()
|
||||
self._spells_prepared = list()
|
||||
self.infusions = list()
|
||||
self.custom_features = list()
|
||||
self.feature_choices = list()
|
||||
|
||||
@@ -417,6 +421,8 @@ class Character():
|
||||
eff_level += c.level // 2
|
||||
elif type(c) in [classes.Fighter, classes.Rogue]:
|
||||
eff_level += c.level // 3
|
||||
elif type(c) is classes.Artificer:
|
||||
eff_level += math.ceil(c.level / 2)
|
||||
if eff_level == 0:
|
||||
return 0
|
||||
else:
|
||||
@@ -516,6 +522,18 @@ class Character():
|
||||
else:
|
||||
# Instantiate them all for the spells list
|
||||
self._spells_prepared = tuple(S() for S in _spells)
|
||||
elif attr == 'infusions':
|
||||
if hasattr(self, 'Artificer'):
|
||||
_infusions = []
|
||||
for infusion_name in val:
|
||||
try:
|
||||
_infusions.append(findattr(infusions, infusion_name))
|
||||
except AttributeError:
|
||||
msg = (f'Infusion "{infusion_name}" not defined. '
|
||||
f'Please add it to ``infusions.py``')
|
||||
warnings.warn(msg)
|
||||
_infusions.sort(key=lambda infusion: infusion.name)
|
||||
self.infusions = tuple(i() for i in _infusions)
|
||||
else:
|
||||
if not hasattr(self, attr):
|
||||
warnings.warn(f"Setting unknown character attribute {attr}",
|
||||
@@ -710,6 +728,13 @@ class Character():
|
||||
if hasattr(self, 'Druid'):
|
||||
self.Druid.wild_shapes = new_shapes
|
||||
|
||||
@property
|
||||
def infusions_text(self):
|
||||
if hasattr(self, 'Artificer'):
|
||||
return tuple([i.name for i in self.infusions])
|
||||
else:
|
||||
return ()
|
||||
|
||||
@classmethod
|
||||
def load(cls, character_file):
|
||||
# Create a character from the character definition
|
||||
@@ -788,6 +813,13 @@ def read_character_file(filename):
|
||||
|
||||
|
||||
# Add backwards compatability for tests
|
||||
class Artificer(Character):
|
||||
def __init__(self, level=1, **attrs):
|
||||
attrs['classes'] = ['Artificer']
|
||||
attrs['levels'] = [level]
|
||||
super().__init__(**attrs)
|
||||
|
||||
|
||||
class Barbarian(Character):
|
||||
def __init__(self, level=1, **attrs):
|
||||
attrs['classes'] = ['Barbarian']
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
__all__ = ('CharClass', 'Barbarian', 'Bard', 'Cleric', 'Druid', 'Fighter',
|
||||
__all__ = ('CharClass', 'Artificer', 'Barbarian', 'Bard', 'Cleric', 'Druid', 'Fighter',
|
||||
'Monk', 'Paladin', 'Ranger', 'Rogue', 'Sorceror', 'Warlock',
|
||||
'Wizard', 'RevisedRanger', 'available_classes')
|
||||
|
||||
from dungeonsheets.classes.artificer import Artificer
|
||||
from dungeonsheets.classes.barbarian import Barbarian
|
||||
from dungeonsheets.classes.bard import Bard
|
||||
from dungeonsheets.classes.classes import CharClass
|
||||
@@ -16,5 +17,5 @@ from dungeonsheets.classes.sorceror import Sorceror
|
||||
from dungeonsheets.classes.warlock import Warlock
|
||||
from dungeonsheets.classes.wizard import Wizard
|
||||
|
||||
available_classes = [Barbarian, Bard, Cleric, Druid, Fighter, Monk, Paladin,
|
||||
available_classes = [Artificer, Barbarian, Bard, Cleric, Druid, Fighter, Monk, Paladin,
|
||||
Ranger, Rogue, Sorceror, Warlock, Wizard, RevisedRanger]
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
from collections import defaultdict
|
||||
|
||||
from dungeonsheets import features, weapons
|
||||
from dungeonsheets.classes.classes import CharClass, SubClass
|
||||
|
||||
|
||||
# Eberron Rising from the Last War
|
||||
class Alchemist(SubClass):
|
||||
"""An Alchemist is an expert at combining reagents to produce mystical
|
||||
effects. Alchemists use their creations to give life and to leech it away.
|
||||
Alchemy is the oldest of artificer traditions, and its versatility has
|
||||
long been valued during times of war and peace.
|
||||
"""
|
||||
|
||||
name = "Alchemist"
|
||||
features_by_level = defaultdict(list)
|
||||
features_by_level[3] = [features.AlchemistToolProficiency,
|
||||
features.AlchemistSpells,
|
||||
features.ExperimentalElixir]
|
||||
features_by_level[5] = [features.AlchemicalSavant]
|
||||
features_by_level[9] = [features.RestorativeReagents]
|
||||
features_by_level[15] = [features.ChemicalMastery]
|
||||
|
||||
|
||||
class Artillerist(SubClass):
|
||||
"""An Artillerist specializes in using magic to hurl energy, projectiles,
|
||||
and explosions on a battlefield. This destructive power was valued by all
|
||||
the armies of the Last War. Now that the war is over, some members of this
|
||||
specialization have sought to build a more peaceful world by using their
|
||||
powers to fight the resurgence of strife in Khorvaire. The gnome artificer
|
||||
Vi, an unlikely yet key member of House Cannith's warforged project, has
|
||||
been especially vocal about making things right: "It's about time we fixed
|
||||
things instead of blowing them all to hell."
|
||||
"""
|
||||
|
||||
name = "Artillerist"
|
||||
features_by_level = defaultdict(list)
|
||||
features_by_level[3] = [features.ArtilleristSpells,
|
||||
features.ArtilleristToolProficiency,
|
||||
features.EldritchCannon]
|
||||
features_by_level[5] = [features.ArcaneFirearm]
|
||||
features_by_level[9] = [features.ExplosiveCannon]
|
||||
features_by_level[15] = [features.FortifiedPosition]
|
||||
|
||||
|
||||
class BattleSmith(SubClass):
|
||||
"""Armies require protection, and someone has to put things back together
|
||||
if defenses fail. A combination of protector and medic, a Battle Smith is
|
||||
an expert at defending others and repairing both material and personnel.
|
||||
To aid in their work, Battle Smiths are usually accompanied by a steel
|
||||
defender, a protective companion of their own creation. Many soldiers tell
|
||||
stories of nearly dying before being saved by a Battle Smith and a steel
|
||||
defender.
|
||||
|
||||
Battle Smiths played a key role in House Cannith's work on battle
|
||||
constructs and the original warforged, and after the Last War, these
|
||||
artificers led efforts to aid those who were injured in the war's horrific
|
||||
battles.
|
||||
"""
|
||||
|
||||
name = "Battle Smith"
|
||||
features_by_level = defaultdict(list)
|
||||
features_by_level[3] = [features.BattleSmithSpells,
|
||||
features.BattleSmithToolProficiency,
|
||||
features.BattleReady,
|
||||
features.SteelDefender]
|
||||
features_by_level[5] = [features.ExtraAttackBattleSmith]
|
||||
features_by_level[9] = [features.ArcaneJolt]
|
||||
features_by_level[15] = [features.ImprovedDefender]
|
||||
|
||||
|
||||
class Artificer(CharClass):
|
||||
name = "Artificer"
|
||||
hit_dice_faces = 8
|
||||
subclass_select_level = 3
|
||||
subclasses_available = (Alchemist, Artillerist, BattleSmith)
|
||||
saving_throw_proficiencies = ('intelligence', 'constitution')
|
||||
primary_abilities = ('intelligence',)
|
||||
_proficiencies_text = (
|
||||
'Light armor', 'Medium armor', 'Shields', 'Simple weapons',
|
||||
"Thieve's tools", "Tinker's tools",
|
||||
"One type of artisan's tools of your choice")
|
||||
_multiclass_proficiencies_text = (
|
||||
"Light armor", "Medium armor", "Shields",
|
||||
"Thieve's tools", "Tinker's tools")
|
||||
weapon_proficiencies = (weapons.SimpleWeapon,)
|
||||
infusions = []
|
||||
class_skill_choices = (
|
||||
'Arcana', 'History', 'Investigation',
|
||||
'Medicine', 'Nature', 'Perception', 'Sleight of Hand')
|
||||
features_by_level = defaultdict(list)
|
||||
features_by_level[1] = [features.MagicalTinkering,
|
||||
features.FirearmProficiency,
|
||||
features.ArtificerSpellcasting,
|
||||
features.ArtificerRitualCasting]
|
||||
features_by_level[2] = [features.InfuseItem]
|
||||
features_by_level[3] = [features.TheRightToolForTheJob]
|
||||
features_by_level[6] = [features.ToolExpertise]
|
||||
features_by_level[7] = [features.FlashOfGenius]
|
||||
features_by_level[10] = [features.MagicItemAdept]
|
||||
features_by_level[11] = [features.SpellStoringItem]
|
||||
features_by_level[14] = [features.MagicItemSavant]
|
||||
features_by_level[18] = [features.MagicItemMaster]
|
||||
features_by_level[20] = [features.SoulOfArtifice]
|
||||
spellcasting_ability = 'intelligence'
|
||||
spell_slots_by_level = {
|
||||
1: (2, 2, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
2: (2, 2, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
3: (2, 3, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
4: (2, 3, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
5: (2, 4, 2, 0, 0, 0, 0, 0, 0, 0),
|
||||
6: (2, 4, 2, 0, 0, 0, 0, 0, 0, 0),
|
||||
7: (2, 4, 3, 0, 0, 0, 0, 0, 0, 0),
|
||||
8: (2, 4, 3, 0, 0, 0, 0, 0, 0, 0),
|
||||
9: (2, 4, 3, 2, 0, 0, 0, 0, 0, 0),
|
||||
10: (3, 4, 3, 2, 0, 0, 0, 0, 0, 0),
|
||||
11: (3, 4, 3, 3, 0, 0, 0, 0, 0, 0),
|
||||
12: (3, 4, 3, 3, 0, 0, 0, 0, 0, 0),
|
||||
13: (3, 4, 3, 3, 1, 0, 0, 0, 0, 0),
|
||||
14: (4, 4, 3, 3, 1, 0, 0, 0, 0, 0),
|
||||
15: (4, 4, 3, 3, 2, 0, 0, 0, 0, 0),
|
||||
16: (4, 4, 3, 3, 2, 0, 0, 0, 0, 0),
|
||||
17: (4, 4, 3, 3, 3, 1, 0, 0, 0, 0),
|
||||
18: (4, 4, 3, 3, 3, 1, 0, 0, 0, 0),
|
||||
19: (4, 4, 3, 3, 3, 2, 0, 0, 0, 0),
|
||||
20: (4, 4, 3, 3, 3, 2, 0, 0, 0, 0)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
from dungeonsheets.features.artificer import *
|
||||
from dungeonsheets.features.backgrounds import *
|
||||
from dungeonsheets.features.barbarian import *
|
||||
from dungeonsheets.features.bard import *
|
||||
|
||||
@@ -0,0 +1,675 @@
|
||||
from dungeonsheets import spells
|
||||
from dungeonsheets.features.features import Feature
|
||||
|
||||
|
||||
class _SpecialistSpells(Feature):
|
||||
"""Starting at 3rd level, you always have certain spells prepared after
|
||||
you reach particular levels in this class, as shown in the Specialization
|
||||
Spells table. These spells count as artificer spells for you, but they
|
||||
don't count against the number of artificer spells you prepare.
|
||||
"""
|
||||
_name = "Select One"
|
||||
source = "Artificer"
|
||||
_spells = {
|
||||
3: [],
|
||||
5: [],
|
||||
9: [],
|
||||
13: [],
|
||||
17: []
|
||||
}
|
||||
spells_known = []
|
||||
spells_prepared = []
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return "{:s} Spells".format(self._name)
|
||||
|
||||
def __init__(self, owner=None):
|
||||
if owner is not None:
|
||||
level = owner.Artificer.level
|
||||
for lvl, spl in self._spells.items():
|
||||
if level >= lvl:
|
||||
self.spells_known.extend(spl)
|
||||
self.spells_prepared.extend(spl)
|
||||
super().__init__(owner=owner)
|
||||
|
||||
|
||||
# Alchemist
|
||||
class ArtificerSpellcasting(Feature):
|
||||
"""You have studied the workings of magic and how to channel it through
|
||||
objects. As a result, you have gained the ability to cast spells. To
|
||||
observers, you don't appear to be casting spells in a conventional way; you
|
||||
look as if you're producing wonders using mundane items or outlandish
|
||||
inventions.
|
||||
|
||||
**Tools Required** You produce your artificer spell effects through your
|
||||
tools. You must have a spellcasting focus-specifically thieves' tools or
|
||||
some kind of artisan's tool-in hand when you cast any spell with this
|
||||
Spellcasting feature. You must be proficient with the tool to use it in
|
||||
this way. See chapter 5, "Equipment," in the Player's Handbook for
|
||||
descriptions of these tools.
|
||||
|
||||
After you gain the Infuse Item feature at 2nd level, you can also use any
|
||||
item bearing one of your infusions as a spellcasting focus.
|
||||
"""
|
||||
|
||||
name = "Spellcasting"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class ArtificerRitualCasting(Feature):
|
||||
"""You can cast an artificer spell as a ritual if that spell has the ritual
|
||||
tag and you have the spell prepared.
|
||||
"""
|
||||
|
||||
name = "Ritual Casting"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class FirearmProficiency(Feature):
|
||||
"""The secrets of creating and operating gunpowder weapons have been
|
||||
discovered in various corners of the D&D multiverse. If your Dungeon Master
|
||||
uses the rules on firearms in chapter 9 of the Dungeon Master's Guide and
|
||||
your artificer has been exposed to the operation of such weapons, your
|
||||
artificer is proficient with them.
|
||||
"""
|
||||
|
||||
name = "Optional Rule: Firearm Proficiency"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class MagicalTinkering(Feature):
|
||||
"""At 1st level, you learn how to invest a spark of magic into mundane
|
||||
objects. To use this ability, you must have tinker's tools or other
|
||||
artisan's tools in hand. You then touch a Tiny nonmagical object as an
|
||||
action and give it one of the following magical properties of your choice:
|
||||
|
||||
• The object sheds bright light in a 5-foot radius and dim light for an
|
||||
additional 5 fe et.
|
||||
|
||||
• Whenever tapped by a creature, the object emits a recorded message that
|
||||
can be heard up to 10 feet away. You utter the message when you bestow
|
||||
this property on the object, and the recording can be no more than 6
|
||||
seconds long.
|
||||
|
||||
• The object continuously emits your choice of an odor or a nonverbal sound
|
||||
(wind, waves, chirping, or the like). The chosen phenomenon is
|
||||
perceivable up to 10 feet away.
|
||||
|
||||
• A static visual effect appears on one of the object's surfaces. This
|
||||
effect can be a picture, up to 25 words of text, lines and shapes, or a
|
||||
mixture of these elements, as you like. The chosen property lasts
|
||||
indefinitely. As an action, you can touch the object and end the property
|
||||
early. You can bestow magic on multiple objects, touching one object each
|
||||
time you use this feature, though a single object can only bear one
|
||||
property at a time. The maximum number of objects you can affect with
|
||||
this feature at one time is equal to your Intelligence modifier (minimum
|
||||
of one object). If you try to exceed your maximum, the oldest property
|
||||
immediately ends, and then the new property applies.
|
||||
"""
|
||||
|
||||
name = "Magical Tinkering"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class InfuseItem(Feature):
|
||||
"""At 2nd level, you gain the ability to imbue mundane items with certain
|
||||
magical infusions. The magic items you create with this feature are
|
||||
effectively prototypes of permanent items.
|
||||
|
||||
**Infusions known**
|
||||
When you gain this feature, pick four artificer infusions
|
||||
to learn, choosing from the "Artificer Infusions" section at the end of the
|
||||
class's description. You learn additional infusions of your choice when you
|
||||
reach certain levels in this class, as shown in the Infusions Known column
|
||||
of the Artificer table. Whenever you gain a level in this class, you can
|
||||
replace one of the artificer infusions you learned with a new one.
|
||||
|
||||
**Infusing an item**
|
||||
Whenever you finish a long rest, you can touch a nonmagical object and
|
||||
imbue it with one of your artificer infusions, turning it into a magic
|
||||
item. An infusion works on only certain kinds of objects, as specified in
|
||||
the infusion's description. If the item requires attunement, you can
|
||||
attune yourself to it the instant you infuse the item. If you decide to
|
||||
attune to the item later, you must do so using the normal process for
|
||||
attunement (see "Attunement" in chapter 7 of the Dungeon Master's Guide).
|
||||
Your infusion remains in an item indefinitely, but when you die, the
|
||||
infusion vanishes after a number of days have passed equal to your
|
||||
Intelligence modifier (minimum of 1 day). The infusion also vanishes if you
|
||||
give up your knowledge of the infusion for another one. You can infuse more
|
||||
than one nonmagical object at the end of a long rest; the maximum number of
|
||||
objects appears in the Infused Items column of the Artificer table. You
|
||||
must touch each of the objects, and each of your infusions can be in only
|
||||
one object at a time. Moreover, no object can bear more than one of your
|
||||
infusions at a time. If you try to exceed your maximum number of
|
||||
infusions, the oldest infusion immediately ends, and then the new
|
||||
infusion applies.
|
||||
"""
|
||||
|
||||
_name = "Infuse Item"
|
||||
source = "Artificer"
|
||||
_infusions = {
|
||||
# level: (infusions known, infused items)
|
||||
2: (4, 2),
|
||||
3: (4, 2),
|
||||
4: (4, 2),
|
||||
5: (4, 2),
|
||||
5: (4, 2),
|
||||
6: (6, 3),
|
||||
7: (6, 3),
|
||||
8: (6, 3),
|
||||
9: (6, 3),
|
||||
10: (8, 4),
|
||||
11: (8, 4),
|
||||
12: (8, 4),
|
||||
13: (8, 4),
|
||||
14: (10, 5),
|
||||
15: (10, 5),
|
||||
16: (10, 5),
|
||||
17: (10, 5),
|
||||
18: (12, 6),
|
||||
19: (12, 6),
|
||||
20: (12, 6),
|
||||
}
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
known_infusions = self._infusions[self.owner.Artificer.level][0]
|
||||
infused_items = self._infusions[self.owner.Artificer.level][1]
|
||||
name_ext = " ({:d} Infusions Known, {:d} Infused Items)"
|
||||
return self._name + name_ext.format(known_infusions, infused_items)
|
||||
|
||||
|
||||
class ArtificerSpecialist(Feature):
|
||||
"""At 3rd level, you choose the type of specialist you are: Alchemist,
|
||||
Artillerist, or Battle Smith, each of which is detailed at the end of the
|
||||
class's description. Your choice grants you features at 5th level and again
|
||||
at 9th and 15th level.
|
||||
"""
|
||||
|
||||
name = "Artificer Specialist"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class TheRightToolForTheJob(Feature):
|
||||
"""At 3rd level, you learn how to produce exactly the tool you need: with
|
||||
tinker's tools in hand, you can magically create one set of artisan's tools
|
||||
in an unoccupied space within 5 feet of you. This creation requires 1 hour
|
||||
of uninterrupted work, which can coincide with a short or long rest.
|
||||
Though the product of magic, the tools are nonmagical, and they vanish when
|
||||
you use this feature again.
|
||||
"""
|
||||
|
||||
name = "The Right Tool For The Job"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class ToolExpertise(Feature):
|
||||
"""Starting at 6th level, your proficiency bonus is doubled for any ability
|
||||
check you make that uses your proficiency with a tool.
|
||||
"""
|
||||
|
||||
name = "Tool Expertise"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class FlashOfGenius(Feature):
|
||||
"""Starting at 7th level, you gain the ability to come up with solutions
|
||||
under pressure. When you or another creature you can see within 30 feet of
|
||||
you makes an ability check or a saving throw, you can use your reaction to
|
||||
add your Intelligence modifier to the roll.
|
||||
|
||||
You can use this feature a number of times equal to your Intelligence
|
||||
modifier (minimum of once). You regain all expended uses when you finish a
|
||||
long rest.
|
||||
"""
|
||||
|
||||
name = "Flash Of Genius"
|
||||
source = "Arificer"
|
||||
|
||||
|
||||
class MagicItemAdept(Feature):
|
||||
"""When you reach 10th level, you achieve a profound understanding of how
|
||||
to use and make magic items:
|
||||
|
||||
• You can attune to up to four magic items at once.
|
||||
|
||||
• If you craft a magic item with a rarity of common or uncommon, it takes
|
||||
you a quarter of the normal time, and it costs you half as much of the
|
||||
usual gold.
|
||||
"""
|
||||
|
||||
name = "Magic Item Adept"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class SpellStoringItem(Feature):
|
||||
"""At 11th level, you learn how to store a spell in an object. Whenever you
|
||||
finish a long rest, you can touch one simple or martial weapon or one item
|
||||
that you can use as a spellcasting focus, and you store a spell in it,
|
||||
choosing a 1st• or 2nd-level spell from the artificer spell list that
|
||||
requires 1 action to cast (you needn't have it prepared).
|
||||
|
||||
While holding the object, a creature can take an action to produce the
|
||||
spell's effect from it, using your spellcasting ability modifier. If the
|
||||
spell requires concentration, the creature must concentrate. The spell
|
||||
stays in the object until it's been used a number of times equal to twice
|
||||
your Intelligence modifier (minimum of twice) or until you use this fe
|
||||
ature again to store a spell in an object.
|
||||
"""
|
||||
|
||||
name = "Spell-Storing Item"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class MagicItemSavant(Feature):
|
||||
"""At 14th level, your skill with magic items deepens more:
|
||||
|
||||
• You can attune to up to five magic items at once.
|
||||
|
||||
• You ignore all class, race, spell, and level requirements on attuning to
|
||||
or using a magic item.
|
||||
"""
|
||||
|
||||
name = "Magic Item Savant"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class MagicItemMaster(Feature):
|
||||
"""Starting at 18th level, you can attune to up to six magic items at
|
||||
once.
|
||||
"""
|
||||
|
||||
name = "Magic Item Master"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
class SoulOfArtifice(Feature):
|
||||
"""At 20th level, you develop a mystical connection to your magic items,
|
||||
which you can draw on for protection:
|
||||
|
||||
• You gain a +1 bonus to all saving throws per magic item you are currently
|
||||
attuned to.
|
||||
|
||||
• If you're reduced to 0 hit points but not killed outright, you can use
|
||||
your reaction to end one of your artificer infusions, causing you to drop
|
||||
to 1 hit point instead of 0.
|
||||
"""
|
||||
|
||||
name = "Soul of Artifice"
|
||||
source = "Artificer"
|
||||
|
||||
|
||||
# Alchemist
|
||||
class AlchemistToolProficiency(Feature):
|
||||
"""When you adopt this specialization at 3rd level, you gain proficiency
|
||||
with alchemist's supplies. If you already have this proficiency, you gain
|
||||
proficiency with one other type of artisan's tools of your choice.
|
||||
"""
|
||||
|
||||
name = "Tool Proficiency"
|
||||
source = "Artificer (Alchemist)"
|
||||
|
||||
|
||||
class AlchemistSpells(_SpecialistSpells):
|
||||
"""Starting at 3rd level, you always have certain spells prepared after
|
||||
you reach particular levels in this class, as shown in the Alchemist Spells
|
||||
table. These spells count as artificer spells for you, but they don't count
|
||||
against the number of artificer spells you prepare.
|
||||
"""
|
||||
|
||||
_name = "Alchemist"
|
||||
_spells = {
|
||||
3: [spells.HealingWord, spells.RayOfSickness],
|
||||
5: [spells.FlamingSphere, spells.MelfsAcidArrow],
|
||||
9: [spells.GaseousForm, spells.MassHealingWord],
|
||||
13: [spells.Blight, spells.DeathWard],
|
||||
17: [spells.Cloudkill, spells.RaiseDead]
|
||||
}
|
||||
|
||||
|
||||
class ExperimentalElixir(Feature):
|
||||
"""Beginning at 3rd level, whenever you finish a long rest, you can
|
||||
magically produce an *experimental elixir* in an empty flask you touch.
|
||||
Roll on the Experimental Elixir table for the elixir's effect, which is
|
||||
triggered when someone drinks the elixir. As an action, a creature can
|
||||
drink the elixir or administer it to an incapacitated creature.
|
||||
|
||||
Creating an *experimental elixir* requires you to have alchemist supplies
|
||||
on your person, and any elixir you create with this feature lasts until it
|
||||
is drunk or until the end of your next long rest.
|
||||
|
||||
When you reach certain levels in this class, you can make more elixirs at
|
||||
the end of a long rest: two at 6th level and three at 15th level. Roll for
|
||||
each elixir's effect separately. Each elixir requires its own flask.
|
||||
|
||||
You can create additional *experimental elixirs* by expending a spell slot
|
||||
of 1st level or higher for each one. When you do so, you use your action to
|
||||
create the elixir in an empty flask you touch, and you choose the elixir's
|
||||
effect from the Experimental Elixir table.
|
||||
|
||||
**Experimental Elixir**
|
||||
|
||||
roll d6
|
||||
|
||||
**1 -- Healing.** The drinker regains a number of hit points equal to 2d4 +
|
||||
your Intelligence modifier.
|
||||
|
||||
**2 -- Swiftness.** The drinker's walking speed increases by 10 feet for 1
|
||||
hour.
|
||||
|
||||
**3 -- Resilience.** The drinker gains a +1 bonus to AC for 10 minutes.
|
||||
|
||||
**4 -- Boldness.** The drinker can roll a d4 and add the number rolled to
|
||||
every attack roll and saving throw they make for the next minute.
|
||||
|
||||
**5 -- Flight.** The drinker gains a flying speed of 10 feet for 10
|
||||
minutes.
|
||||
|
||||
**6 -- Transformation.** The drinker's body is transformed as if by the
|
||||
alter self spell. The drinker determines the transformation caused by the
|
||||
spell, the effects of which last for 10 minutes.
|
||||
"""
|
||||
|
||||
name = "Experimental Elixir"
|
||||
source = "Artificer (Alchemist)"
|
||||
|
||||
|
||||
class AlchemicalSavant(Feature):
|
||||
"""At 5th level, you develop masterful command of magical chemicals,
|
||||
enhancing the healing and damage you create through them. Whenever you
|
||||
cast a spell using your alchemist's supplies as the spellcasting focus, you
|
||||
gain a bonus to one roll of the spell. That roll must restore hit points or
|
||||
be a damage roll that deals acid, fire, necrotic, or poison damage, and the
|
||||
bonus equals your Intelligence modifier (minimum of +1).
|
||||
"""
|
||||
|
||||
name = "Alchemical Savant"
|
||||
source = "Artificer (Alchemist)"
|
||||
|
||||
|
||||
class RestorativeReagents(Feature):
|
||||
"""Starting at 9th level, you can incorporate
|
||||
restorative reagents into some of your works:
|
||||
|
||||
• Whenever a creature drinks an experimental elixir you created, the
|
||||
creature gains temporary hit points equal to 2d6 + your Intelligence
|
||||
modifier (minimum of 1 temporary hit point).
|
||||
|
||||
• You can cast lesser restoration without expending a spell slot and
|
||||
without preparing the spell, provided you use alchemist's supplies as the
|
||||
spellcasting focus. You can do so a number of times equal to your
|
||||
Intelligence modifier (minimum of once), and you regain all expended uses
|
||||
when you finish a long rest.
|
||||
"""
|
||||
|
||||
name = "Restorative Reagents"
|
||||
source = "Artificer (Alchemist)"
|
||||
|
||||
|
||||
class ChemicalMastery(Feature):
|
||||
"""By 15th level, you have been exposed to so many chemicals that they
|
||||
pose little risk to you, and you can use them to quickly end certain
|
||||
ailments:
|
||||
|
||||
• You gain resistance to acid damage and poison damage, and you are immune
|
||||
to the poisoned condition.
|
||||
|
||||
• You can cast greater restoration and heal without expending a spell
|
||||
slot, without preparing the spell, and without material components,
|
||||
provided you use alchemist's supplies as the spellcasting focus. Once
|
||||
you cast either spell with this feature, you can't cast that spell with
|
||||
it again until you finish a long rest.
|
||||
"""
|
||||
|
||||
name = "Chemical Mastery"
|
||||
source = "Artificer (Alchemist)"
|
||||
|
||||
|
||||
# Artillerist
|
||||
class ArtilleristSpells(_SpecialistSpells):
|
||||
"""Starting at 3rd level, you always have certain spells prepared after
|
||||
you reach particular levels in this class, as shown in the Artillerist
|
||||
Spells table. These spells count as artificer spells for you, but they
|
||||
don't count against the number of artificer spells you prepare.
|
||||
"""
|
||||
|
||||
_name = "Artillerist"
|
||||
_spells = {
|
||||
3: [spells.Shield, spells.Thunderwave],
|
||||
5: [spells.ScorchingRay, spells.Shatter],
|
||||
9: [spells.Fireball, spells.WindWall],
|
||||
13: [spells.IceStorm, spells.WallOfFire],
|
||||
17: [spells.ConeOfCold, spells.WallOfForce]
|
||||
}
|
||||
|
||||
|
||||
class ArtilleristToolProficiency(Feature):
|
||||
"""When you adopt this specialization at 3rd level, you gain proficiency
|
||||
with woodcarver's tools. If you already have this proficiency, you gain
|
||||
proficiency with one other type of artisan's tools of your choice.
|
||||
"""
|
||||
|
||||
name = "Tool Proficiency"
|
||||
source = "Artificer (Artillerist)"
|
||||
|
||||
|
||||
class EldritchCannon(Feature):
|
||||
"""At 3rd level, you learn how to create a magical cannon. Using
|
||||
woodcarver's tools or smith's tools, you can take an action to magically
|
||||
create a Small or Tiny eldritch cannon in an unoccupied space on a
|
||||
horizontal surface within 5 feet of you. A Small eldritch cannon occupies
|
||||
its space, and a Tiny one can be held in one hand.
|
||||
|
||||
Once you create a cannon, you can't do so again until you finish a long
|
||||
rest or until you expend a spell slot of 1st level or higher. You can have
|
||||
only one cannon at a time and can't create one while your cannon is
|
||||
present.
|
||||
|
||||
The cannon is a magical object. Regardless of size, the cannon has an AC of
|
||||
18 and a number of hit points equal to five times your artificer level. It
|
||||
is immune to poison damage, psychic damage, and all conditions. If it is
|
||||
forced to make an ability check or a saving throw, treat all its ability
|
||||
scores as 10 (+O). If the *mending* spell is cast on it, it regains 2d6 hit
|
||||
points. It disappears if it is reduced to 0 hit points or after 1 hour. You
|
||||
can dismiss it early as an action.
|
||||
|
||||
When you create the cannon, you determine its appearance and whether it
|
||||
has legs. You also decide which type it is, choosing from the options on
|
||||
the Eldritch Cannons table. On each of your turns, you can take a bonus
|
||||
action to cause the cannon to activate if you are within 60 feet of it. As
|
||||
part of the same bonus action, you can direct the cannon to walk or climb
|
||||
up to 15 feet to an unoccupied space, provided it has legs.
|
||||
|
||||
**Eldritch Cannons**
|
||||
|
||||
*Flamethrower*: The cannon exhales fire in an adjacent 15-foot cone that
|
||||
you designate. Each creature in that area must make a Dexterity saving
|
||||
throw against your spell save DC, taking 2d8 fire damage on a failed save
|
||||
or half as much damage on a successful one. The fire ignites any flammable
|
||||
objects in the area that aren't being worn or carried.
|
||||
|
||||
*Force Ballista*: Make a ranged spell attack, originating from the cannon,
|
||||
at one creature or object within 120 feet of it. On a hit, the target takes
|
||||
2d8 force damage, and if the target is a creature, it is pushed up to 5
|
||||
feet away from the cannon.
|
||||
|
||||
*Protector*: The cannon emits a burst of positive energy
|
||||
that grants itself and each creature of your choice within 10 feet of it a
|
||||
number of temporary hit points equal to 1d8 + your Intelligence modifier
|
||||
(minimum of +1)
|
||||
"""
|
||||
|
||||
name = "Eldritch Cannon"
|
||||
source = "Artificer (Artillerist)"
|
||||
|
||||
|
||||
class ArcaneFirearm(Feature):
|
||||
"""At 5th level, you know how to turn a wand, staff, or rod into an arcane
|
||||
firearm, a conduit for your destructive spells. When you finish a long
|
||||
rest, you can use woodcarver's tools to carve special sigils into a wand,
|
||||
staff, or rod and thereby turn it into your arcane firearm. The sigils
|
||||
disappear from the object if you later carve them on a different item. The
|
||||
sigils otherwise last indefinitely.
|
||||
|
||||
You can use your arcane firearm as a spellcasting focus for your artificer
|
||||
spells. When you cast an artificer spell through the firearm, roll a d8,
|
||||
and you gain a bonus to one of the spell's damage rolls equal to the
|
||||
number rolled.
|
||||
"""
|
||||
|
||||
name = "Arcane Firearm"
|
||||
source = "Artificer (Artillerist)"
|
||||
|
||||
|
||||
class ExplosiveCannon(Feature):
|
||||
"""Starting at 9th level, every eldritch cannon you create is more
|
||||
destructive:
|
||||
|
||||
• The cannon's damage rolls all increase by 1d8.
|
||||
|
||||
• As an action, you can command the cannon to detonate if you are within 60
|
||||
feet of it. Doing so destroys the cannon and forces each creature within
|
||||
20 feet of it to make a Dexterity saving throw against your spell save
|
||||
DC, taking 3d8 force damage on a failed save or half as much damage on a
|
||||
successful one.
|
||||
"""
|
||||
|
||||
name = "Explosive Cannon"
|
||||
source = "Artificer (Artillerist)"
|
||||
|
||||
|
||||
class FortifiedPosition(Feature):
|
||||
"""Starting at 15th level, you're a master at forming well-defended
|
||||
emplacements using Eldritch Cannon:
|
||||
|
||||
• You and your allies have half cover while within 10 feet of a cannon you
|
||||
create with Eldritch Cannon, as a result of a shimmering field of magical
|
||||
protection that the cannon emits.
|
||||
|
||||
• You can now have two cannons at the same time. You can create two with
|
||||
the same action (but not the same spell slot), and you can activate both
|
||||
of them with the same bonus action. You determine whether the cannons are
|
||||
identical to each other or different. You can't create a third cannon
|
||||
while you have two.
|
||||
"""
|
||||
|
||||
name = "Fortified Position"
|
||||
source = "Artificer (Artillerist)"
|
||||
|
||||
|
||||
# Battle Smith
|
||||
class BattleSmithSpells(_SpecialistSpells):
|
||||
"""Starting at 3rd level, you always have certain spells prepared after you
|
||||
reach particular levels in this class, as shown in the Battle Smith Spells
|
||||
table. These spells count as artificer spells for you, but they don't count
|
||||
against the number of artificer spells you prepare.
|
||||
"""
|
||||
|
||||
_name = "Battle Smith"
|
||||
_spells = {
|
||||
3: [spells.Heroism, spells.Shield],
|
||||
5: [spells.BrandingSmite, spells.WardingBond],
|
||||
9: [spells.AuraOfVitality, spells.ConjureBarrage],
|
||||
13: [spells.AuraOfPurity, spells.FireShield],
|
||||
17: [spells.BanishingSmite, spells.MassCureWounds]
|
||||
}
|
||||
|
||||
|
||||
class BattleSmithToolProficiency(Feature):
|
||||
"""When you adopt this specialization at 3rd level, you gain proficiency
|
||||
with smith's tools. If you already have this proficiency, you gain
|
||||
proficiency with one other type of artisan's tools of your choice.
|
||||
"""
|
||||
|
||||
name = "Tool Proficiency"
|
||||
source = "Artificer (Battle Smith)"
|
||||
|
||||
|
||||
class BattleReady(Feature):
|
||||
"""When you reach 3rd level, your combat training and your experiments with
|
||||
magic have paid off in two ways:
|
||||
|
||||
• You gain proficiency with martial weapons.
|
||||
|
||||
• When you attack with a magic weapon, you can use your Intelligence
|
||||
modifier, instead of Strength or Dexterity modifier, for the attack and
|
||||
damage rolls.
|
||||
"""
|
||||
|
||||
name = "Battle Ready"
|
||||
source = "Artificer (Battle Smith)"
|
||||
|
||||
|
||||
class SteelDefender(Feature):
|
||||
"""By 3rd level, your tinkering has borne you a faithful companion, a steel
|
||||
defender. It is friendly to you and your companions, and it obeys your
|
||||
commands. See this creature's game statistics in the steel defender stat
|
||||
block. You determine the creature's appearance and whether it has two legs
|
||||
or fo ur; your choice has no effect on its game statistics.
|
||||
|
||||
In combat, the steel defender shares your initiative count, but it takes
|
||||
its turn immediately after yours. It can move and use its reaction on its
|
||||
own, but the only action it takes on its turn is the Dodge action, unless
|
||||
you take a bonus action on your turn to command it to take one of the
|
||||
actions in its stat block or the Dash, Disengage, Help, Hide, or Search
|
||||
action.
|
||||
|
||||
If the *mending* spell is cast on it, it regains 2d6 hit points. If it has
|
||||
died within the last hour, you can use your smith's tools as an action to
|
||||
revive it, provided you are within 5 feet of it and you expend a spell slot
|
||||
of 1st level or higher. The steel defender returns to life after 1 minute
|
||||
with all its hit points restored.
|
||||
|
||||
At the end of a long rest, you can create a new steel defender if you have
|
||||
your smith's tools with you. If you already have a steel defender from this
|
||||
feature, the first one immediately perishes.
|
||||
"""
|
||||
|
||||
name = "Steel Defender"
|
||||
source = "Artificer (Battle Smith)"
|
||||
|
||||
|
||||
class ExtraAttackBattleSmith(Feature):
|
||||
"""Starting at 5th level, you can attack twice, rather than once, whenever
|
||||
you take the Attack action on your turn.
|
||||
"""
|
||||
|
||||
name = "Extra Attack"
|
||||
source = "Artificer (Battle Smith)"
|
||||
|
||||
|
||||
class ArcaneJolt(Feature):
|
||||
"""At 9th level, you learn new ways to channel arcane energy to harm or
|
||||
heal. When either you hit a target with a magic weapon attack or your steel
|
||||
defender hits a target, you can channel magical energy through the strike
|
||||
to create one of the following effects:
|
||||
|
||||
• The target takes an extra 2d6 force damage.
|
||||
|
||||
• Choose one creature or object you can see within 30 feet of the target.
|
||||
Healing energy flows into the chosen recipient, restoring 2d6 hit points
|
||||
to it. You can use this energy a number of times equal to your
|
||||
Intelligence modifier (minimum of once), but you can do so no more than
|
||||
once on a turn. You regain all expended uses when you finish a long rest
|
||||
"""
|
||||
|
||||
name = "Arcane Jolt"
|
||||
source = "Artificer (Battle Smith)"
|
||||
|
||||
|
||||
class ImprovedDefender(Feature):
|
||||
"""At 15th level, your Arcane jolt and steel defender become more
|
||||
powerful:
|
||||
|
||||
• The extra damage and the healing of your Arcane jolt both increase to
|
||||
4d6.
|
||||
|
||||
• Your steel defender gains a +2 bonus to Armor Class.
|
||||
|
||||
• Whenever your steel defender uses its Deflect Attack, the attacker takes
|
||||
force damage equal to 1d4 +your Intelligence modifier.
|
||||
"""
|
||||
|
||||
name = "Improved Defender"
|
||||
source = "Artificer (Battle Smith)"
|
||||
@@ -85,6 +85,9 @@ spells_prepared = {{ char.spells_prepared }}
|
||||
# Wild shapes for Druid
|
||||
wild_shapes = {{ char.all_wild_shapes }} # Ex: ('ape', 'wolf', 'ankylosaurus')
|
||||
|
||||
# Infusions for Artificer
|
||||
infusions = {{ char.infusions_text }} # Ex: ('repeating shot', 'replicate magic item')
|
||||
|
||||
# Backstory
|
||||
# Describe your backstory here
|
||||
personality_traits = """{{ char.personality_traits}}"""
|
||||
|
||||
@@ -92,6 +92,9 @@ spells = spells_prepared + __spells_unprepared
|
||||
# Wild shapes for Druid
|
||||
wild_shapes = () # Ex: ('ape', 'wolf', 'ankylosaurus')
|
||||
|
||||
# Infusions for Artificer
|
||||
infusions = {{ char.infusions_text }} # Ex: ('repeating shot', 'replicate magic item')
|
||||
|
||||
# Backstory
|
||||
# Describe your backstory here
|
||||
personality_traits = """{{ char.personality_traits }}"""
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
\documentclass[10pt,twocolumn,lettersize]{article}
|
||||
|
||||
\newlength{\zerosep}
|
||||
[% if use_dnd_decorations %]
|
||||
\usepackage[layout=true]{dnd}
|
||||
\setlength{\zerosep}{0em}
|
||||
[% else %]
|
||||
\usepackage[margin=1.5cm]{geometry}
|
||||
\setlength{\zerosep}{-1em}
|
||||
[% endif %]
|
||||
|
||||
\title{Infusion Descriptions}
|
||||
\author{[[ character.name ]] (Artificer [[ character.Artificer.level ]] level)}
|
||||
\date{}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\maketitle
|
||||
|
||||
[% for inf in character.infusions %]
|
||||
|
||||
\section*{[[ inf.name ]]}
|
||||
|
||||
[% if inf.prerequisite %]%
|
||||
|
||||
\noindent
|
||||
\textit{Prerequisite: [[ inf.prerequisite ]]}%
|
||||
|
||||
[% endif %]%
|
||||
[% if inf.item %]%
|
||||
|
||||
\noindent
|
||||
\textit{Item: [[ inf.item ]]}%
|
||||
|
||||
[% endif %]%
|
||||
|
||||
[[ inf.__doc__|rst_to_latex ]]
|
||||
|
||||
[% endfor %]
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,184 @@
|
||||
class Infusion():
|
||||
name = "Unknown infusion"
|
||||
item = "Item to be infused"
|
||||
prerequisite = ""
|
||||
classes = ('Artificer',)
|
||||
|
||||
def __str__(self):
|
||||
indicator = ('$', self.special_material)
|
||||
if indicator:
|
||||
return self.name + f' ({"".join(indicator)})'
|
||||
else:
|
||||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
return "\"{:s}\"".format(self.name)
|
||||
|
||||
def __eq__(self, other):
|
||||
return (self.name == other.name)
|
||||
|
||||
def __hash__(self):
|
||||
return 0
|
||||
|
||||
@property
|
||||
def special_material(self):
|
||||
return ('worth at least' in self.item.lower())
|
||||
|
||||
|
||||
class BootsOfTheWindingPath(Infusion):
|
||||
"""While wearing these boots, a creature can teleport up to 15 feet as a
|
||||
bonus action to an unoccupied space the creature can see. The creature
|
||||
must have occupied that space at some point during the current turn.
|
||||
"""
|
||||
|
||||
name = "Boots of the Winding Path"
|
||||
item = "A pair of boots (requires attunement"
|
||||
prerequisite = "6th-level artificer"
|
||||
|
||||
|
||||
class EnhancedArcaneFocus(Infusion):
|
||||
"""While holding this item, a creature gains a + 1 bonus to spell attack
|
||||
rolls. In addition, the creature ignores half cover when making a spell
|
||||
attack.
|
||||
|
||||
The bonus increases to +2 when you reach 10th level in this class.
|
||||
"""
|
||||
|
||||
name = "Enhanced Arcane Focus"
|
||||
item = "A rod, staff, or wand (requires attunement)"
|
||||
|
||||
|
||||
class EnhancedDefense(Infusion):
|
||||
"""A creature gains a + 1 bonus to Armor Class while wearing (armor) or
|
||||
wielding (shield) the infused item.
|
||||
|
||||
The bonus increases to +2 when you reach 10th level in this class.
|
||||
"""
|
||||
|
||||
name = "Enhanced Defense"
|
||||
item = "A suit of armor or shield"
|
||||
|
||||
|
||||
class EnhancedWeapon(Infusion):
|
||||
"""This magic weapon grants a +1 bonus to attack and damage rolls made with
|
||||
it.
|
||||
|
||||
The bonus increases to +2 when you reach 10th level in this class.
|
||||
"""
|
||||
|
||||
name = "Enhanced Weapon"
|
||||
item = "A simple or martial weapon"
|
||||
|
||||
|
||||
class HomunculusServant(Infusion):
|
||||
"""You learn intricate methods for magically creating a special homunculus
|
||||
that serves you. The item you infuse serves as the creature's heart, around
|
||||
which the creature's body instantly forms.
|
||||
|
||||
You determine the homunculus's appearance. Some artificers prefer
|
||||
mechanical-looking birds, whereas some like winged vials or miniature,
|
||||
animate cauldrons.
|
||||
|
||||
The homunculus is friendly to you and your companions, and it obeys your
|
||||
commands. See this creature's game statistics in the Homunculus Servant
|
||||
stat block.
|
||||
|
||||
In combat, the homunculus shares your initiative count, but it takes its
|
||||
turn immediately after yours. It can move and use its reaction on its own,
|
||||
but the only action it takes on its turn is the Dodgeaction, unless you
|
||||
take a bonus action on your turn to command it to take the action in its
|
||||
stat block or the Dash, Disengage, Help, Hide, or Search action.
|
||||
|
||||
The homunculus regains 2d6 hit points if the *mending* spell is cast on it.
|
||||
If it dies, it vanishes, leaving its heart in its space.
|
||||
"""
|
||||
|
||||
name = "Homunculus Servant"
|
||||
item = "A gem worth at least 100gp or a dragonshard"
|
||||
prerequisite = "6th-level artificer"
|
||||
|
||||
|
||||
class RadiantWeapon(Infusion):
|
||||
"""This magic weapon grants a + 1 bonus to attack and damage rolls made
|
||||
with it. While holding it, the wielder can take a bonus action to cause it
|
||||
to shed bright light in a 30-foot radius and dim light for an additional 30
|
||||
feet. The wielder can extinguish the light as a bonus action.
|
||||
|
||||
The weapon has 4 charges. As a reaction immediately after being hit by an
|
||||
attack, the wielder can expend 1 charge and cause the attacker to be
|
||||
blinded until the end of the attacker's next turn, unless the attacker
|
||||
succeeds on a Constitution saving throw against your spell save DC. The
|
||||
weapon regains ld4 expended charges daily at dawn.
|
||||
"""
|
||||
|
||||
name = "Radiant Weapon"
|
||||
item = "A simple or martial weapon (requires attunement)"
|
||||
prerequisite = "6th-level artificer"
|
||||
|
||||
|
||||
class RepeatingShot(Infusion):
|
||||
"""This magic weapon grants a + 1 bonus to attack and damage rolls made
|
||||
with it when it's used to make a ranged attack, and it ignores the loading
|
||||
property if it has it.
|
||||
|
||||
If you load no ammunition in the weapon, it produces its own, automatically
|
||||
creating one piece of magic ammunition when you make a ranged attack with
|
||||
it. The ammunition created by the weapon vanishes the instant after it hits
|
||||
or misses a target.
|
||||
"""
|
||||
|
||||
name = "Repeating Shot"
|
||||
item = """A simple or martial weapon with the ammunition property (requires
|
||||
attunement)"""
|
||||
|
||||
|
||||
class ReplicateMagicItem(Infusion):
|
||||
"""Using this infusion, you replicate a particular magic item. You can
|
||||
learn this infusion multiple times; each time you do so, choose a magic
|
||||
item that you can make with it, picking from the Replicable Items tables
|
||||
below. A table's title tells you the level you must be in the class to
|
||||
choose an item from the table.
|
||||
|
||||
In the tables, an item's entry tells you whether the item requires
|
||||
attunement. See the item's description in the *Dungeon Master's Guide* for
|
||||
more information about it, including the type of object required for its
|
||||
making. If you have *Xanathar's Guide to Everything*, you can choose from
|
||||
among the common magic items in that book when you pick a magic item you
|
||||
can replicate with this infusion.
|
||||
"""
|
||||
|
||||
name = "Replicate Magic Item"
|
||||
|
||||
|
||||
class RepulsionShield(Infusion):
|
||||
"""A creature gains a + 1 bonus to Armor Class while wielding this shield.
|
||||
|
||||
The shield has 4 charges. While holding it, the wielder can use a reaction
|
||||
immediately after being hit by a melee attack to expend 1 of the shield's
|
||||
charges and push the attacker up to 15 feet away. The shield regains ld4
|
||||
expended charges daily at dawn.
|
||||
"""
|
||||
|
||||
name = "Repulsion Shield"
|
||||
item = "A shield (requires attunement)"
|
||||
|
||||
|
||||
class ResistantArmor(Infusion):
|
||||
"""While wearing this armor, a creature has resistance to one of the
|
||||
following damage types, which you choose when you infuse the item: acid,
|
||||
cold, fire, force, lightning, necrotic, poison, psychic, radiant, or
|
||||
thunder.
|
||||
"""
|
||||
|
||||
name = "Resistant Armor"
|
||||
item = "A suit of armor (requires attunement)"
|
||||
|
||||
|
||||
class ReturningWeapon(Infusion):
|
||||
"""This magic weapon grants a + 1 bonus to attack and damage rolls made
|
||||
with it, and it returns to the wielder's hand immediately after it is used
|
||||
to make a ranged attack.
|
||||
"""
|
||||
|
||||
name = "Returning Weapon"
|
||||
item = "A simple or martial weapon with the thrown property"
|
||||
@@ -79,6 +79,13 @@ def create_druid_shapes_pdf(character, basename, keep_temp_files=False, use_dnd_
|
||||
use_dnd_decorations=use_dnd_decorations)
|
||||
|
||||
|
||||
def create_infusions_pdf(character, basename, keep_temp_files=False, use_dnd_decorations=False):
|
||||
template = jinja_env.get_template('infusions_template.tex')
|
||||
return create_latex_pdf(character, basename, template,
|
||||
keep_temp_files=keep_temp_files,
|
||||
use_dnd_decorations=use_dnd_decorations)
|
||||
|
||||
|
||||
def create_spellbook_pdf(character, basename, keep_temp_files=False, use_dnd_decorations=False):
|
||||
template = jinja_env.get_template('spellbook_template.tex')
|
||||
return create_latex_pdf(character, basename, template,
|
||||
@@ -496,6 +503,19 @@ def make_sheet(character_file, character=None, flatten=False, fancy_decorations=
|
||||
f'for {character.name}')
|
||||
else:
|
||||
sheets.append(spellbook_base + '.pdf')
|
||||
#Create a list of Artificer infusions
|
||||
infusions = getattr(character, 'infusions', [])
|
||||
if len(infusions) > 0:
|
||||
infusions_base = os.path.splitext(character_file)[0] + '_infusions'
|
||||
try:
|
||||
create_infusions_pdf(character=character,
|
||||
basename=infusions_base, keep_temp_files=debug,
|
||||
use_dnd_decorations=fancy_decorations)
|
||||
except exceptions.LatexNotFoundError as e:
|
||||
log.warning('``pdflatex`` not available. Skipping infusions list '
|
||||
f'for {character.name}')
|
||||
else:
|
||||
sheets.append(infusions_base + '.pdf')
|
||||
# Create a list of Druid wild_shapes
|
||||
wild_shapes = getattr(character, 'wild_shapes', [])
|
||||
if len(wild_shapes) > 0:
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
"""This file describes the heroic adventurer Cemzack.
|
||||
|
||||
It's used primarily for saving characters from create-character,
|
||||
where there will be many missing sections.
|
||||
|
||||
Modify this file as you level up and then re-generate the character
|
||||
sheet by running ``makesheets`` from the command line.
|
||||
|
||||
"""
|
||||
|
||||
dungeonsheets_version = "0.10.1"
|
||||
|
||||
name = "Cemzack"
|
||||
player_name = ""
|
||||
|
||||
# Be sure to list Primary class first
|
||||
classes = ['Artificer'] # ex: ['Wizard'] or ['Rogue', 'Fighter']
|
||||
levels = [20] # ex: [10] or [3, 2]
|
||||
subclasses = ["Artillerist"] # ex: ['Necromacy'] or ['Thief', None]
|
||||
background = "Sailor"
|
||||
race = "Rock Gnome"
|
||||
alignment = "Neutral good"
|
||||
|
||||
xp = 0
|
||||
hp_max = 149
|
||||
inspiration = 0 # integer inspiration value
|
||||
|
||||
# Ability Scores
|
||||
strength = 13
|
||||
dexterity = 16
|
||||
constitution = 18
|
||||
intelligence = 20
|
||||
wisdom = 12
|
||||
charisma = 10
|
||||
|
||||
# Select what skills you're proficient with
|
||||
# ex: skill_proficiencies = ('athletics', 'acrobatics', 'arcana')
|
||||
skill_proficiencies = ('investigation', 'sleight of hand', 'athletics', 'perception')
|
||||
|
||||
# Any skills you have "expertise" (Bard/Rogue) in
|
||||
skill_expertise = ()
|
||||
|
||||
# Named features / feats that aren't part of your classes, race, or background.
|
||||
# Also include Eldritch Invocations and features you make multiple selection of
|
||||
# (like Maneuvers for Fighter, Metamagic for Sorcerors, Trick Shots for
|
||||
# Gunslinger, etc.)
|
||||
# Example:
|
||||
# features = ('Tavern Brawler',) # take the optional Feat from PHB
|
||||
features = ('sharpshooter')
|
||||
|
||||
# If selecting among multiple feature options: ex Fighting Style
|
||||
# Example (Fighting Style):
|
||||
# feature_choices = ('Archery',)
|
||||
feature_choices = ()
|
||||
|
||||
# Weapons/other proficiencies not given by class/race/background
|
||||
weapon_proficiencies = () # ex: ('shortsword', 'quarterstaff')
|
||||
_proficiencies_text = () # ex: ("thieves' tools",)
|
||||
|
||||
# Proficiencies and languages
|
||||
languages = """Common, Gnomish"""
|
||||
|
||||
# Inventory
|
||||
# TODO: Get yourself some money
|
||||
cp = 0
|
||||
sp = 0
|
||||
ep = 0
|
||||
gp = 0
|
||||
pp = 0
|
||||
|
||||
# TODO: Put your equipped weapons and armor here
|
||||
weapons = [] # Example: ('shortsword', 'longsword')
|
||||
magic_items = () # Example: ('ring of protection',)
|
||||
armor = "Breastplate" # Eg "leather armor"
|
||||
shield = "None" # Eg "shield"
|
||||
|
||||
equipment = """TODO: list the equipment and magic items your character carries"""
|
||||
|
||||
attacks_and_spellcasting = """TODO: Describe how your character usually attacks
|
||||
or uses spells."""
|
||||
|
||||
# List of known spells
|
||||
# Example: spells_prepared = ('magic missile', 'mage armor')
|
||||
spells_prepared = () # Todo: Learn some spells
|
||||
|
||||
# Which spells have not been prepared
|
||||
__spells_unprepared = ()
|
||||
|
||||
# all spells known
|
||||
spells = spells_prepared + __spells_unprepared
|
||||
|
||||
# Wild shapes for Druid
|
||||
wild_shapes = () # Ex: ('ape', 'wolf', 'ankylosaurus')
|
||||
|
||||
# Infusions for Artificer
|
||||
infusions = ('boots of the winding path', 'enhanced arcane focus',
|
||||
'enhanced defense', 'enhanced weapon', 'repeating shot',
|
||||
'homunculus servant', 'radiant weapon', 'replicate magic item',
|
||||
'repulsion shield', 'resistant armor', 'returning weapon')
|
||||
# Ex: ('repeating shot', 'replicate magic item')
|
||||
|
||||
# Backstory
|
||||
# Describe your backstory here
|
||||
personality_traits = """TODO: Describe how your character behaves, interacts with others"""
|
||||
|
||||
ideals = """TODO: Describe what values your character believes in."""
|
||||
|
||||
bonds = """TODO: Describe your character's commitments or ongoing quests."""
|
||||
|
||||
flaws = """TODO: Describe your character's interesting flaws."""
|
||||
|
||||
features_and_traits = """TODO: Describe other features and abilities your
|
||||
character has."""
|
||||
Reference in New Issue
Block a user