Ran flake8 and black linters, and other cleanup-related fixes.

Project now passes flake8 and black linter (also including more rst
cleanup). Moved latex related things to dedicated ``latex.py`` module,
and removed the ``makesheets -dF`` call from travis.
This commit is contained in:
Mark Wolfman
2021-04-16 11:10:17 -05:00
parent 9dfc02f3df
commit 30369ce1d4
81 changed files with 7668 additions and 4936 deletions
+120 -92
View File
@@ -8,30 +8,25 @@ class _SpecialistSpells(Feature):
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 = {3: [], 5: [], 9: [], 13: [], 17: []}
spells_known = []
spells_prepared = []
@property
def name(self):
return "{:s} Spells".format(self._name)
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)
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
@@ -52,6 +47,7 @@ class ArtificerSpellcasting(Feature):
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"
@@ -60,6 +56,7 @@ 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"
@@ -71,6 +68,7 @@ class FirearmProficiency(Feature):
your artificer has been exposed to the operation of such weapons, your
artificer is proficient with them.
"""
name = "Optional Rule: Firearm Proficiency"
source = "Artificer"
@@ -81,7 +79,7 @@ class MagicalTinkering(Feature):
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 feet.
- Whenever tapped by a creature, the object emits a recorded
@@ -105,6 +103,7 @@ class MagicalTinkering(Feature):
applies.
"""
name = "Magical Tinkering"
source = "Artificer"
@@ -113,7 +112,7 @@ 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
@@ -143,39 +142,40 @@ class InfuseItem(Feature):
of your infusions at a time. If you try to exceed your maximum
number of in­fusions, 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),
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),
}
# level: (infusions known, infused items)
2: (4, 2),
3: (4, 2),
4: (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)
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):
@@ -184,6 +184,7 @@ class ArtificerSpecialist(Feature):
class's description. Your choice grants you features at 5th level and again
at 9th and 15th level.
"""
name = "Artificer Specialist"
source = "Artificer"
@@ -196,6 +197,7 @@ class TheRightToolForTheJob(Feature):
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"
@@ -204,6 +206,7 @@ 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"
@@ -214,12 +217,13 @@ class FlashOfGenius(Feature):
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 = "Artificer"
@@ -227,13 +231,14 @@ class FlashOfGenius(Feature):
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"
@@ -245,7 +250,7 @@ class SpellStoringItem(Feature):
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
@@ -254,18 +259,20 @@ class SpellStoringItem(Feature):
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"
@@ -274,6 +281,7 @@ class MagicItemMaster(Feature):
"""Starting at 18th level, you can attune to up to six magic items at
once.
"""
name = "Magic Item Master"
source = "Artificer"
@@ -281,14 +289,15 @@ class MagicItemMaster(Feature):
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 out­right, 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"
@@ -299,6 +308,7 @@ class AlchemistToolProficiency(Feature):
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)"
@@ -309,14 +319,15 @@ class AlchemistSpells(_SpecialistSpells):
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]
}
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):
@@ -361,6 +372,7 @@ class ExperimentalElixir(Feature):
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)"
@@ -373,6 +385,7 @@ class AlchemicalSavant(Feature):
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)"
@@ -380,7 +393,7 @@ class AlchemicalSavant(Feature):
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).
@@ -389,8 +402,9 @@ class RestorativeReagents(Feature):
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)"
@@ -399,7 +413,7 @@ 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
@@ -408,8 +422,9 @@ class ChemicalMastery(Feature):
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)"
@@ -421,14 +436,15 @@ class ArtilleristSpells(_SpecialistSpells):
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]
}
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):
@@ -436,6 +452,7 @@ class ArtilleristToolProficiency(Feature):
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)"
@@ -485,6 +502,7 @@ class EldritchCannon(Feature):
number of temporary hit points equal to 1d8 + your Intelligence modifier
(minimum of +1)
"""
name = "Eldritch Cannon"
source = "Artificer (Artillerist)"
@@ -497,13 +515,14 @@ class ArcaneFirearm(Feature):
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)"
@@ -511,15 +530,16 @@ class ArcaneFirearm(Feature):
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)"
@@ -527,7 +547,7 @@ class ExplosiveCannon(Feature):
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.
@@ -536,8 +556,9 @@ class FortifiedPosition(Feature):
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)"
@@ -549,16 +570,17 @@ class BattleSmithSpells(_SpecialistSpells):
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]
}
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):
@@ -566,8 +588,9 @@ class BattleSmithToolProficiency(Feature):
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)"
@@ -575,13 +598,14 @@ class BattleSmithToolProficiency(Feature):
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)"
@@ -593,26 +617,27 @@ class SteelDefender(Feature):
steel defender stat block. You determine the creature's appearance
and whether it has two legs or four; 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)"
@@ -620,8 +645,9 @@ class SteelDefender(Feature):
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)"
@@ -631,7 +657,7 @@ class ArcaneJolt(Feature):
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,
@@ -639,8 +665,9 @@ class ArcaneJolt(Feature):
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)"
@@ -648,14 +675,15 @@ class ArcaneJolt(Feature):
class ImprovedDefender(Feature):
"""At 15th level, your Arcane jolt and steel defender be­come 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)"
+25
View File
@@ -17,6 +17,7 @@ class ShelterOfTheFaithful(Feature):
hazardous and you remain in good standing with your temple.
"""
name = "Shelter of the Faithful"
source = "Background (Acolyte)"
@@ -29,6 +30,7 @@ class FalseIdentity(Feature):
document or the handwriting you are trying to copy.
"""
name = "False Identity"
source = "Background (Charlattan)"
@@ -41,6 +43,7 @@ class CriminalContact(Feature):
messages for you.
"""
name = "Criminal Contact"
source = "Background (Criminal)"
@@ -55,6 +58,7 @@ class ByPopularDemand(Feature):
performed, they typically take a liking to you.
"""
name = "By Popular Demand"
source = "Background (Entertainer)"
@@ -67,6 +71,7 @@ class RusticHospitality(Feature):
not risk their lives for you.
"""
name = "Rustic Hospitality"
source = "Background (Folk Hero)"
@@ -90,6 +95,7 @@ class GuildMembership(Feature):
must make up back dues to remain in the guild's good graces.
"""
name = "Guild Membership"
source = "Background (Guild Artisan)"
@@ -109,6 +115,7 @@ class Discovery(Feature):
your discovery and its impact on the campaign.
"""
name = "Discovery"
source = "Background (Hermit)"
@@ -122,6 +129,7 @@ class PositionOfPrivilege(Feature):
noble if you need to.
"""
name = "Position of Privilege"
source = "Background (Noble)"
@@ -134,6 +142,7 @@ class Wanderer(Feature):
small game, water, and so forth.
"""
name = "Wanderer"
source = "Background (Outlander)"
@@ -147,6 +156,7 @@ class Researcher(Feature):
place, or that it simply cannot be found. Unearthing the deepest secrets of
the multiverse can require an adventure or even a whole campaign.
"""
name = "Researcher"
source = "Background (Sage)"
@@ -162,6 +172,7 @@ class ShipsPassage(Feature):
expected to assist the crew during the voyage
"""
name = "Ship's Passage"
source = "Background (Sailor)"
@@ -176,6 +187,7 @@ class MilitaryRank(Feature):
recognized.
"""
name = "Military Rank"
source = "Background (Soldier)"
@@ -187,6 +199,7 @@ class CitySecrets(Feature):
in the city twice as fast as your speed would normally allow.
"""
name = "City Secrets"
source = "Background (Urchin)"
@@ -205,6 +218,7 @@ class AllEyesOnYou(Feature):
hearing about your distant homeland and people.
"""
name = "All Eyes on You"
source = "Background (Far Traveler)"
@@ -218,6 +232,7 @@ class EarToTheGround(Feature):
the local area.
"""
name = "Ear to the Ground"
source = "Background (Urban Bounty Hunter)"
@@ -230,6 +245,7 @@ class WatchersEye(Feature):
likely to be welcome in the former locations rather than the latter.
"""
name = "Watcher's Eye"
source = "Background (City Watch)"
@@ -242,6 +258,7 @@ class RespectOfTheStoutFolk(Feature):
(and possibly your compatriots) the finest accommodations and assistance.
"""
name = "Respect of the Stout Folk"
source = "Background (Clan Crafter)"
@@ -261,6 +278,7 @@ class LibraryAccess(Feature):
scholar.
"""
name = "Library Access"
source = "Background (Cloistered Scholar)"
@@ -273,6 +291,7 @@ class CourtFunctionary(Feature):
are.
"""
name = "Court Functionary"
source = "Background (Courtier)"
@@ -286,6 +305,7 @@ class SafeHaven(Feature):
for you or risk revealing their true identities.
"""
name = "Save Haven"
source = "Background (Faction Agent)"
@@ -313,6 +333,7 @@ class Inheritance(Feature):
until you learn more about what it means to you and what it can do for you.
"""
name = "Inheritance"
source = "Background (Inheritor)"
@@ -333,6 +354,7 @@ class KnightlyRegard(Feature):
he or she is being hunted unjustly.
"""
name = "Knightly Regard"
source = "Background (Knight of the Order)"
@@ -349,6 +371,7 @@ class MercenaryLife(Feature):
Handbook).
"""
name = "Mercenary Life"
source = "Background (Mercenary Veteran)"
@@ -365,6 +388,7 @@ class UthgardtHeritage(Feature):
gods of the First Circle.
"""
name = "Uthgardt Heritage"
source = "Background (Uthgardt Tribe Member)"
@@ -383,5 +407,6 @@ class KeptInStyle(Feature):
actual monetary reward.
"""
name = "Kept in Style"
source = "Background (Waterdhavian Noble)"
+121 -60
View File
@@ -1,4 +1,3 @@
from dungeonsheets import armor, weapons
from dungeonsheets.features.features import Feature, FeatureSelector
@@ -7,7 +6,7 @@ class Rage(Feature):
"""In battle, you fight with primal ferocity. On your turn, you can enter a
rage as a bonus action. While raging, you gain the following benefits if
you aren't wearing heavy armor:
- You have advantage on Strength checks and Strength saving
throws.
- When you make a melee weapon attack using Strength, you gain a
@@ -16,7 +15,7 @@ class Rage(Feature):
table.
- You have resistance to bludgeoning, piercing, and slashing
damage.
If you are able to cast spells, you can't cast them or concentrate on them
while raging. Your rage lasts for 1 minute. It ends early if you are
knocked unconscious or if your turn ends and you haven't attacked a hostile
@@ -24,31 +23,32 @@ class Rage(Feature):
your rage on your turn as a bonus action. Once you have raged the number of
times shown for your barbarian level in the Rages column of the Barbarian
table, you must finish a long rest before you can rage again
"""
_name = "Rage"
source = "Barbarian"
@property
def name(self):
level = self.owner.Barbarian.level
num = 2
if level >= 3:
num = 3
if level >= 6:
num = 4
if level >= 12:
num = 5
if level >= 17:
num = 6
if level >= 20:
num = 100
damage = '+2'
if level >= 9:
damage = "+3"
if level >= 16:
damage = "+4"
return self._name + " ({:s}, {:d}x/LR)".format(damage, num)
level = self.owner.Barbarian.level
num = 2
if level >= 3:
num = 3
if level >= 6:
num = 4
if level >= 12:
num = 5
if level >= 17:
num = 6
if level >= 20:
num = 100
damage = "+2"
if level >= 9:
damage = "+3"
if level >= 16:
damage = "+4"
return self._name + " ({:s}, {:d}x/LR)".format(damage, num)
class UnarmoredDefenseBarbarian(Feature):
@@ -59,8 +59,9 @@ class UnarmoredDefenseBarbarian(Feature):
This bonus is computed in the AC given on the Character Sheet above.
"""
name = "Unarmored Defense"
source = 'Barbarian'
source = "Barbarian"
class RecklessAttack(Feature):
@@ -71,6 +72,7 @@ class RecklessAttack(Feature):
against you have advantage until your next turn
"""
name = "Reckless Attack"
source = "Barbarian"
@@ -83,6 +85,7 @@ class DangerSense(Feature):
deafened, or incapacitated.
"""
name = "Danger Sense"
source = "Barbarian"
@@ -92,6 +95,7 @@ class ExtraAttackBarbarian(Feature):
take the Attack action on your turn.
"""
name = "Extra Attack (2x)"
source = "Barbarian"
@@ -101,6 +105,7 @@ class FastMovement(Feature):
wearing heavy armor.
"""
name = "Fast Movement"
source = "Barbarian"
@@ -112,6 +117,7 @@ class FeralInstinct(Feature):
but only if you enter your rage before doing anything else on that turn.
"""
name = "Feral Instinct"
source = "Barbarian"
@@ -123,6 +129,7 @@ class BrutalCritical(Feature):
17th level.
"""
name = "Brutal Critical"
source = "Barbarian"
@@ -136,6 +143,7 @@ class RelentlessRage(Feature):
resets to 10.
"""
name = "Relentless Rage"
source = "Barbarian"
@@ -145,6 +153,7 @@ class PersistentRage(Feature):
you fall unconscious or if you choose to end it.
"""
name = "Persistent Rage"
source = "Barbarian"
@@ -154,6 +163,7 @@ class IndomitableMight(Feature):
your Strength score, you can use that score in place of the total.
"""
name = "Indomitable Might"
source = "Barbarian"
@@ -163,6 +173,7 @@ class PrimalChampion(Feature):
Constitution scores increase by 4. Your maximum for those scores is now 24.
"""
name = "Primal Champion"
source = "Barbarian"
@@ -176,6 +187,7 @@ class Frenzy(Feature):
described in appendix A)
"""
name = "Frenzy"
source = "Barbarian (Berserker)"
@@ -186,6 +198,7 @@ class MindlessRage(Feature):
suspended for the duration of the rage.
"""
name = "Mindless Rage"
source = "Barbarian (Berserker)"
@@ -203,6 +216,7 @@ class IntimidatingPresence(Feature):
throw, you can't use this feature on that creature again for 24 hours.
"""
name = "Intimidating Presence"
source = "Barbarian (Berserker)"
@@ -213,6 +227,7 @@ class Retaliation(Feature):
against that creature.
"""
name = "Retaliation"
source = "Barbarian (Berserker)"
@@ -225,6 +240,7 @@ class SpiritSeeker(Feature):
rituals, as described in chapter 10 of PHB.
"""
name = "Spirit Seeker"
source = "Barbarian (Totem Warrior)"
@@ -234,6 +250,7 @@ class BearSpirit(Feature):
spirit of the bear makes you tough enough to stand up to any punishment.
"""
name = "Totem Spirit (Bear)"
source = "Barbarian (Totem Warrior)"
@@ -245,6 +262,7 @@ class EagleSpirit(Feature):
you into a predator who can weave through the fray with ease.
"""
name = "Totem Spirit (Eagle)"
source = "Barbarian (Totem Warrior)"
@@ -255,6 +273,7 @@ class WolfSpirit(Feature):
spirit of the wolf makes you a leader of hunters
"""
name = "Totem Spirit (Wolf)"
source = "Barbarian (Totem Warrior)"
@@ -264,6 +283,7 @@ class ElkSpirit(Feature):
increases by 15 feet. The spirit of the elk makes you extraordinarily swift
"""
name = "Totem Spirit (Elk)"
source = "Barbarian (Totem Warrior)"
@@ -273,6 +293,7 @@ class TigerSpirit(Feature):
your high jump distance. The spirit of the tiger empowers your leaps
"""
name = "Totem Spirit (Tiger)"
source = "Barbarian (Totem Warrior)"
@@ -293,11 +314,14 @@ class TotemSpirit(FeatureSelector):
tiger spirit
"""
options = {'bear spirit': BearSpirit,
'eagle spirit': EagleSpirit,
'wolf spirit': WolfSpirit,
'elk spirit': ElkSpirit,
'tiger spirit': TigerSpirit}
options = {
"bear spirit": BearSpirit,
"eagle spirit": EagleSpirit,
"wolf spirit": WolfSpirit,
"elk spirit": ElkSpirit,
"tiger spirit": TigerSpirit,
}
name = "Totem Spirit (Select One)"
source = "Barbarian (Totem Warrior)"
@@ -306,8 +330,9 @@ class BearAspect(FeatureSelector):
"""You gain the might of a bear. Your carrying capacity (including
maximum load and maximum lift) is doubled, and you have advantage
on Strength checks made to push, pull, lift, or break objects.
"""
name = "Aspect of the Beast (Bear)"
source = "Barbarian (Totem Warrior)"
@@ -319,6 +344,7 @@ class EagleAspect(FeatureSelector):
doesn't impose disadvantage on your Wisdom (Perception) checks.
"""
name = "Aspect of the Beast (Eagle)"
source = "Barbarian (Totem Warrior)"
@@ -329,6 +355,7 @@ class WolfAspect(FeatureSelector):
at a normal pace (see chapter 8 for rules on travel pace).
"""
name = "Aspect of the Beast (Wolf)"
source = "Barbarian (Totem Warrior)"
@@ -340,6 +367,7 @@ class ElkAspect(FeatureSelector):
information about travel pace). The elk spirit helps you roam far and fast
"""
name = "Aspect of the Beast (Elk)"
source = "Barbarian (Totem Warrior)"
@@ -350,6 +378,7 @@ class TigerAspect(FeatureSelector):
instincts
"""
name = "Aspect of the Beast (Tiger)"
source = "Barbarian (Totem Warrior)"
@@ -369,11 +398,14 @@ class BeastAspect(FeatureSelector):
tiger aspect
"""
options = {'bear aspect': BearAspect,
'eagle aspect': EagleAspect,
'wolf aspect': WolfAspect,
'elk aspect': ElkAspect,
'tiger aspect': TigerAspect}
options = {
"bear aspect": BearAspect,
"eagle aspect": EagleAspect,
"wolf aspect": WolfAspect,
"elk aspect": ElkAspect,
"tiger aspect": TigerAspect,
}
name = "Aspect of the Beast (Select One)"
source = "Barbarian (Totem Warrior)"
@@ -385,6 +417,7 @@ class SpiritWalker(Feature):
information you seek.
"""
name = "Spirit Walker"
source = "Barbarian (Totem Warrior)"
@@ -396,6 +429,7 @@ class BearAttunement(Feature):
it can't see or hear you or if it can't be frightened.
"""
name = "Totemic Attunement (Bear)"
source = "Barbarian (Totem Warrior)"
@@ -406,6 +440,7 @@ class EagleAttunement(Feature):
turn in the air and nothing else is holding you aloft.
"""
name = "Totemic Attunement (Eagle)"
source = "Barbarian (Totem Warrior)"
@@ -415,6 +450,7 @@ class WolfAttunement(Feature):
a Large or smaller creature prone when you hit it with melee weapon attack.
"""
name = "Totemic Attunement (Wolf)"
source = "Barbarian (Totem Warrior)"
@@ -427,6 +463,7 @@ class ElkAttunement(Feature):
Strength modifier
"""
name = "Totemic Attunement (Elk)"
source = "Barbarian (Totem Warrior)"
@@ -438,6 +475,7 @@ class TigerAttunement(Feature):
against it
"""
name = "Totemic Attunement (Tiger)"
source = "Barbarian (Totem Warrior)"
@@ -457,11 +495,14 @@ class TotemicAttunement(FeatureSelector):
tiger attunement
"""
options = {'bear attunement': BearAttunement,
'eagle attunement': EagleAttunement,
'wolf attunement': WolfAttunement,
'elk attunement': ElkAttunement,
'tiger attunement': TigerAttunement}
options = {
"bear attunement": BearAttunement,
"eagle attunement": EagleAttunement,
"wolf attunement": WolfAttunement,
"elk attunement": ElkAttunement,
"tiger attunement": TigerAttunement,
}
name = "Totemic Attunement (Select One)"
source = "Barbarian (Totem Warrior)"
@@ -478,7 +519,8 @@ class BattleragerArmor(Feature):
piercing damage if your grapple check succeeds.
"""
name = 'Battlerager Armor'
name = "Battlerager Armor"
source = "Barbarian (Battlerager)"
@@ -488,6 +530,7 @@ class RecklessAbandon(Feature):
1). They vanish if any of them are left when your rage ends .
"""
name = "Reckless Abandon"
source = "Barbarian (Battlerager)"
@@ -497,6 +540,7 @@ class BattleragerCharge(Feature):
while you are raging.
"""
name = "Battlerager Charge"
source = "Barbarian (Battlerager)"
@@ -507,6 +551,7 @@ class SpikedRetribution(Feature):
aren't incapacitated, and are wearing spiked armor.
"""
name = "Spiked Retribution"
source = "Barbarian (Battlerager)"
@@ -523,6 +568,7 @@ class AncestralProtectors(Feature):
ifyour rage ends
"""
name = "Ancestral Protectors"
source = "Barbarian (Ancestral Guardian)"
@@ -537,18 +583,19 @@ class SpiritShield(Feature):
more: by 3d6 at 10th level and by 4d6 at 14th level.
"""
_name = "Spirit Shield"
source = "Barbarian (Ancestral Guardian)"
@property
def name(self):
level = self.owner.Barbarian.level
damage = " (2d6)"
if level >= 10:
damage = " (3d6)"
if level >= 14:
damage = " (4d6)"
return self._name + damage
level = self.owner.Barbarian.level
damage = " (2d6)"
if level >= 10:
damage = " (3d6)"
if level >= 14:
damage = " (4d6)"
return self._name + damage
class ConsultTheSpirits(Feature):
@@ -561,6 +608,7 @@ class ConsultTheSpirits(Feature):
feature again until you finish a short or long rest
"""
name = "Consult the Spirits"
source = "Barbarian (Ancestral Guardian)"
@@ -572,6 +620,7 @@ class VengefulAncestors(Feature):
that your Spirit Shield prevents.
"""
name = "Vengeful Ancestors"
source = "Barbarian (Ancestral Guardian)"
@@ -596,6 +645,7 @@ class DesertAura(Feature):
15th level, and 6 at 20th level.
"""
name = "Storm Aura (Desert)"
source = "Barbarian (Storm Herald)"
@@ -621,6 +671,7 @@ class SeaAura(Feature):
level, and 4d6 at 20th level.
"""
name = "Storm Aura (Sea)"
source = "Barbarian (Storm Herald)"
@@ -645,6 +696,7 @@ class TundraAura(Feature):
level, and 6 at 20th level.
"""
name = "Storm Aura (Tundra)"
source = "Barbarian (Storm Herald)"
@@ -660,9 +712,8 @@ class StormAura(FeatureSelector):
tundra
"""
options = {'desert': DesertAura,
'sea': SeaAura,
'tundra': TundraAura}
options = {"desert": DesertAura, "sea": SeaAura, "tundra": TundraAura}
name = "Storm Aura (Select One)"
source = "Barbarian (Storm Herald)"
@@ -678,6 +729,7 @@ class DesertSoul(Feature):
being worn or carried by anyone else and set it on fire
"""
name = "Storm Soul (Desert)"
source = "Barbarian (Storm Herald)"
@@ -690,6 +742,7 @@ class SeaSoul(Feature):
**Sea**: You gain resistance to lightning damage, and
you can breathe underwater. You also gain a swimming speed of 30 feet.
"""
name = "Storm Soul (Sea)"
source = "Barbarian (Storm Herald)"
@@ -705,6 +758,7 @@ class TundraSoul(Feature):
Of it into ice, which melts after 1 minute. This action fails if a creature
is in the cube
"""
name = "Storm Soul (Tundra)"
source = "Barbarian (Storm Herald)"
@@ -720,9 +774,8 @@ class StormSoul(FeatureSelector):
tundra
"""
options = {'desert': DesertSoul,
'sea': SeaSoul,
'tundra': TundraSoul}
options = {"desert": DesertSoul, "sea": SeaSoul, "tundra": TundraSoul}
name = "Storm Soul (Select One)"
source = "Barbarian (Storm Herald)"
@@ -733,6 +786,7 @@ class ShieldingStorm(Feature):
from the Storm Soul fea ture while the creature is in your Storm Aura.
"""
name = "Shielding Storm"
source = "Barbarian (Storm Herald)"
@@ -748,6 +802,7 @@ class RagingDesert(Feature):
equal to half your barbarian level.
"""
name = "Raging Storm (Desert)"
source = "Barbarian (Storm Herald)"
@@ -762,6 +817,7 @@ class RagingSea(Feature):
failed save, the creature is knocked prone, as if struck by a wave.
"""
name = "Raging Storm (Sea)"
source = "Barbarian (Storm Herald)"
@@ -777,6 +833,7 @@ class RagingTundra(Feature):
your next turn, as magical frost covers it
"""
name = "Raging Storm (Tundra)"
source = "Barbarian (Storm Herald)"
@@ -792,9 +849,8 @@ class RagingStorm(FeatureSelector):
tundra
"""
options = {'desert': RagingDesert,
'sea': RagingSea,
'tundra': RagingTundra}
options = {"desert": RagingDesert, "sea": RagingSea, "tundra": RagingTundra}
name = "Raging Storm (Select One)"
source = "Barbarian (Storm Herald)"
@@ -808,14 +864,15 @@ class DivineFury(Feature):
you choose the type of damage when you gain this feature.
"""
_name = "Divine Fury"
source = "Barbarian (Zealot)"
@property
def name(self):
level = self.owner.Barbarian.level
damage = " (1d6+{:d})".format(level//2)
return self._name + damage
level = self.owner.Barbarian.level
damage = " (1d6+{:d})".format(level // 2)
return self._name + damage
class WarriorOfTheGods(Feature):
@@ -825,6 +882,7 @@ class WarriorOfTheGods(Feature):
on you
"""
name = "Warrior of the Gods"
source = "Barbarian (Zealot)"
@@ -834,6 +892,7 @@ class FanaticalFocus(Feature):
you. If you fail a saving throw while you're raging, you can reroll it, and
you must use the new roll. You can use this ability only once per rage.
"""
name = "Fanatical Focus"
source = "Barbarian (Zealot)"
@@ -847,6 +906,7 @@ class ZealousPresence(Feature):
until you finish a long rest
"""
name = "Zealous Presence"
source = "Barbarian (Zealot)"
@@ -860,5 +920,6 @@ class RageBeyondDeath(Feature):
your rage ends, and you die then only if you still have 0 hit points.
"""
name = "Rage Beyond Death"
source = "Barbarian (Zealot)"
+67 -38
View File
@@ -26,24 +26,25 @@ class BardicInspiration(Feature):
at 15th level.
"""
_name = "Bardic Inspiration"
source = "Bard"
@property
def name(self):
level = self.owner.Bard.level
die = 'd6'
if level >= 5:
die = 'd8'
if level >= 10:
die = 'd10'
if level >= 15:
die = 'd12'
num = max(1, self.owner.charisma.modifier)
rest = 'LR'
if level >= 5: # font of inspiration
rest = 'SR'
return self._name + " ({:d}{:s}/{:s})".format(num, die, rest)
level = self.owner.Bard.level
die = "d6"
if level >= 5:
die = "d8"
if level >= 10:
die = "d10"
if level >= 15:
die = "d12"
num = max(1, self.owner.charisma.modifier)
rest = "LR"
if level >= 5: # font of inspiration
rest = "SR"
return self._name + " ({:d}{:s}/{:s})".format(num, die, rest)
class JackOfAllTrades(Feature):
@@ -52,6 +53,7 @@ class JackOfAllTrades(Feature):
proficiency bonus. (Included in stats on Character Sheet above).
"""
name = "Jack of All Trades"
source = "Bard"
@@ -65,20 +67,21 @@ class SongOfRest(Feature):
1d8 at 9th level, to 1d10 at 13th level, and to 1d12 at 17th level.
"""
_name = "Song of Rest"
source = "Bard"
@property
def name(self):
level = self.owner.Bard.level
die = ' (1d6)'
if level >= 9:
die = ' (1d8)'
if level >= 13:
die = ' (1d10)'
if level >= 17:
die = ' (1d12)'
return self._name + die
level = self.owner.Bard.level
die = " (1d6)"
if level >= 9:
die = " (1d8)"
if level >= 13:
die = " (1d10)"
if level >= 17:
die = " (1d12)"
return self._name + die
class BardExpertise(Feature):
@@ -90,6 +93,7 @@ class BardExpertise(Feature):
Add these skills to "skill_expertise" in your character.py file
"""
name = "Expertise"
source = "Bard"
@@ -99,6 +103,7 @@ class FontOfInspiration(Feature):
Bardic Inspiration when you finish a short or long rest.
"""
name = "Font of Inspiration"
source = "Bard"
@@ -114,6 +119,7 @@ class Countercharm(Feature):
required).
"""
name = "Countercharm"
source = "Bard"
@@ -127,6 +133,7 @@ class MagicalSecrets(Feature):
additional spells from any class at 14th level and again at 18th level.
"""
name = "Magical Secrets"
source = "Bard"
@@ -136,6 +143,7 @@ class SuperiorInspiration(Feature):
Inspiration left, you regain one use.
"""
name = "Superior Inspiration"
source = "Bard"
@@ -146,6 +154,7 @@ class LoreProficiencies(Feature):
three skills o f your choice.
"""
name = "Bonus Proficiencies"
source = "Bard (College of Lore)"
@@ -163,6 +172,7 @@ class CuttingWords(Feature):
immune to being charmed.
"""
name = "Cutting Words"
source = "Bard (College of Lore)"
@@ -174,6 +184,7 @@ class AdditionalMagicalSecrets(Feature):
against the number of bard spells you know.
"""
name = "Additional Magical Secrets"
source = "Bard (College of Lore)"
@@ -186,6 +197,7 @@ class PeerlessSkill(Feature):
or fail
"""
name = "Peerless Skill"
source = "Bard (College of Lore)"
@@ -200,6 +212,7 @@ class CombatInspiration(Feature):
attack, after seeing the roll but before knowing whether it hits or misses
"""
name = "Combat Inspiration"
source = "Bard (College of Valor)"
@@ -209,6 +222,7 @@ class BardExtraAttack(Feature):
take the Attack action on your turn
"""
name = "Extra Attack (x2)"
source = "Bard (College of Valor)"
@@ -219,6 +233,7 @@ class BardBattleMagic(Feature):
spell, you can make one weapon attack as a bonus action
"""
name = "Battle Magic"
source = "Bard (College of Valor)"
@@ -238,14 +253,15 @@ class MantleOfInspiration(Feature):
5th level, 11 at 10th level, and 14 at 15th level.
"""
_name = "Mantle of Inspiration"
source = "Bard (College of Glamour)"
@property
def name(self):
level = self.owner.Bard.level
hp = 5 + 3*(level // 5)
return self._name + " ({:d}HP)".format(hp)
level = self.owner.Bard.level
hp = 5 + 3 * (level // 5)
return self._name + " ({:d}HP)".format(hp)
class EnthrallingPerformance(Feature):
@@ -267,6 +283,7 @@ class EnthrallingPerformance(Feature):
you finish a short or long rest
"""
name = "Enthralling Performance"
source = "Bard (College of Glamour)"
@@ -284,6 +301,7 @@ class MantleOfMajesty(Feature):
can't use it again until you finish a long rest
"""
name = "Mantle of Majesty"
source = "Bard (College of Glamour)"
@@ -304,6 +322,7 @@ class UnbreakableMajesty(Feature):
you finish a short or long rest.
"""
name = "Unbreakable Majesty"
source = "Bard (College of Glamour)"
@@ -316,6 +335,7 @@ class SwordsProficiency(Feature):
spells
"""
name = "Bonus Proficiencies"
source = "Bard (College of Swords)"
@@ -328,10 +348,13 @@ class BardFightingStyle(FeatureSelector):
two-weapon fighting
"""
options = {'dueling': Dueling,
'two-weapon fighting': TwoWeaponFighting,
'two-weapon': TwoWeaponFighting,
'dual wield': TwoWeaponFighting}
options = {
"dueling": Dueling,
"two-weapon fighting": TwoWeaponFighting,
"two-weapon": TwoWeaponFighting,
"dual wield": TwoWeaponFighting,
}
name = "Fighting Style (Select One)"
source = "Bard (College of Swords)"
@@ -363,6 +386,7 @@ class BladeFlourish(Feature):
target.
"""
name = "Blade Flourish"
source = "Bard (College of Swords)"
@@ -371,6 +395,7 @@ class MastersFlourish(Feature):
"""Starting at 14th level, whenever you use a Blade Flourish option, you can
roll a d6 and use it instead of expend- ing a Bardic Inspiration die.
"""
name = "Master's Flourish"
source = "Bard (College of Swords)"
@@ -386,20 +411,21 @@ class PsychicBlades(Feature):
at 10th level, and 8d6 at 15th level.
"""
_name = "Psychic Blades"
source = "Bard (College of Whispers)"
@property
def name(self):
level = self.owner.Bard.level
dice = ' (2d6)'
if level >= 5:
dice = ' (3d6)'
if level >= 10:
dice = ' (5d6)'
if level >= 15:
dice = ' (8d6)'
return self._name + dice
level = self.owner.Bard.level
dice = " (2d6)"
if level >= 5:
dice = " (3d6)"
if level >= 10:
dice = " (5d6)"
if level >= 15:
dice = " (8d6)"
return self._name + dice
class WordsOfTerror(Feature):
@@ -417,6 +443,7 @@ class WordsOfTerror(Feature):
until you finish a short or long rest.
"""
name = "Words of Terror"
source = "Bard (College of Whispers)"
@@ -441,6 +468,7 @@ class MantleOfWhispers(Feature):
until you finish a short or long rest.
"""
name = "Mantle of Whispers"
source = "Bard (College of Whispers)"
@@ -466,5 +494,6 @@ class ShadowLore(Feature):
feature, you can't use it again until / you finish a long rest.
"""
name = "Shadow Lore"
source = "Bard (College of Whispers)"
+99 -36
View File
@@ -21,18 +21,19 @@ class ChannelDivinity(Feature):
rests. When you finish a short or long rest, you regain your expended uses.
"""
_name = "Channel Divinity"
source = "Cleric"
@property
def name(self):
level = self.owner.Cleric.level
if level < 6:
return "Channel Divinity (1x/SR)"
elif level < 18:
return "Channel Divinity (2x/SR)"
else:
return "Channel Divinity (3x/SR)"
level = self.owner.Cleric.level
if level < 6:
return "Channel Divinity (1x/SR)"
elif level < 18:
return "Channel Divinity (2x/SR)"
else:
return "Channel Divinity (3x/SR)"
class TurnUndead(Feature):
@@ -48,6 +49,7 @@ class TurnUndead(Feature):
nowhere to move, the creature can use the Dodge action.
"""
name = "Channel Divinity: Turn Undead"
source = "Cleric"
@@ -59,22 +61,23 @@ class DestroyUndead(Feature):
table.
"""
_name = "Destroy Undead"
source = "Cleric"
@property
def name(self):
level = self.owner.Cleric.level
name = self._name + ' (CR 1/2)'
if level >= 8:
name = self._name + ' (CR 1)'
if level >= 11:
name = self._name + ' (CR 2)'
if level >= 14:
name = self._name + ' (CR 3)'
if level >= 17:
name = self._name + ' (CR 4)'
return name
level = self.owner.Cleric.level
name = self._name + " (CR 1/2)"
if level >= 8:
name = self._name + " (CR 1)"
if level >= 11:
name = self._name + " (CR 2)"
if level >= 14:
name = self._name + " (CR 3)"
if level >= 17:
name = self._name + " (CR 4)"
return name
class DivineIntervention(Feature):
@@ -94,6 +97,7 @@ class DivineIntervention(Feature):
required.
"""
name = "Divine Intervention"
source = "Cleric"
@@ -102,16 +106,17 @@ class DivineStrike(Feature):
"""
Generic Divine Strike
"""
_name = "Divine Strike"
source = "Cleric"
@property
def name(self):
level = self.owner.Cleric.level
damage = ' (1d8)'
if level >= 14:
damage = ' (2d8)'
return self._name + damage
level = self.owner.Cleric.level
damage = " (1d8)"
if level >= 14:
damage = " (2d8)"
return self._name + damage
# Knowledge Domain
@@ -122,6 +127,7 @@ class BlessingsOfKnowledge(Feature):
check you make that uses either of those skills.
"""
name = "Blessings of Knowledge"
source = "Cleric (Knowledge Domain)"
@@ -132,6 +138,7 @@ class KnowledgeOfTheAncients(DivineIntervention):
10 minutes, you have proficiency with the chosen skill or tool.
"""
name = "Divine Intervention: Knowledge of the Ancients"
source = "Cleric (Knowledge Domain)"
@@ -153,6 +160,7 @@ class ReadThoughts(DivineIntervention):
spell.
"""
name = "Divine Intervention: Read Thoughts"
source = "Cleric (Knowledge Domain)"
@@ -162,6 +170,7 @@ class PotentSpellcasting(Feature):
with any cleric cantrip.
"""
name = "Potent Spellcasting"
source = "Cleric"
@@ -193,6 +202,7 @@ class VisionsOfThePast(Feature):
nevertheless important in your current situation.
"""
name = "Visions of the Past"
source = "Cleric (Knowledge Domain)"
@@ -205,6 +215,7 @@ class DiscipleOfLife(Feature):
+ the spell's level
"""
name = "Disciple of Life"
source = "Cleric (Life Domain)"
@@ -219,6 +230,7 @@ class PreserveLife(ChannelDivinity):
construct.
"""
name = "Channel Divinity: Preserve Life"
source = "Cleric (Life Domain)"
@@ -230,6 +242,7 @@ class BlessedHealer(Feature):
spell's level.
"""
name = "Blessed Healer"
source = "Cleric (Life Domain)"
@@ -242,6 +255,7 @@ class DivineStrikeLife(DivineStrike):
2d8.
"""
source = "Cleric (Life Domain)"
@@ -252,6 +266,7 @@ class SupremeHealing(Feature):
a creature, you restore 12.
"""
name = "Supreme Healing"
source = "Cleric (Life Domain)"
@@ -267,13 +282,14 @@ class WardingFlare(Feature):
minimum of once). You regain all expended uses when you finish a long rest
"""
_name = "Warding Flare"
source = "Cleric (Light Domain)"
@property
def name(self):
times = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(times)
times = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(times)
class RadianceOfTheDawn(ChannelDivinity):
@@ -288,6 +304,7 @@ class RadianceOfTheDawn(ChannelDivinity):
successful one. A creature that has total cover from you is not affected.
"""
name = "Channel Divinity: Radiance of the Dawn"
source = "Cleric (Light Domain)"
@@ -298,6 +315,7 @@ class ImprovedFlare(Feature):
than you.
"""
name = "Improved Flare"
source = "Cleric (Light Domain)"
@@ -310,6 +328,7 @@ class CoronaOfLight(Feature):
throws against any spell that deals fire or radiant damage
"""
name = "Corona of Light"
source = "Cleric (Light Domain)"
@@ -321,6 +340,7 @@ class AcolyteOfNature(Feature):
Nature, or Survival.
"""
name = "Acolyte of Nature"
source = "Cleric (Nature Domain)"
@@ -336,6 +356,7 @@ class CharmAnimalsAndPlants(ChannelDivinity):
and other creatures you designate.
"""
name = "Channel Divinity: Charm Animals and Plants"
source = "Cleric (Nature Domain)"
@@ -346,6 +367,7 @@ class DampenElements(Feature):
to grant resistance to the creature against that instance of the damage.
"""
name = "Dampen Elements"
source = "Cleric (Nature Domain)"
@@ -358,6 +380,7 @@ class DivineStrikeNature(DivineStrike):
the extra damage increases to 2d8.
"""
source = "Cleric (Nature Domain)"
@@ -368,6 +391,7 @@ class MasterOfNature(Feature):
each of those creatures will do on its next turn.
"""
name = "Master of Nature"
source = "Cleric (Nature Domain)"
@@ -384,13 +408,14 @@ class WrathOfTheStorm(Feature):
minimum of once). You regain all expended uses when you finish a long rest.
"""
_name = "Wrath of the Storm"
source = "Cleric (Tempest Domain)"
@property
def name(self):
num_uses = max(1, self.owner.wisdom.modifier)
return self._name + ' ({:d}x/LR)'.format(num_uses)
num_uses = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(num_uses)
class DestructiveWrath(ChannelDivinity):
@@ -401,6 +426,7 @@ class DestructiveWrath(ChannelDivinity):
Divinity to deal maximum damage, instead of rolling.
"""
name = "Channel Divinity: Destructive Wrath"
source = "Cleric (Tempest Domain)"
@@ -410,6 +436,7 @@ class ThunderboltStrike(Feature):
creature, you can also push it up to 10 feet away from you.
"""
name = "Thunderbolt Strike"
source = "Cleric (Tempest Domain)"
@@ -422,6 +449,7 @@ class DivineStrikeTempest(DivineStrike):
2d8.
"""
source = "Cleric (Tempest Domain)"
@@ -430,6 +458,7 @@ class Stormborn(Feature):
whenever you are not underground or indoors.
"""
name = "Stormborn"
source = "Cleric (Tempest Domain)"
@@ -442,6 +471,7 @@ class BlessingOfTheTrickster(Feature):
this feature again
"""
name = "Blessing of the Trickster"
source = "Cleric (Trickery Domain)"
@@ -462,6 +492,7 @@ class InvokeDuplicity(ChannelDivinity):
distracting the illusion is to the target.
"""
name = "Channel Divinity: Invoke Duplicity"
source = "Cleric (Trickery Domain)"
@@ -472,6 +503,7 @@ class CloakOfShadows(ChannelDivinity):
visible if you attack or cast a spell.
"""
name = "Channel Divinity: Cloak of Shadows"
source = "Cleric (Trickery Domain)"
@@ -484,6 +516,7 @@ class DivineStrikeTrickery(DivineStrike):
damage increases to 2d8.
"""
source = "Cleric (Trickery Domain)"
@@ -493,6 +526,7 @@ class ImprovedDuplicity(Feature):
move any number of them up to 30 feet, to a maximum range of 120 feet.
"""
name = "Improved Duplicity"
source = "Cleric (Trickery Domain)"
@@ -506,13 +540,14 @@ class WarPriest(Feature):
when you finish a long rest
"""
_name = "War Priest"
source = "Cleric (War Domain)"
@property
def name(self):
num = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(num)
num = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(num)
class GuidedStrike(ChannelDivinity):
@@ -523,6 +558,7 @@ class GuidedStrike(ChannelDivinity):
misses
"""
name = "Channel Divinity: Guided Strike"
source = "Cleric (War Domain)"
@@ -534,6 +570,7 @@ class WarGodsBlessing(ChannelDivinity):
but before the DM says whether the attack hits or misses.
"""
name = "Channel Divinity: War Gods Blessing"
source = "Cleric (War Domain)"
@@ -545,6 +582,7 @@ class DivineStrikeWar(DivineStrike):
same type dealt by the weapon to the target. When you reach 14th level, the
extra damage increases to 2d8.
"""
source = "Cleric (War Domain)"
@@ -553,6 +591,7 @@ class AvatarOfBattle(Feature):
damage from nonmagical weapons.
"""
name = "Avatar of Battle"
source = "Cleric (War Domain)"
@@ -564,6 +603,7 @@ class ArcaneInitiate(Feature):
spell list. For you, these cantrips count as cleric cantrips
"""
name = "Arcane Initiate"
source = "Cleric (Arcana Domain)"
@@ -595,6 +635,7 @@ class ArcaneAbjuration(ChannelDivinity):
17th level : CR 4
"""
name = "Channel Divinity: Arcane Abjuration"
source = "Cleric (Arcana Domain)"
@@ -606,6 +647,7 @@ class SpellBreaker(Feature):
level of the spell slot you use to cast the healing spell
"""
name = "Spell Breaker"
source = "Cleric (Arcana Domain)"
@@ -617,6 +659,7 @@ class ArcaneMastery(Feature):
prepared and count as cleric spells for you.
"""
name = "Arcane Mastery"
source = "Cleric (Arcana Domain)"
@@ -632,6 +675,7 @@ class BlessingOfTheForge(Feature):
you finish a long rest
"""
name = "Blessing of the Forge"
source = "Cleric (Forge Domain)"
@@ -654,6 +698,7 @@ class ArtisansBlessing(Feature):
original during the ritual.
"""
name = "Channel Divinity: Artisans Blessing"
source = "Cleric (Forge Domain)"
@@ -667,6 +712,7 @@ class SoulOfTheForge(Feature):
• While wearing heavy armor, you gain a +1 bonus to AC.
"""
name = "Soul of the Forge"
source = "Cleric (Forge Domain)"
@@ -677,20 +723,22 @@ class DivineStrikeForge(DivineStrike):
you hit a creature with a weapon attack, you can cause the attack
to deal an extra 1d8 fire damage to the target. When you reach
14th level, the extra damage increases to 2d8
"""
source = "Cleric (Forge Domain)"
class SaintOfForgeAndFire(Feature):
"""At 17th level, your blessed affinity with fire and metal becomes
more powerful:
- You gain immunity to fire damage.
- While wearing heavy armor, you have resistance to bludgeoning,
piercing, and slashing damage from non-magical attacks
"""
name = "Saint of Forge and Fire"
source = "Cleric (Forge Domain)"
@@ -706,6 +754,7 @@ class CircleOfMortality(Feature):
action
"""
spells_known = (spells.SpareTheDying,)
spells_prepared = (spells.SpareTheDying,)
name = "Circle of Mortality"
@@ -726,13 +775,14 @@ class EyesOfTheGrave(Feature):
long rest
"""
_name = "Eyes of the Grave"
source = "Cleric (Grave Domain)"
@property
def name(self):
num = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(num)
num = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(num)
class PathToTheGrave(ChannelDivinity):
@@ -744,6 +794,7 @@ class PathToTheGrave(ChannelDivinity):
attack's damage, and then the curse ends
"""
name = "Channel Divinity: Path to the Grave"
source = "Cleric (Grave Domain)"
@@ -757,13 +808,14 @@ class SentinelAtDeathsDoor(Feature):
all expended uses when you finish a long rest.
"""
_name = "Sentinel at Death's Door"
source = "Cleric (Grave Domain)"
@property
def name(self):
num = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(num)
num = max(1, self.owner.wisdom.modifier)
return self._name + " ({:d}x/LR)".format(num)
class KeeperOfSouls(Feature):
@@ -775,9 +827,11 @@ class KeeperOfSouls(Feature):
can't do so again until the start ofyour next turn.
"""
name = "Keeper of Souls"
source = "Cleric (Grave Domain)"
class Reaper(Feature):
"""At 1st level, you learn one necromancy cantrip of your choice from any
spell list. When you cast a necromancy cantrip that normally targets only
@@ -785,9 +839,11 @@ class Reaper(Feature):
within 5 feet of each other.
"""
name = "Reaper"
source = "Cleric (Death Domain)"
class TouchOfDeathCleric(Feature):
"""Starting at 2nd level, you can use Channel Divinity to destroy another
creature's life force by touch. When you hit a creature with a melee
@@ -795,18 +851,22 @@ class TouchOfDeathCleric(Feature):
the target. The damage equals 5 + twice your cleric level.
"""
name = "Channel Divinity: Touch of Death"
source = "Cleric (Death Domain)"
class InescapableDestruction(Feature):
"""Starting at 6th level, your ability to channel negative energy becomes
more potent. Necrotic damage dealt by your cleric spells and Channel
Divinity options ignores resistance to necrotic damage
"""
name = "Inescapable Destruction"
source = "Cleric (Death Domain)"
class DivineStrikeDeath(DivineStrike):
"""At 8th level, you gain the ability to infuse your weapon strikes with
necrotic energy. Once on each of your turns when you hit a creature with
@@ -815,8 +875,10 @@ class DivineStrikeDeath(DivineStrike):
increases to 2d8.
"""
source = "Cleric (Death Domain)"
class ImprovedReaper(Feature):
"""Starting at 17th level, when you cast a necromancy spell of 1st through
5th level that targets only one creature, the spell can instead target two
@@ -824,5 +886,6 @@ class ImprovedReaper(Feature):
consumes its material components, you must provide them for each target.
"""
name = "Improved Reaper"
source = "Cleric (Death Domain)"
+149 -90
View File
@@ -12,7 +12,7 @@ class WildShape(Feature):
for example, you can transform into any beast that has a challenge
rating of 1/4 or lower that doesn't have a flying or swimming
speed.
===== ====== ================== ===========
Level Max CR Limitations Example
===== ====== ================== ===========
@@ -20,16 +20,16 @@ class WildShape(Feature):
4th 1/2 No flying Crocodile
8th 1 -- Giant eagle
===== ====== ================== ===========
You can stay in a beast shape for a number of hours equal to half
your druid level (rounded down). You then revert to your normal
form unless you expend another use of this feature. You can revert
to your normal form earlier by using a bonus action on your
turn. You automatically revert if you fall unconscious, drop to 0
hit points, or die.
While you are transformed, the following rules apply:
- Your game statistics are replaced by the statistics of the
beast, but you retain your alignment, personality, and
Intelligence, Wisdom, and Charisma scores. You also retain all
@@ -67,16 +67,17 @@ class WildShape(Feature):
new form can't wear must either fall to the ground or merge with
it. Equipment that merges with the form has no effect until you
leave the form.
"""
_name = "Wild Shape"
source = "Druid"
@property
def name(self):
num = 2
time = self.owner.Druid.level // 2
return self._name + " ({:d}x/SR, {:d} hours)".format(num, time)
num = 2
time = self.owner.Druid.level // 2
return self._name + " ({:d}x/SR, {:d} hours)".format(num, time)
class TimelessBody(Feature):
@@ -84,6 +85,7 @@ class TimelessBody(Feature):
more slowly. For every 10 years that pass, your body ages only 1 year.
"""
name = "Timeless Body"
source = "Druid"
@@ -95,6 +97,7 @@ class BeastSpells(Feature):
provide material components.
"""
name = "Beast Spells"
source = "Druid"
@@ -108,6 +111,7 @@ class Archdruid(Feature):
and your beast shape from Wild Shape
"""
name = "Archdruid"
source = "Druid"
@@ -118,6 +122,7 @@ class BonusCantrip(Feature):
cantrip of your choice
"""
name = "Bonus Cantrip"
source = "Druid (Circle of the Land)"
@@ -135,6 +140,7 @@ class NaturalRecovery(Feature):
1st-level slots.
"""
name = "Natural Recovery"
source = "Druid (Circle of the Land)"
@@ -152,27 +158,30 @@ class _CircleSpells(Feature):
spell is nonetheless a druid spell for you.
"""
_name = "Select One"
source = "Druid (Circle of the Land)"
_spells = {3: [spells.MirrorImage, spells.MistyStep],
5: [spells.WaterBreathing, spells.WaterWalk],
7: [spells.ControlWater, spells.FreedomOfMovement],
9: [spells.ConjureElemental, spells.Scrying]}
_spells = {
3: [spells.MirrorImage, spells.MistyStep],
5: [spells.WaterBreathing, spells.WaterWalk],
7: [spells.ControlWater, spells.FreedomOfMovement],
9: [spells.ConjureElemental, spells.Scrying],
}
spells_known = []
spells_prepared = []
@property
def name(self):
return "Circle Spells ({:s})".format(self._name)
return "Circle Spells ({:s})".format(self._name)
def __init__(self, owner=None):
if owner is not None:
level = owner.Druid.level
for lvl, sps in self._spells.items():
if level >= lvl:
self.spells_known.extend(sps)
self.spells_prepared.extend(sps)
super().__init__(owner=owner)
if owner is not None:
level = owner.Druid.level
for lvl, sps in self._spells.items():
if level >= lvl:
self.spells_known.extend(sps)
self.spells_prepared.extend(sps)
super().__init__(owner=owner)
class ArcticSpells(_CircleSpells):
@@ -182,11 +191,14 @@ class ArcticSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Arctic'
_spells = {3: [spells.HoldPerson, spells.SpikeGrowth],
5: [spells.SleetStorm, spells.Slow],
7: [spells.FreedomOfMovement, spells.IceStorm],
9: [spells.CommuneWithNature, spells.ConeOfCold]}
_name = "Arctic"
_spells = {
3: [spells.HoldPerson, spells.SpikeGrowth],
5: [spells.SleetStorm, spells.Slow],
7: [spells.FreedomOfMovement, spells.IceStorm],
9: [spells.CommuneWithNature, spells.ConeOfCold],
}
class CoastSpells(_CircleSpells):
@@ -196,11 +208,14 @@ class CoastSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Coast'
_spells = {3: [spells.MirrorImage, spells.MistyStep],
5: [spells.WaterBreathing, spells.WaterWalk],
7: [spells.ControlWater, spells.FreedomOfMovement],
9: [spells.ConjureElemental, spells.Scrying]}
_name = "Coast"
_spells = {
3: [spells.MirrorImage, spells.MistyStep],
5: [spells.WaterBreathing, spells.WaterWalk],
7: [spells.ControlWater, spells.FreedomOfMovement],
9: [spells.ConjureElemental, spells.Scrying],
}
class DesertSpells(_CircleSpells):
@@ -210,11 +225,14 @@ class DesertSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Desert'
_spells = {3: [spells.Blur, spells.Silence],
5: [spells.CreateFoodAndWater, spells.ProtectionFromEnergy],
7: [spells.Blight, spells.HallucinatoryTerrain],
9: [spells.InsectPlague, spells.WallOfStone]}
_name = "Desert"
_spells = {
3: [spells.Blur, spells.Silence],
5: [spells.CreateFoodAndWater, spells.ProtectionFromEnergy],
7: [spells.Blight, spells.HallucinatoryTerrain],
9: [spells.InsectPlague, spells.WallOfStone],
}
class ForestSpells(_CircleSpells):
@@ -224,11 +242,14 @@ class ForestSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Forest'
_spells = {3: [spells.Barkskin, spells.SpiderClimb],
5: [spells.CallLightning, spells.PlantGrowth],
7: [spells.Divination, spells.FreedomOfMovement],
9: [spells.CommuneWithNature, spells.TreeStride]}
_name = "Forest"
_spells = {
3: [spells.Barkskin, spells.SpiderClimb],
5: [spells.CallLightning, spells.PlantGrowth],
7: [spells.Divination, spells.FreedomOfMovement],
9: [spells.CommuneWithNature, spells.TreeStride],
}
class GrasslandSpells(_CircleSpells):
@@ -238,11 +259,14 @@ class GrasslandSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Grassland'
_spells = {3: [spells.Invisibility, spells.PassWithoutTrace],
5: [spells.Daylight, spells.Haste],
7: [spells.Divination, spells.FreedomOfMovement],
9: [spells.Dream, spells.InsectPlague]}
_name = "Grassland"
_spells = {
3: [spells.Invisibility, spells.PassWithoutTrace],
5: [spells.Daylight, spells.Haste],
7: [spells.Divination, spells.FreedomOfMovement],
9: [spells.Dream, spells.InsectPlague],
}
class MountainSpells(_CircleSpells):
@@ -252,11 +276,14 @@ class MountainSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Mountain'
_spells = {3: [spells.SpiderClimb, spells.SpikeGrowth],
5: [spells.LightningBolt, spells.MeldIntoStone],
7: [spells.StoneShape, spells.Stoneskin],
9: [spells.Passwall, spells.WallOfStone]}
_name = "Mountain"
_spells = {
3: [spells.SpiderClimb, spells.SpikeGrowth],
5: [spells.LightningBolt, spells.MeldIntoStone],
7: [spells.StoneShape, spells.Stoneskin],
9: [spells.Passwall, spells.WallOfStone],
}
class SwampSpells(_CircleSpells):
@@ -266,11 +293,14 @@ class SwampSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Swamp'
_spells = {3: [spells.Darkness, spells.MelfsAcidArrow],
5: [spells.WaterWalk, spells.StinkingCloud],
7: [spells.FreedomOfMovement, spells.LocateCreature],
9: [spells.InsectPlague, spells.Scrying]}
_name = "Swamp"
_spells = {
3: [spells.Darkness, spells.MelfsAcidArrow],
5: [spells.WaterWalk, spells.StinkingCloud],
7: [spells.FreedomOfMovement, spells.LocateCreature],
9: [spells.InsectPlague, spells.Scrying],
}
class UnderdarkSpells(_CircleSpells):
@@ -280,11 +310,14 @@ class UnderdarkSpells(_CircleSpells):
These spells are included in your Spell Sheet
"""
_name = 'Underdark'
_spells = {3: [spells.SpiderClimb, spells.Web],
5: [spells.GaseousForm, spells.StinkingCloud],
7: [spells.GreaterInvisibility, spells.StoneShape],
9: [spells.Cloudkill, spells.InsectPlague]}
_name = "Underdark"
_spells = {
3: [spells.SpiderClimb, spells.Web],
5: [spells.GaseousForm, spells.StinkingCloud],
7: [spells.GreaterInvisibility, spells.StoneShape],
9: [spells.Cloudkill, spells.InsectPlague],
}
class SporesSpells(_CircleSpells):
@@ -295,12 +328,14 @@ class SporesSpells(_CircleSpells):
"""
_name = 'Spores'
_spells = {2: [spells.ChillTouch],
3: [spells.BlindnessDeafness, spells.GentleRepose],
5: [spells.AnimateDead, spells.GaseousForm],
7: [spells.Blight, spells.Confusion],
9: [spells.Cloudkill, spells.Contagion]}
_name = "Spores"
_spells = {
2: [spells.ChillTouch],
3: [spells.BlindnessDeafness, spells.GentleRepose],
5: [spells.AnimateDead, spells.GaseousForm],
7: [spells.Blight, spells.Confusion],
9: [spells.Cloudkill, spells.Contagion],
}
class CircleSpells(FeatureSelector, _CircleSpells):
@@ -326,15 +361,18 @@ class CircleSpells(FeatureSelector, _CircleSpells):
spores
"""
options = {'arctic': ArcticSpells,
'coast': CoastSpells,
'desert': DesertSpells,
'forest': ForestSpells,
'grassland': GrasslandSpells,
'mountain': MountainSpells,
'swamp': SwampSpells,
'underdark': UnderdarkSpells,
'spores': SporesSpells}
options = {
"arctic": ArcticSpells,
"coast": CoastSpells,
"desert": DesertSpells,
"forest": ForestSpells,
"grassland": GrasslandSpells,
"mountain": MountainSpells,
"swamp": SwampSpells,
"underdark": UnderdarkSpells,
"spores": SporesSpells,
}
name = "Circle Spells (Select One)"
source = "Druid (Circle of the Land/Spores)"
@@ -348,6 +386,7 @@ class LandsStride(Feature):
impede movement, such those created by the entangle spell.
"""
name = "Land's Stride"
source = "Class (Many)"
@@ -357,6 +396,7 @@ class NaturesWard(Feature):
or fey, and you are immune to poison and disease
"""
name = "Nature's Ward"
source = "Druid (Circle of the Land)"
@@ -371,6 +411,7 @@ class NaturesSanctuary(Feature):
creature is aware of this effect before it makes its attack against you
"""
name = "Nature's Sanctuary"
source = "Druid (Circle of the Land)"
@@ -384,6 +425,7 @@ class CombatWildShape(Feature):
of the spell slot expended.
"""
name = "Combat Wild Shape"
source = "Druid (Circle of the Moon)"
@@ -398,13 +440,14 @@ class CircleForms(Feature):
down
"""
_name = "Circle Forms"
source = "Druid (Circle of the Moon)"
@property
def name(self):
level = self.owner.Druid.level
return self._name + ' (CR {:d})'.format(max(1, level//3))
level = self.owner.Druid.level
return self._name + " (CR {:d})".format(max(1, level // 3))
class PrimalStrike(Feature):
@@ -413,6 +456,7 @@ class PrimalStrike(Feature):
damage.
"""
name = "Primal Strike"
source = "Druid (Circle of the Moon)"
@@ -423,6 +467,7 @@ class ElementalWildShape(Feature):
water elemental.
"""
name = "Elemental Wild Shape"
source = "Druid (Circle of the Moon)"
@@ -432,6 +477,7 @@ class ThousandForms(Feature):
more subtle ways. You can cast the alter self spell at will.
"""
name = "Thousand Forms"
source = "Druid (Circle of the Moon)"
spells_known = (spells.AlterSelf,)
@@ -451,12 +497,13 @@ class BalmOfTheSummerCourt(Feature):
long rest.
"""
_name = "Balm Of The Summer Court"
source = "Druid (Circle of Dreams)"
@property
def name(self):
return self._name + " ({:d}x d6)".format(self.owner.Druid.level)
return self._name + " ({:d}x d6)".format(self.owner.Druid.level)
class HearthOfMoonlightAndShadow(Feature):
@@ -472,6 +519,7 @@ class HearthOfMoonlightAndShadow(Feature):
sphere vanishes at the end of the rest or when you leave the sphere
"""
name = "Hearth of Moonlight and Shadow"
source = "Druid (Circle of the Moon)"
@@ -488,6 +536,7 @@ class HiddenPaths(Feature):
and you regain all expended uses of it when you finish a long rest
"""
name = "Hidden Paths"
source = "Druid (Circle of the Moon)"
@@ -507,6 +556,7 @@ class WalkerInDreams(Feature):
a long rest.
"""
name = "Walker in Dreams"
source = "Druid (Circle of the Moon)"
@@ -523,6 +573,7 @@ class SpeechOfTheWoods(Feature):
them as you would with any nonplayer character.
"""
name = "Speech of the Woods"
source = "Druid (Circle of the Shepherd)"
@@ -535,27 +586,27 @@ class SpiritTotem(Feature):
radius around that point. It counts as neither a creature nor an
object, though it has the spectral appearance of the creature
it. represents.
As a bonus action, you can move the spirit up to 60 feet to a
point you can see. The spirit persists for 1 minute or until
you're incapacitated. Once you use this feature, you can't use it
again until you finish a short or long rest. The effect of the
spirit's aura depends on the type of spirit you summon from the
options below.
**Bear Spirit**: The bear spirit grants you and your allies its
might and endurance. Each creature ofyour choice in the aura when
the spirit appears gains temporary hit points equal to 5 + your
druid level. In addition, you and your allies gain advantage on
Strength checks and Strength saving throws while in the aura.
**Hawk Spirit**: The hawk spirit is a consummate hunter, aiding
you and your allies with its keen sight. When a creature makes an
attack roll against a target in the spirit's aura, you can use
your reaction to grant advantage to that attack roll. In addition,
you and your allies have advantage on Wisdom (Perception) checks
while in the aura
**Unicorn Spirit**: The unicorn spirit lends its protection to
those nearby. You and your allies gain advantage on all ability
checks made to detect creatures in the spirit's aura. In
@@ -563,8 +614,9 @@ class SpiritTotem(Feature):
points to any creature inside or outside the aura, each creature
of your choice in the aura also regains hit points equal to your
druid level.
"""
name = "Spirit Totem"
source = "Druid (Circle of the Shepherd)"
@@ -573,7 +625,7 @@ class MightySummoner(Feature):
"""Starting at 6th level, beasts and fey that you conjure are more
resilient than normal. Any beast or fey summoned or created by a
spell that you cast gains the. following benefits:
- The creature appears with more hit points than normal: 2 extra
hit
- The creature appears with more hit points than normal: 2 extra
@@ -581,8 +633,9 @@ class MightySummoner(Feature):
- The damage from its natural weapons is considered magical for
the purpose of overcoming immunity and resistance to nonmagical
attacks and damage.
"""
name = "Mighty Summoner"
source = "Druid (Circle of the Shepherd)"
@@ -593,8 +646,9 @@ class GuardianSpirit(Feature):
that you summoned or created with a spell ends its turn in your
Spirit Totem aura, that creature regains a number of hit points
equal to half your druid level.
"""
name = "Guardian Spirit"
source = "Druid (Circle of the Shepherd)"
@@ -613,11 +667,12 @@ class FaithfulSummons(Feature):
you finish a long rest
"""
name = "Faithful Summons"
source = "Druid (Circle of the Shepherd)"
#Circle of Spores
# Circle of Spores
class HaloOfSpores(Feature):
"""Starting at 2nd level, you are surrounded by invisible, necrotic spores
that are harmless until you unleash them on a creature nearby. When a
@@ -628,6 +683,7 @@ class HaloOfSpores(Feature):
10th level, and 1d10 at 14th level
"""
name = "Halo of Spores"
source = "Druid (Cirlce of Spores)"
@@ -649,6 +705,7 @@ class SymbioticEntity(Feature):
points, or until you use your Wild Shape again.
"""
name = "Symbiotic Entity"
source = "Druid (Circle of Spores)"
@@ -660,16 +717,17 @@ class FungalInfestation(Feature):
causing it to stand up immediately with 1 hit point. The creature
uses the zombie stat block in the Monster Manual. It remains
animated for 1 hour, after which time it collapses and dies.
In combat, the zombie's turn comes immediately after yours. It
obeys your mental commands, and the only action it can take is the
Attack action, making one melee attack.
You can use this feature a number of times equal to your Wisdom
modifier (minimum of once), and you regain all expended uses of it
when you finish a long rest.
"""
name = "Fungal Infestation"
source = "Druid (Circle of Spores)"
@@ -691,6 +749,7 @@ class SpreadingSpores(Feature):
reaction.
"""
name = "Spreading Spores"
source = "Druid (Circle of Spores)"
@@ -701,6 +760,6 @@ class FungalBody(Feature):
you counts as a normal hit instead, unless you're incapacitated.
"""
name = "Fungal Body"
source = "Druid (Circle of Spores)"
File diff suppressed because it is too large Load Diff
+38 -36
View File
@@ -25,72 +25,74 @@ def create_feature(**params):
NewFeature
New feature class, subclass of ``Feature``, with given params.
"""
NewFeature = type('UnknownFeature', (Feature,), params)
NewFeature = type("UnknownFeature", (Feature,), params)
return NewFeature
class Feature():
class Feature:
"""
Provide full text of rules in documentation
"""
name = "Generic Feature"
owner = None
source = 'Unknown' # race, class, background, etc.
source = "Unknown" # race, class, background, etc.
spells_known = ()
spells_prepared = ()
needs_implementation = False # Set to True if need to find way to compute stats
def __init__(self, owner=None):
self.owner = owner
self.spells_known = [S() for S in self.spells_known]
self.spells_prepared = [S() for S in self.spells_prepared]
self.owner = owner
self.spells_known = [S() for S in self.spells_known]
self.spells_prepared = [S() for S in self.spells_prepared]
def __eq__(self, other):
return (self.name == other.name) and (self.source == other.source)
return (self.name == other.name) and (self.source == other.source)
def __hash__(self):
return 0
return 0
def __str__(self):
return self.name
return self.name
def __repr__(self):
return "\"{:s}\"".format(self.name)
return '"{:s}"'.format(self.name)
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""
Updates weapon based on the Feature property
"""
Updates weapon based on the Feature property
Parameters
----------
weapon
The weapon to be tested for special bonuses
kwargs
Any other key-word arguments the function may require
"""
pass
Parameters
----------
weapon
The weapon to be tested for special bonuses
kwargs
Any other key-word arguments the function may require
"""
pass
class FeatureSelector(Feature):
"""
A feature with multiple possible choices.
"""
options = dict()
name = ''
source = ''
name = ""
source = ""
def __new__(t, owner, feature_choices=[]):
# Look for matching feature_choices
new_feat = Feature.__new__(Feature, owner=owner)
new_feat.__doc__ = t.__doc__
new_feat.name = t.name
new_feat.source = t.source
new_feat.needs_implementation = True
for selection in feature_choices:
if selection.lower() in t.options:
feat_class = t.options[selection.lower()]
if owner.has_feature(feat_class):
continue
new_feat = feat_class(owner=owner)
new_feat.source = t.source
return new_feat
# Look for matching feature_choices
new_feat = Feature.__new__(Feature, owner=owner)
new_feat.__doc__ = t.__doc__
new_feat.name = t.name
new_feat.source = t.source
new_feat.needs_implementation = True
for selection in feature_choices:
if selection.lower() in t.options:
feat_class = t.options[selection.lower()]
if owner.has_feature(feat_class):
continue
new_feat = feat_class(owner=owner)
new_feat.source = t.source
return new_feat
+169 -84
View File
@@ -1,7 +1,5 @@
from dungeonsheets import armor, weapons
from dungeonsheets.features.features import Feature, FeatureSelector
from dungeonsheets.features.ranger import (Archery, Defense, Dueling,
TwoWeaponFighting)
from dungeonsheets.features.ranger import Archery, Defense, Dueling, TwoWeaponFighting
# Features added for all PHB classes
# SCAG and XGTE needed
@@ -15,8 +13,8 @@ class GreatWeaponFighting(Feature):
have the two-handed or versatile property for you to gain this benefit.
"""
name = 'Fighting Style (Great Weapon Fighting)'
source = 'Fighter'
name = "Fighting Style (Great Weapon Fighting)"
source = "Fighter"
class Protection(Feature):
@@ -25,8 +23,8 @@ class Protection(Feature):
attack roll. You must be wielding a shield.
"""
name = 'Fighting Style (Protection)'
source = 'Fighter'
name = "Fighting Style (Protection)"
source = "Fighter"
# UA
@@ -35,8 +33,8 @@ class BlindingFighting(Feature):
rolls against it, provided the creature isnt hidden from you.
"""
name = 'Fighting Style (Blinding Fighting)'
source = 'Fighter'
name = "Fighting Style (Blinding Fighting)"
source = "Fighter"
class CloseQuartersShooter(Feature):
@@ -46,8 +44,8 @@ class CloseQuartersShooter(Feature):
30 feet of you. You have a +1 bonus to attack rolls on ranged attacks.
"""
name = 'Fighting Style (Close Quarters Shooter)'
source = 'Fighter'
name = "Fighting Style (Close Quarters Shooter)"
source = "Fighter"
class Interception(Feature):
@@ -57,8 +55,8 @@ class Interception(Feature):
be wielding a shield or a simple or martial weapon to use this reaction.
"""
name = 'Fighting Style (Interception)'
source = 'Fighter'
name = "Fighting Style (Interception)"
source = "Fighter"
class Mariner(Feature):
@@ -67,20 +65,21 @@ class Mariner(Feature):
gain a +1 bonus to armor class.
"""
name = 'Fighting Style (Mariner)'
source = 'Fighter'
name = "Fighting Style (Mariner)"
source = "Fighter"
class ThrownWeaponFighting(Feature):
"""You can draw a weapon that has the thrown property as part of the
attack you make with the weapon.
In addition, when you hit with a ranged attack using a thrown
weapon, you gain a +1 bonus to the damage roll.
"""
name = 'Fighting Style (Thrown Weapon Fighting)'
source = 'Fighter'
name = "Fighting Style (Thrown Weapon Fighting)"
source = "Fighter"
class TunnelFighter(Feature):
@@ -90,27 +89,29 @@ class TunnelFighter(Feature):
reaction to make a melee attack against a creature that moves more than
5 feet while within your reach.
"""
name = 'Fighting Style (Tunnel Fighter)'
source = 'Fighter'
name = "Fighting Style (Tunnel Fighter)"
source = "Fighter"
class UnarmedFighting(Feature):
"""Your unarmed strikes can deal bludgeoning damage equal to 1d6 + your
Strength modifier. If you strike with two free hands, the d6 becomes a d8.
When you successfully start a grapple, you can deal 1d4
bludgeoning damage to the grappled creature. Until the grapple
ends, you can also deal this damage to the creature whenever you
hit it with a melee attack.
"""
name = 'Fighting Style (Unarmed Fighting)'
source = 'Fighter'
name = "Fighting Style (Unarmed Fighting)"
source = "Fighter"
class FighterFightingStyle(FeatureSelector):
"""Select a Fighting Style by choosing in feature_choices:
- archery
- defense
- dueling
@@ -124,24 +125,27 @@ class FighterFightingStyle(FeatureSelector):
- thrown weapon fighting
- tunnel fighter
- unarmed fighting
"""
options = {'archery': Archery,
'defense': Defense,
'dueling': Dueling,
'great': GreatWeaponFighting,
'great-weapon fighting': GreatWeaponFighting,
'projection': Protection,
'two-weapon fighting': TwoWeaponFighting,
'two-weapon': TwoWeaponFighting,
'dual wield': TwoWeaponFighting,
'blinding fighting': BlindingFighting,
'close quarters shooter': CloseQuartersShooter,
'interception': Interception,
'mariner': Mariner,
'thrown weapon fighting': ThrownWeaponFighting,
'tunnel fighter': TunnelFighter,
'unarmed fighting': UnarmedFighting}
options = {
"archery": Archery,
"defense": Defense,
"dueling": Dueling,
"great": GreatWeaponFighting,
"great-weapon fighting": GreatWeaponFighting,
"projection": Protection,
"two-weapon fighting": TwoWeaponFighting,
"two-weapon": TwoWeaponFighting,
"dual wield": TwoWeaponFighting,
"blinding fighting": BlindingFighting,
"close quarters shooter": CloseQuartersShooter,
"interception": Interception,
"mariner": Mariner,
"thrown weapon fighting": ThrownWeaponFighting,
"tunnel fighter": TunnelFighter,
"unarmed fighting": UnarmedFighting,
}
name = "Fighting Style (Select One)"
source = "Fighter"
@@ -153,6 +157,7 @@ class SecondWind(Feature):
finish a short or long rest before you can use it again
"""
name = "Second Wind"
source = "Fighter"
@@ -167,6 +172,7 @@ class ActionSurge(Feature):
rest, but only once on the same turn.
"""
name = "Action Surge"
source = "Fighter"
@@ -178,18 +184,19 @@ class ExtraAttackFighter(Feature):
20th level in this class.
"""
_name = "Extra Attack"
source = "Fighter"
@property
def name(self):
level = self.owner.Fighter.level
if level < 11:
return self._name + ' (2x)'
elif level < 20:
return self._name + ' (3x)'
else:
return self._name + ' (4x)'
level = self.owner.Fighter.level
if level < 11:
return self._name + " (2x)"
elif level < 20:
return self._name + " (3x)"
else:
return self._name + " (4x)"
class Indomitable(Feature):
@@ -201,18 +208,19 @@ class Indomitable(Feature):
and three times between long rests starting at 17th level.
"""
_name = "Indomitable"
source = "Fighter"
@property
def name(self):
level = self.owner.Fighter.level
if level < 13:
return self._name + ' (1x/LR)'
elif level < 17:
return self._name + ' (2x/LR)'
else:
return self._name + ' (3x/LR)'
level = self.owner.Fighter.level
if level < 13:
return self._name + " (1x/LR)"
elif level < 17:
return self._name + " (2x/LR)"
else:
return self._name + " (3x/LR)"
# Champion
@@ -221,6 +229,7 @@ class ImprovedCritical(Feature):
score a critical hit on a roll of 19 or 20.
"""
name = "Improved Critical"
source = "Fighter (Champion)"
@@ -234,6 +243,7 @@ class RemarkableAthelete(Feature):
increases by a number of feet equal to your Strength modifier.
"""
name = "Remarkable Athelete"
source = "Fighter (Champion)"
@@ -254,15 +264,18 @@ class AdditionalFightingStyle(FeatureSelector):
two-weapon fighting 2
"""
options = {'archery 2': Archery,
'defense 2': Defense,
'dueling 2': Dueling,
'great 2': GreatWeaponFighting,
'great-weapon fighting 2': GreatWeaponFighting,
'projection 2': Protection,
'two-weapon fighting 2': TwoWeaponFighting,
'two-weapon 2': TwoWeaponFighting,
'dual wield 2': TwoWeaponFighting}
options = {
"archery 2": Archery,
"defense 2": Defense,
"dueling 2": Dueling,
"great 2": GreatWeaponFighting,
"great-weapon fighting 2": GreatWeaponFighting,
"projection 2": Protection,
"two-weapon fighting 2": TwoWeaponFighting,
"two-weapon 2": TwoWeaponFighting,
"dual wield 2": TwoWeaponFighting,
}
name = "Fighting Style (Select One)"
source = "Fighter (Champion)"
@@ -271,6 +284,7 @@ class SuperiorCritical(Feature):
"""Starting at 15th level, your weapon attacks score a critical hit on a roll
of 18-20 .
"""
name = "Superior Critical"
source = "Fighter (Champion)"
@@ -282,6 +296,7 @@ class Survivor(Feature):
left. You don't gain this benefit if you have 0 hit points.
"""
name = "Survivor"
source = "Fighter (Champion)"
@@ -310,17 +325,18 @@ class CombatSuperiority(Feature):
modifier (your choice)
"""
_name = "Combat Superiority"
@property
def name(self):
level = self.owner.Fighter.level
if level < 10:
return self._name + ' (d8)'
elif level < 18:
return self._name + ' (d10)'
else:
return self._name + ' (d12)'
level = self.owner.Fighter.level
if level < 10:
return self._name + " (d8)"
elif level < 18:
return self._name + " (d10)"
else:
return self._name + " (d12)"
class StudentOfWar(Feature):
@@ -328,6 +344,7 @@ class StudentOfWar(Feature):
choice.
"""
name = "Student of War"
source = "Fighter (Battle Master)"
@@ -339,7 +356,7 @@ class KnowYourEnemy(Feature):
own. The DM tells you if the creature is your equal, superior, or
inferior in regard to two of the following characteristics of your
choice:
- Strength score
- Dexterity score
- Constitution score
@@ -349,6 +366,7 @@ class KnowYourEnemy(Feature):
- Fighter class levels (if any)
"""
name = "Know Your Enemy"
source = "Fighter (Battle Master)"
@@ -358,6 +376,7 @@ class Relentless(Feature):
dice remaining, you regain 1 superiority die.
"""
name = "Relentless"
source = "Fighter (Battle Master)"
@@ -367,6 +386,7 @@ class Maneuver(Feature):
"""
A generic Maneuver
"""
name = "Maneuver"
source = "Fighter Maneuver (Battle Master)"
@@ -380,6 +400,7 @@ class CommandersStrike(Maneuver):
attack's damage roll.
"""
name = "Commander's Strike"
@@ -392,6 +413,7 @@ class DisarmingAttack(Maneuver):
feet.
"""
name = "Disarming Attack"
@@ -403,6 +425,7 @@ class DistractingStrike(Maneuver):
if the attack is made before the start of your next turn.
"""
name = "Distracting Strike"
@@ -411,6 +434,7 @@ class EvasiveFootwork(Maneuver):
adding the number rolled to your AC until you stop moving.
"""
name = "Evasive Footwork"
@@ -421,6 +445,7 @@ class FeintingAttack(Maneuver):
hits, add the superiority die to the attack's damage roll.
"""
name = "Feinting Attack"
@@ -433,6 +458,7 @@ class GoadingAttack(Maneuver):
turn.
"""
name = "Goading Attack"
@@ -442,6 +468,7 @@ class LungingAttack(Maneuver):
hit, you add the superiority die to the attack's damage roll.
"""
name = "Lunging Attack"
@@ -454,6 +481,7 @@ class ManeuveringAttack(Maneuver):
attacks from the target of your attack.
"""
name = "Maneuvering Attack"
@@ -465,6 +493,7 @@ class MenacingAttack(Maneuver):
next turn.
"""
name = "Menacing Attack"
@@ -474,6 +503,7 @@ class Parry(Maneuver):
you roll on your superiority die + your Dexterity modifier.
"""
name = "Parry"
@@ -484,6 +514,7 @@ class PrecisionAttack(Maneuver):
applied
"""
name = "Precision Attack"
@@ -495,6 +526,7 @@ class PushingAttack(Maneuver):
the target up to 15 feet away from you.
"""
name = "Pushing Attack"
@@ -505,6 +537,7 @@ class Rally(Maneuver):
hit points equal to the superiority die roll + your Charisma modifier.
"""
name = "Rally"
@@ -515,6 +548,7 @@ class Riposte(Maneuver):
roll
"""
name = "Riposte"
@@ -527,6 +561,7 @@ class SweepingAttack(Maneuver):
die. The damage is of the same type dealt by the original attack. Trip
"""
name = "Sweeping Attack"
@@ -538,6 +573,7 @@ class TripingAttack(Maneuver):
the target prone
"""
name = "Triping Attack"
@@ -563,6 +599,7 @@ class EldritchKnightSpellcasting(Feature):
spell you gained at 8th, 14th, or 20th level.
"""
name = "Spellcasting"
source = "Fighter (Eldritch Knight)"
@@ -584,6 +621,7 @@ class WeaponBond(Feature):
must break the bond with one of the other two.
"""
name = "Weapon Bond"
source = "Fighter (Eldritch Knight)"
@@ -593,6 +631,7 @@ class WarMagic(Feature):
make one weapon attack as a bonus action.
"""
name = "War Magic"
source = "Fighter (Eldritch Knight)"
@@ -604,6 +643,7 @@ class EldritchStrike(Feature):
against a spell you cast before the end of your next turn.
"""
name = "Eldritch Strike"
source = "Fighter (Eldritch Knight)"
@@ -614,6 +654,7 @@ class ArcaneCharge(Feature):
teleport before or after the additional action.
"""
name = "Arcane Charge"
source = "Fighter (Eldritch Knight)"
@@ -623,6 +664,7 @@ class ImprovedWarMagic(Feature):
make one weapon attack as a bonus action.
"""
name = "Improved War Magic"
source = "Fighter (Eldritch Knight)"
@@ -636,6 +678,7 @@ class RallyingCry(Feature):
level, provided that the creature can see or hear you
"""
name = "Rallying Cry"
source = "Fighter (Purple Dragon Knight)"
@@ -654,15 +697,16 @@ class RoyalEnvoy(Feature):
you gain from this feature
"""
name = "Royal Envoy"
source = "Fighter (Purple Dragon Knight)"
def __init__(self, owner=None):
super().__init__(owner=owner)
if 'persuasion' not in self.owner.skill_proficiencies:
self.owner.skill_proficiencies.append('persuasion')
if 'persuasion' not in self.owner.skill_expertise:
self.owner.skill_expertise.append('persuasion')
super().__init__(owner=owner)
if "persuasion" not in self.owner.skill_proficiencies:
self.owner.skill_proficiencies.append("persuasion")
if "persuasion" not in self.owner.skill_expertise:
self.owner.skill_expertise.append("persuasion")
class InspiringSurge(Feature):
@@ -673,6 +717,7 @@ class InspiringSurge(Feature):
two allies within 60 feet of you, rather than one.
"""
name = "Inspiring Surge"
source = "Fighter (Purple Dragon Knight)"
@@ -686,6 +731,7 @@ class Bulwark(Feature):
or hear you, it can reroll its saving throw and must use the new roll
"""
name = "Bulwark"
source = "Fighter (Purple Dragon Knight)"
@@ -698,6 +744,7 @@ class ArcaneArcherLore(Feature):
you choose to learn either the prestidigr'tation or the drufdcraft cantrip
"""
name = "Arcane Archer Lore"
source = "Fighter (Arcane Archer)"
@@ -724,6 +771,7 @@ class ArcaneShot(Feature):
your proficiency bonus + your Intelligence modifier
"""
name = "Arcane Shot (2x/SR)"
source = "Fighter (Arcane Archer)"
@@ -736,6 +784,7 @@ class MagicArrow(Feature):
after it hits or misses its target.
"""
name = "Magic Arrow"
source = "Fighter (Arcane Archer)"
@@ -747,6 +796,7 @@ class CurvingShot(Feature):
within 60 feet of the original target
"""
name = "Curving Shot"
source = "Fighter (Arcane Archer)"
@@ -757,6 +807,7 @@ class EverReadyShot(Feature):
you regain one use of it.
"""
name = "Ever-Ready Shot"
source = "Fighter (Arcane Archer)"
@@ -773,6 +824,7 @@ class BanishingArrow(Feature):
damage when the arrow hits it.
"""
name = "Arcane Shot: Banishing Arrow"
source = "Fighter (Arcane Archer)"
@@ -788,6 +840,7 @@ class BeguilingArrow(Feature):
level in this class.
"""
name = "Arcane Shot: Beguiling Arrow"
source = "Fighter (Arcane Archer)"
@@ -800,6 +853,7 @@ class BurstingArrow(Feature):
when you reach 18th level in this class
"""
name = "Arcane Shot: Bursting Arrow"
source = "Fighter (Arcane Archer)"
@@ -812,6 +866,7 @@ class EnfeeblingArrow(Feature):
4d6 when you reach 18th level in this class.
"""
name = "Arcane Shot: Enfeebling Arrow"
source = "Fighter (Arcane Archer)"
@@ -829,6 +884,7 @@ class GraspingArrow(Feature):
in this class
"""
name = "Arcane Shot: Grasping Arrow"
source = "Fighter (Arcane Archer)"
@@ -845,6 +901,7 @@ class PiercingArrow(Feature):
in this class.
"""
name = "Arcane Shot: Piercing Arrow"
source = "Fighter (Arcane Archer)"
@@ -864,6 +921,7 @@ class SeekingArrow(Feature):
force damage increases to 2d6 when you reach 18th level in this class.
"""
name = "Arcane Shot: Seeking Arrow"
source = "Fighter (Arcane Archer)"
@@ -877,6 +935,7 @@ class ShadowArrow(Feature):
class
"""
name = "Shadow Arrow"
source = "Fighter (Arcane Archer)"
@@ -889,6 +948,7 @@ class BonusProficiencyCavalier(Feature):
choice.
"""
name = "Bonus Proficiency"
source = "Fighter (Cavalier)"
@@ -901,6 +961,7 @@ class BornToTheSaddle(Feature):
costs you only 5 feet of movement, rather than half your speed.
"""
name = "Born to the Saddle"
source = "Fighter (Cavalier)"
@@ -925,13 +986,14 @@ class UnwaveringMark(Feature):
and you regain all expended uses of it when you finish a long rest
"""
_name = "Unwavering Mark"
source = "Fighter (Cavalier)"
@property
def name(self):
num = max(1, self.owner.strength.modifier)
return self._name + ' ({:d}x/LR)'.format(num)
num = max(1, self.owner.strength.modifier)
return self._name + " ({:d}x/LR)".format(num)
class WardingManeuver(Feature):
@@ -947,13 +1009,14 @@ class WardingManeuver(Feature):
finish a long rest
"""
_name = "Warding Maneuver"
source = "Fighter (Cavalier)"
@property
def name(self):
num = max(1, self.owner.constitution.modifier)
return self._name + ' ({:d}x/LR)'.format(num)
num = max(1, self.owner.constitution.modifier)
return self._name + " ({:d}x/LR)".format(num)
class HoldTheLine(Feature):
@@ -963,6 +1026,7 @@ class HoldTheLine(Feature):
the target's speed is reduced to 0 until the end of the current turn.
"""
name = "Hold the Line"
source = "Fighter (Cavalier)"
@@ -976,6 +1040,7 @@ class FerociousCharger(Feature):
on each of your turns
"""
name = "Ferocious Charger"
source = "Fighter (Cavalier)"
@@ -988,6 +1053,7 @@ class VigilantDefender(Feature):
that you take your normal reaction
"""
name = "Vigiland Defender"
source = "Fighter (Cavalier)"
@@ -999,6 +1065,7 @@ class BonusProficiencySamurai(Feature):
Persuasion. Alterna- tively, you learn one language of your choice.
"""
name = "Bonus Proficiency"
source = "Fighter (Samurai)"
@@ -1014,6 +1081,7 @@ class FightingSpirit(Feature):
a long rest.
"""
name = "Fighting Spirit (3x/LR)"
source = "Fighter (Samurai)"
@@ -1027,6 +1095,7 @@ class ElegantCourtier(Feature):
in Intelligence or Charisma saving throws (your choice).
"""
name = "Elegant Courtier"
source = "Fighter (Samurai)"
needs_implementation = True
@@ -1037,6 +1106,7 @@ class TirelessSpirit(Feature):
Fighting Spirit remaining, you regain one use.
"""
name = "Tireless Spirit"
source = "Fighter (Samurai)"
@@ -1049,6 +1119,7 @@ class RapidStrike(Feature):
same action. You can do so no more than once per turn
"""
name = "Rapid Strike"
source = "Fighter (Samurai)"
@@ -1065,6 +1136,7 @@ class StrengthBeforeDeath(Feature):
again until you finish a long rest.
"""
name = "Strength Before Death"
source = "Fighter (Samurai)"
@@ -1078,6 +1150,7 @@ class Gunsmith(Feature):
available through crafting.
"""
name = "Gunsmith"
source = "Fighter (Gunslinger)"
@@ -1142,6 +1215,7 @@ class AdeptMarksman(Feature):
below next to the price.
"""
name = "Adept Marksman"
source = "Fighter (Gunslinger"
@@ -1152,6 +1226,7 @@ class QuickDraw(Feature):
single object interaction on your turn.
"""
name = "Quick Draw"
source = "Fighter (Gunslinger)"
@@ -1162,14 +1237,14 @@ class RapidRepair(Feature):
broken) firearm as a bonus action.
"""
name = "Rapid Repair"
source = "Fighter (Gunslinger)"
class LightningReload(Feature):
"""Starting at 15th level, you can reload any firearm as a bonus action.
"""Starting at 15th level, you can reload any firearm as a bonus action."""
"""
name = "Lightning Repaid"
source = "Fighter (Gunslinger)"
@@ -1179,6 +1254,7 @@ class ViciousIntent(Feature):
and you regain a grit point on a roll of 19 or 20 on a d20 attack roll.
"""
name = "Vicious Intent"
source = "Fighter (Gunslinger)"
@@ -1189,6 +1265,7 @@ class HemorrhagingCritical(Feature):
attack at the end of its next turn.
"""
name = "Hemorrhaging Critical"
source = "Fighter (Gunslinger)"
@@ -1199,6 +1276,7 @@ class BullyingShot(Feature):
Charisma (Intimidation) check to gain advantage on the roll.
"""
name = "Bullying Shot"
source = "Gunslinger (Trick Shot)"
@@ -1210,6 +1288,7 @@ class DazingShot(Feature):
disadvantage on attacks until the end of their next turn.
"""
name = "Dazing Shot"
source = "Gunslinger (Trick Shot)"
@@ -1219,6 +1298,7 @@ class DeadeyeShot(Feature):
point to gain advantage on the attack roll.
"""
name = "Deadeye Shot"
source = "Gunslinger (Trick Shot)"
@@ -1231,6 +1311,7 @@ class DisarmingShot(Feature):
away from you.
"""
name = "Disarming Shot"
source = "Gunslinger (Trick Shot)"
@@ -1242,6 +1323,7 @@ class ForcefulShot(Feature):
or be pushed 15 feet away from you.
"""
name = "Forceful Shot"
source = "Gunslinger (Trick Shot)"
@@ -1255,6 +1337,7 @@ class PiercingShot(Feature):
increment. Only the initial attack can misfire.
"""
name = "Piercing Shot"
source = "Gunslinger (Trick Shot)"
@@ -1265,6 +1348,7 @@ class WingingShot(Feature):
normal damage and must make a Strength saving throw or be knocked prone.
"""
name = "Winging Shot"
source = "Gunslinger (Trick Shot)"
@@ -1277,5 +1361,6 @@ class ViolentShot(Feature):
point spent when determining the damage.
"""
name = "Violent Shot"
source = "Gunslinger (Trick Shot)"
+127 -69
View File
@@ -1,4 +1,4 @@
from dungeonsheets import armor, spells, weapons
from dungeonsheets import spells, weapons
from dungeonsheets.features.features import Feature
@@ -6,13 +6,14 @@ class UnarmoredDefenseMonk(Feature):
"""Beginning at 1st level, while you are wearing no armor and not
wearing a shield, your AC equals 10 + your Dexterity modifier +
your Wisdom modifier.
This bonus is computed in the AC given on the Character Sheet
above.
"""
name = "Unarmored Defense"
source = 'Monk'
source = "Monk"
class MartialArts(Feature):
@@ -22,7 +23,7 @@ class MartialArts(Feature):
two-handed or heavy property. You gain the following benefits
while you are unarmed or wielding only monk weapons and you aren't
wearing armor or wielding a shield:
- You can use Dexterity instead of Strength for the attack and
damage rolls of your unarmed strikes and monk weapons.
- You can roll a d4 in place of the normal damage of your unarmed
@@ -34,36 +35,36 @@ class MartialArts(Feature):
with a quarter- staff, you can also make an unarmed strike as a
bonus action, assuming you haven't already taken a bonus action
this turn.
Certain monasteries use specializepd forms of the monk
weapons. For example, you might use a club that is two lengths of
w ood connected by a short chain (called a nunchaku) or a sickle
with a shorter, straighter blade (called a kama). Whatever name
you use for a monk weapon, you can use the game statistics
provided for
"""
name = "Martial Arts"
source = 'Monk'
die = 'd4'
source = "Monk"
die = "d4"
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""Update increasing damage dice and DEX mod of Monk weapons"""
is_monk_weapon = any([isinstance(weapon, w)
for w in weapons.monk_weapons])
is_monk_weapon = any([isinstance(weapon, w) for w in weapons.monk_weapons])
level = self.owner.Monk.level
if not is_monk_weapon:
return weapon
self.die = 'd4'
self.die = "d4"
if level >= 5:
self.die = 'd6'
self.die = "d6"
if level >= 11:
self.die = 'd8'
self.die = "d8"
if level >= 17:
self.die = 'd10'
self.die = "d10"
# check if new damage is better than default
if int(self.die[1:]) > int(weapon.base_damage.split('d')[-1]):
weapon.base_damage = '1' + str(self.die)
if int(self.die[1:]) > int(weapon.base_damage.split("d")[-1]):
weapon.base_damage = "1" + str(self.die)
weapon.is_finesse = True
@@ -73,7 +74,7 @@ class Ki(Feature):
a number of ki points. Your monk level determines the number of
points you have, as shown in the Ki Points column of the Monk
table. You can spend these points to fuel various ki features.
You start knowing three such features: Flurry of Blows, Patient
Defense, and Step of the Wind. You learn more ki features as you
gain levels in this class. When you spend a ki point, it is
@@ -81,13 +82,14 @@ class Ki(Feature):
which you draw all of your expended ki back into yourself. You
must spend at least 30 minutes of the rest meditating to regain
your ki points.
Some of your ki features require your target to make a saving
throw to resist the feature's effects. The saving throw DC is
calculated as follows: Ki save DC = 8 + your proficiency bonus +
your Wisdom modifier
"""
_name = "Ki"
source = "Monk"
@@ -103,6 +105,7 @@ class FlurryOfBlows(Feature):
ki point to make two unarmed strikes as a bonus action
"""
name = "Flurry of Blows"
source = "Monk"
@@ -112,6 +115,7 @@ class PatientDefense(Feature):
turn
"""
name = "Patient Defense"
source = "Monk"
@@ -121,6 +125,7 @@ class StepOfTheWind(Feature):
action on your turn, and your jump distance is doubled for the turn
"""
name = "Step of the Wind"
source = "Monk"
@@ -134,6 +139,7 @@ class UnarmoredMovement(Feature):
across liquids on your turn without falling during the move.
"""
name = "Unarmored Movement"
source = "Monk"
@@ -159,17 +165,18 @@ class DeflectMissiles(Feature):
+ your Dexterity modifier + your monk level. If you reduce the
damage to 0, you can catch the missile if it is small enough for
you to hold in one hand and you have at least one hand free.
If you catch a missile in this way, you can spend 1 ki point to
make a ranged attack with the weapon or piece of ammunition you
just caught, as part of the same reaction. You make this attack
with proficiency, regardless of your weapon proficiencies, and the
missile counts as a monk weapon for the attack
"""
_name = "Deflect Missiles"
source = "Monk"
@property
def name(self):
mod = self.owner.dexterity.modifier + self.owner.Monk.level
@@ -182,6 +189,7 @@ class SlowFall(Feature):
times your monk level.
"""
name = "Slow Fall"
source = "Monk"
@@ -189,8 +197,9 @@ class SlowFall(Feature):
class ExtraAttackMonk(Feature):
"""Beginning at 5th level, you can attack twice, instead of once,
whenever you take the Attack action on your turn
"""
name = "Extra Attack (2x)"
source = "Monk"
@@ -201,8 +210,9 @@ class StunningStrike(Feature):
attack, you can spend 1 ki point to attempt a stunning strike. The
target must succeed on a Constitution saving throw or be stunned
until the end of your next turn
"""
name = "Stunning Strike"
source = "Monk"
@@ -211,8 +221,9 @@ class KiEmpoweredStrikes(Feature):
"""Starting at 6th level, your unarmed strikes count as magical for
the purpose of overcoming resistance and immunity to nonmagical
attacks and damage
"""
name = "Ki-Empowered Strikes"
source = "Monk"
@@ -220,8 +231,9 @@ class KiEmpoweredStrikes(Feature):
class StillnessOfMind(Feature):
"""Starting at 7th level, you can use your action to end one effect on
yourself that is causing you to be charmed or frightened
"""
name = "Stillness of Mind"
source = "Monk"
@@ -229,8 +241,9 @@ class StillnessOfMind(Feature):
class PurityOfBody(Feature):
"""At 10th level, your mastery of the ki flowing through you makes you
immune to disease and poison.
"""
name = "Purity of Body"
source = "Monk"
@@ -239,8 +252,9 @@ class TongueOfTheSunAndMoon(Feature):
"""Starting at 13th level, you learn to touch the ki of other minds so
that you understand all spoken languages. Moreover, any creature
that can understand a language can understand what you say.
"""
name = "Tongue of the Sun and Moon"
source = "Monk"
@@ -250,8 +264,9 @@ class DiamondSoul(Feature):
in all saving throws. Additionally, whenever you make a saving
throw and fail, you can spend 1 ki point to reroll it and take the
second result.
"""
name = "Diamond Soul"
source = "Monk"
@@ -261,8 +276,9 @@ class TimelessBody(Feature):
frailty of old age, and you can't be aged magically. You can still
die of old age, however. In addition, you no longer need food or
water.
"""
name = "Timeless Body"
source = "Monk"
@@ -274,8 +290,9 @@ class EmptyBody(Feature):
you can spend 8 ki points to cast the astral projection spell,
without needing material components. When you do so, you can't
take any other creatures with you.
"""
name = "Empty Body"
source = "Monk"
@@ -283,8 +300,9 @@ class EmptyBody(Feature):
class PerfectSelf(Feature):
"""At 20th level, when you roll for initiative and have no ki points
remaining, you regain 4 ki points.
"""
name = "Perfect Self"
source = "Monk"
@@ -296,13 +314,14 @@ class OpenHandTechnique(Feature):
hit a creature with one of the attacks granted by your *Flurry of
Blows*, you can impose one of the following effects on that
target:
- It must succeed on a Dexterity saving throw or be knocked prone.
- It must make a Strength saving throw. If it fails, you can push
it up to 15 feet away from you.
- It can't take reactions until the end of your next turn
"""
name = "Open Hand Technique"
source = "Monk (Way of the Open Hand)"
@@ -312,8 +331,9 @@ class WholenessOfBody(Feature):
you can regain hit points equal to three times your monk
level. You must finish a long rest before you can use this feature
again
"""
name = "Wholeness of Body"
source = "Monk (Way of the Open Hand)"
@@ -325,8 +345,9 @@ class Tranquility(Feature):
start of your next long rest (the spell can end early as
normal). The saving throw DC for the spell equals 8 + your Wisdom
modifier + your proficiency bonus
"""
name = "Tranquility"
source = "Monk (Way of the Open Hand)"
@@ -344,8 +365,9 @@ class QuiveringPalm(Feature):
have only one creature under the effect of this feature at a
time. You can choose to end the vibrations harmlessly without
using an action.
"""
name = "Quivering Palm"
source = "Monk (Way of the Open Hand)"
@@ -358,8 +380,9 @@ class ShadowArts(Feature):
without trace, or silence, without providing material
components. Additionally, you gain the minor illusion cantrip if
you don't already know it.
"""
name = "Shadow Arts"
source = "Monk (Way of Shadow)"
@@ -370,8 +393,9 @@ class ShadowStep(Feature):
you can teleport up to 60 feet to an unoccupied space you can see
that is also in dim light or darkness. You then have advantage on
the first melee attack you make before the end of the turn.
"""
name = "Shadow Step"
source = "Monk (Way of Shadow)"
@@ -382,8 +406,9 @@ class CloakOfShadows(Feature):
use your action to become invisible. You remain invisible until
you make an attack, cast a spell, or are in an area of bright
light.
"""
name = "Cloak of Shadows"
source = "Monk (Way of Shadow)"
@@ -393,8 +418,9 @@ class Opportunist(Feature):
when it is hit by an attack. Whenever a creature within 5 feet of
you is hit by an attack made by a creature other than you, you can
use your reaction to make a melee attack against that creature.
"""
name = "Opportunist"
source = "Monk (Way of Shadow)"
@@ -407,14 +433,14 @@ class DiscipleOfTheElements(Feature):
it. You know the Elemental Attunement discipline and one other
elemental discipline of your choice, which are detailed in the
"Elemental Disciplines" section below.
You learn one additional elemental discipline of your choice at
6th, 11th, and 17th level. Whenever you learn a new elemental
discipline, you can also replace one elemental discipline that you
already know with a different discipline.
Add your chosen disciplines under "features" in your .py file
**Casting Elemental Spells:** Some elemental disciplines allow you
to cast spells. See chapter 10 for the general rules of
spellcasting. To cast one o f these spells, you use its casting
@@ -443,6 +469,7 @@ class DiscipleOfTheElements(Feature):
Monk Levels 17-20 : 6 Ki points Max
"""
name = "Disciple of the Elements"
source = "Monk (Way of the Four Elements)"
@@ -450,7 +477,7 @@ class DiscipleOfTheElements(Feature):
class ElementalAttunement(Feature):
"""You can use your action to briefly control elemental forces nearby,
causing one of the following effects of your choice:
- Create a harmless, instantaneous sensory effect related to air,
earth, fire, or water, such as a shower of sparks, a puff of
wind, a spray o f light mist, or a gentle rumbling of stone.
@@ -461,18 +488,20 @@ class ElementalAttunement(Feature):
- Cause earth, fire, water, or mist that can fit within a 1-foot
cube to shape itself into a crude form you desig nate for 1
minute.
"""
name = "Elemental Attunement"
source = "Monk (Way of the Four Elements)"
class BreathOfWinter(Feature):
"""You can spend 6 ki points to cast cone of cold.
**Prerequisite:** 17th Level
"""
name = "Breath of Winter"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.ConeOfCold,)
@@ -480,10 +509,11 @@ class BreathOfWinter(Feature):
class ClenchOfTheNorthWind(Feature):
"""You can spend 3 ki points to cast hold person.
**Prerequisite:** 6th Level
"""
name = "Clench of the North Wind"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.HoldPerson,)
@@ -491,10 +521,11 @@ class ClenchOfTheNorthWind(Feature):
class EternalMountainDefense(Feature):
"""You can spend 5 ki points to cast stoneskin, targeting yourself.
**Prerequisite:** 11th Level
"""
name = "Eternal Mountain Defense"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.Stoneskin,)
@@ -508,14 +539,16 @@ class FangsOfTheFireSnake(Feature):
such an attack deals fire damage instead of bludgeoning damage,
and if you spend 1 ki point when the attack hits, it also deals an
extra 1d10 fire damage
"""
name = "Fangs of the Fire Snake"
source = "Monk (Way of the Four Elements)"
class FistOfFourThunders(Feature):
"""You can spend 2 ki points to cast thunderwave."""
name = "Fist of Four Thunders"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.Thunderwave,)
@@ -531,18 +564,20 @@ class FistOfUnbrokenAir(Feature):
20 feet away from you and knock it prone. On a successful save,
the creature takes half as much damage, and you don't push it or
knock it prone.
"""
name = "Fist of Unbroken Air"
source = "Monk (Way of the Four Elements)"
class FlamesOfThePhoenix(Feature):
"""You can spend 4 ki points to cast fireball.
**Prerequisite:** 11th Level
"""
name = "Flames of the Phoenix"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.Fireball,)
@@ -550,10 +585,11 @@ class FlamesOfThePhoenix(Feature):
class GongOfTheSummit(Feature):
"""You can spend 3 ki points to cast shatter.
**Prerequisite:** 6th Level
"""
name = "Gong of the Summit"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.Shatter,)
@@ -561,10 +597,11 @@ class GongOfTheSummit(Feature):
class MistStance(Feature):
"""You can spend 4 ki points to cast gaseous form, targeting yourself.
**Prerequisite:** 11th Level
"""
name = "Mist Stance"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.GaseousForm,)
@@ -576,6 +613,7 @@ class RideTheWind(Feature):
**Prerequisite:** 11th Level
"""
name = "Ride the Wind"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.Fly,)
@@ -587,15 +625,15 @@ class RiverOfHungryFlame(Feature):
**Prerequisite:** 17th Level
"""
name = "River of Hungry Flame"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.WallOfFire,)
class RushOfTheGaleSpirits(Feature):
"""You can spend 2 ki points to cast gust of wind.
"""You can spend 2 ki points to cast gust of wind."""
"""
name = "Rush of the Gale Spirits"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.GustOfWind,)
@@ -614,14 +652,16 @@ class ShapeTheFlowingRiver(Feature):
elevation by up to 15 feet, dig a trench up to 15 feet deep, and
so on. You can't shape the ice to trap or injure a creature in the
area.
"""
name = "Shape the Flowing River"
source = "Monk (Way of the Four Elements)"
class SweepingCinderStrike(Feature):
"""You can spend 2 ki points to cast burning hands."""
name = "Sweeping Cinder Strike"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.BurningHands,)
@@ -639,16 +679,18 @@ class WaterWhip(Feature):
it prone
"""
name = "Water Whip"
source = "Monk (Way of the Four Elements)"
class WaveOfRollingEarth(Feature):
"""You can spend 6 ki points to cast wall of stone
**Prerequisite:** 17th Level
"""
name = "Wave of Rolling Earth"
source = "Monk (Way of the Four Elements)"
spells_known = (spells.WallOfStone,)
@@ -663,7 +705,8 @@ class TouchOfDeath(Feature):
level (minimum of 1 temporary hit point)
"""
name = 'Touch of Death'
name = "Touch of Death"
source = "Monk (Way of the Sun Soul)"
@@ -675,6 +718,7 @@ class HourOfReaping(Feature):
the end of your next turn
"""
name = "Hour of Reaping"
source = "Monk (Way of the Sun Soul)"
@@ -685,6 +729,7 @@ class MasteryOfDeath(Feature):
action required) to have 1 hit point instead
"""
name = "Mastery of Death"
source = "Monk (Way of the Sun Soul)"
@@ -697,6 +742,7 @@ class TouchOfTheLongDeath(Feature):
save, or half as much damage on a suc- cessful one
"""
name = "Touch of the Long Death"
source = "Monk (Way of the Sun Soul)"
@@ -715,12 +761,13 @@ class RadiantSunBolt(Feature):
attacks with it as a bonus action.
"""
name = "Radiant Sun Bolt"
source = "Monk (Way of the Sun Soul)"
def __init__(self, owner=None):
super().__init__(owner=owner)
self.owner.wield_weapon("sun bolt")
super().__init__(owner=owner)
self.owner.wield_weapon("sun bolt")
class SearingArcStrike(Feature):
@@ -734,6 +781,7 @@ class SearingArcStrike(Feature):
down)
"""
name = "Searing Arc Strike"
source = "Monk (Way of the Sun Soul)"
spells_known = (spells.BurningHands,)
@@ -751,6 +799,7 @@ class SearingSunburst(Feature):
maximum of 3, increases the damage by 2d6.
"""
name = "Searing Sunburst"
source = "Monk (Way of the Sun Soul)"
@@ -764,6 +813,7 @@ class SunShield(Feature):
Wisdom modifier
"""
name = "Sun Shield"
source = "Monk (Way of the Sun Soul)"
@@ -776,6 +826,7 @@ class DrunkenTechnique(Feature):
end of the current turn
"""
name = "Drunken Technique"
source = "Monk (Way of the Drunken Master)"
@@ -793,6 +844,7 @@ class TipsySway(Feature):
feet of you.
"""
name = "Tipsy Sway"
source = "Monk (Way of the Drunken Master)"
@@ -804,6 +856,7 @@ class DrunkardsLuck(Feature):
the disadvantage for that roll
"""
name = "Drunkard's Luck"
source = "Monk (Way of the Drunken Master)"
@@ -816,6 +869,7 @@ class IntoxicatedFrenzy(Feature):
targets a different creature this turn
"""
name = "Intoxicated Frenzy"
source = "Monk (Way of the Drunken Master)"
@@ -853,6 +907,7 @@ class PathOfTheKensei(Feature):
calligrapher's supplies or painter's supplies
"""
name = "Path of the Kensei"
source = "Monk (Way of the Kensei)"
@@ -871,6 +926,7 @@ class OneWithTheBlade(Feature):
your turns.
"""
name = "One with the Blade"
source = "Monk (Way of the Kensei)"
@@ -885,6 +941,7 @@ class SharpenTheBlade(Feature):
rolls
"""
name = "Sharpen the Blade"
source = "Monk (Way of the Kensei)"
@@ -896,5 +953,6 @@ class UnerringAccuracy(Feature):
turns.
"""
name = "Unerring Accuracy"
source = "Monk (Way of the Kensei)"
+35 -13
View File
@@ -1,4 +1,3 @@
from dungeonsheets import armor, weapons
from dungeonsheets.features.features import Feature, FeatureSelector
from dungeonsheets.features.fighter import GreatWeaponFighting, Protection
from dungeonsheets.features.ranger import Defense, Dueling
@@ -20,13 +19,14 @@ class DivineSense(Feature):
modifier. When you finish a long rest, you regain all expended uses.
"""
_name = "Divine Sense"
source = "Paladin"
@property
def name(self):
num_uses = max(1, 1+self.owner.charisma.modifier)
return self._name + ' ({:d}x/LR)'.format(num_uses)
num_uses = max(1, 1 + self.owner.charisma.modifier)
return self._name + " ({:d}x/LR)".format(num_uses)
class LayOnHands(Feature):
@@ -46,13 +46,14 @@ class LayOnHands(Feature):
This feature has no effect on undead and constructs
"""
_name = "Lay on Hands"
source = "Paladin"
@property
def name(self):
level = self.owner.Paladin.level
return self._name + " ({:d}HP/LR)".format(level*5)
level = self.owner.Paladin.level
return self._name + " ({:d}HP/LR)".format(level * 5)
class PaladinFightingStyle(FeatureSelector):
@@ -67,11 +68,14 @@ class PaladinFightingStyle(FeatureSelector):
protection
"""
options = {'defense': Defense,
'dueling': Dueling,
'great': GreatWeaponFighting,
'great-weapon fighting': GreatWeaponFighting,
'projection': Protection}
options = {
"defense": Defense,
"dueling": Dueling,
"great": GreatWeaponFighting,
"great-weapon fighting": GreatWeaponFighting,
"projection": Protection,
}
name = "Fighting Style (Select One)"
source = "Paladin"
@@ -84,13 +88,15 @@ class DivineSmite(Feature):
5d8. The damage increases by 1d8 if the target is an undead or a fiend.
"""
name = "Divine Smite"
source = "Paladin"
class DivineHealth(Feature):
"""By 3rd level, the divine magic flowing through you makes you immune to
disease """
disease"""
name = "Divine Health"
source = "Paladin"
@@ -100,6 +106,7 @@ class ExtraAttackPaladin(Feature):
take the Attack action on your turn
"""
name = "Extra Attack (2x)"
source = "Paladin"
@@ -113,6 +120,7 @@ class AuraOfProtection(Feature):
At 18th level, the range of this aura increases to 30 feet.
"""
name = "Aura of Protection"
source = "Paladin"
@@ -124,6 +132,7 @@ class AuraOfCourage(Feature):
At 18th level, the range of this aura increases to 30 feet
"""
name = "Aura of Courage"
source = "Paladin"
@@ -136,6 +145,7 @@ class ImprovedDivineSmite(Feature):
damage of your Divine Smite.
"""
name = "Improved Divine Smite"
source = "Paladin"
@@ -147,13 +157,14 @@ class CleansingTouch(Feature):
once). You regain expended uses when you finish a long rest.
"""
_name = "Cleansing Touch"
source = "Paladin"
@property
def name(self):
num_uses = max(1, 1+self.owner.charisma.modifier)
return self._name + ' ({:d}x/LR)'.format(num_uses)
num_uses = max(1, 1 + self.owner.charisma.modifier)
return self._name + " ({:d}x/LR)".format(num_uses)
class ChannelDivinityPaladin(Feature):
@@ -168,6 +179,7 @@ class ChannelDivinityPaladin(Feature):
effect from this class, the DC equals your paladin spell save DC.
"""
name = "Channel Divinity (1x/SR)"
source = "Paladin"
@@ -186,6 +198,7 @@ class SacredWeapon(Feature):
this effect ends.
"""
name = "Channel Divinity: Sacred Weapon"
source = "Paladin (Oath of Devotion)"
@@ -204,6 +217,7 @@ class TurnTheUnholy(Feature):
nowhere to move, the creature can use the Dodge action.
"""
name = "Channel Divinity: Turn the Unholy"
source = "Paladin (Oath of Devotion)"
@@ -214,6 +228,7 @@ class AuraOfDevotion(Feature):
aura increases to 30 feet.
"""
name = "Aura of Devotion"
source = "Paladin (Oath of Devotion)"
@@ -223,6 +238,7 @@ class PurityOfSpirit(Feature):
from evil and good spell.
"""
name = "Purity of Spirit"
source = "Paladin (Oath of Devotion)"
@@ -240,6 +256,7 @@ class HolyNimbus(Feature):
it again until you finish a long rest.
"""
name = "Holy Nimbus"
source = "Paladin (Oath of Devotion)"
@@ -252,6 +269,7 @@ class EmissaryOfPeace(Feature):
(Persuasion) checks for the next 10 minutes.
"""
name = "Channel Divinity: Emissary of Peace"
source = "Paladin (Oath of Redemption)"
@@ -265,6 +283,7 @@ class RebukeTheViolent(Feature):
successful save, it takes half as much damage.
"""
name = "Channel Divinity: Rebuke the Violent"
source = "Paladin (Oath of Redemption)"
@@ -278,6 +297,7 @@ class AuraOfTheGuardian(Feature):
the range of this aura increases to 30 feet.
"""
name = "Aura of the Guardian"
source = "Paladin (Oath of Redemption)"
@@ -289,6 +309,7 @@ class ProtectiveSpirit(Feature):
aren't incapacitated.
"""
name = "Protective Spirit"
source = "Paladin (Oath of Redemption)"
@@ -307,5 +328,6 @@ class EmissaryOfRedemption(Feature):
you finish a long rest
"""
name = "Emissary of Redemption"
source = "Paladin (Oath of Redemption)"
+131 -65
View File
@@ -1,4 +1,4 @@
from dungeonsheets import armor, spells
from dungeonsheets import spells
from dungeonsheets.features.features import Feature
@@ -10,6 +10,7 @@ class Darkvision(Feature):
color in darkness, only shades of gray.
"""
name = "Darkvision (60')"
source = "Race"
@@ -21,14 +22,17 @@ class SuperiorDarkvision(Feature):
color in darkness, only shades of gray.
"""
name = "Darkvision (120')"
source = "Race"
class PowerfulBuild(Feature):
"""You count as one size larger when determining your carrying
capacity and the weight you can push, drag, or lift.
"""
You count as one size larger when determining your carrying capacity and the weight you can push, drag, or lift.
"""
name = "Powerful Build"
source = "Race"
@@ -38,6 +42,7 @@ class Amphibious(Feature):
You can breath air and water
"""
name = "Amphibious"
source = "Race"
@@ -48,6 +53,7 @@ class DwarvenResilience(Feature):
against poison damage
"""
name = "Dwarven Resilience"
source = "Race (Dwarf)"
@@ -59,6 +65,7 @@ class Stonecunning(Feature):
proficiency bonus. Languages.
"""
name = "Stonecunning"
source = "Race (Dwarf)"
@@ -69,6 +76,7 @@ class DwarvenToughness(Feature):
increases by 1, and it increases by 1 every time you gain a level.
"""
name = "DwarvenToughness"
source = "Race (Hill Dwarf)"
needs_implementation = True
@@ -80,6 +88,7 @@ class FeyAncestry(Feature):
put you to sleep.
"""
name = "Fey Ancestry"
source = "Race (Elf)"
@@ -93,6 +102,7 @@ class Trance(Feature):
does from 8 hours of sleep.
"""
name = "Trance"
source = "Race (Elf)"
@@ -102,6 +112,7 @@ class ElfCantrip(Feature):
list. Intelligence is your spellcasting ability for it.
"""
name = "Cantrip"
source = "Race (High-Elf)"
needs_implementation = True
@@ -112,6 +123,7 @@ class MaskOfTheWild(Feature):
heavy rain, falling snow, mist, and other natural phenomena.
"""
name = "Mask of the Wild"
source = "Race (Wood Elf)"
@@ -122,6 +134,7 @@ class SunlightSensitivity(Feature):
trying to perceive is in direct sunlight.
"""
name = "Sunlight Sensitivity"
source = "Race (Dark Elf)"
@@ -133,6 +146,7 @@ class DrowMagic(Feature):
ability for these spells.
"""
name = "Drow Magic"
source = "Race (Dark Elf)"
spells_known = spells_prepared = (spells.DancingLights,)
@@ -144,14 +158,14 @@ class Lucky(Feature):
reroll the die and must use the new roll.
"""
name = "Lucky"
source = "Race (Halfling)"
class Brave(Feature):
"""You have advantage on saving throws against being frightened.
"""You have advantage on saving throws against being frightened."""
"""
name = "Brave"
source = "Race (Halfling)"
@@ -160,6 +174,7 @@ class HalflingNimbleness(Feature):
"""
You can move through the space of any creature that is of a size larger than yours.
"""
name = "Halfling Nimbleness"
source = "Race (Halfling)"
@@ -169,6 +184,7 @@ class NaturallyStealthy(Feature):
is at least one size larger than you.
"""
name = "Naturally Stealthy"
source = "Race (Lightfoot Halfling)"
@@ -178,6 +194,7 @@ class StoutResilience(Feature):
against poison damage.
"""
name = "Stout Resilience"
source = "Race (Stout Halfling)"
@@ -189,7 +206,7 @@ class DraconicAncestry(Feature):
"""You have draconic ancestry. Choose one type of dragon from the Draconic
Ancestry table. Your breath weapon and damage resistance are determined by the
dragon type.
====== =========== ===========================
Dragon Damage Type Breath Weapon
====== =========== ===========================
@@ -204,8 +221,9 @@ class DraconicAncestry(Feature):
Silver Cold 15 ft. cone (CON save)
White White 15 ft. cone (CON save)
====== =========== ===========================
"""
name = "Draconic Ancestry"
source = "Race (Dragonborn)"
@@ -223,6 +241,7 @@ class BreathWeapon(Feature):
long rest. Damage
"""
name = "Breath Weapon"
source = "Race (Dragonborn)"
@@ -232,6 +251,7 @@ class DraconicResistance(Feature):
ancestry. Languages.
"""
name = "Damage Resistance"
source = "Race (Dragonborn)"
@@ -242,6 +262,7 @@ class GnomeCunning(Feature):
against magic.
"""
name = "Gnome Cunning"
source = "Race (Gnome)"
@@ -251,6 +272,7 @@ class NaturalIllusionist(Feature):
ability for it.
"""
name = "Natural Illusionist"
source = "Race (Forest Gnome)"
@@ -262,6 +284,7 @@ class SpeakWithSmallBeasts(Feature):
"""
name = "Speak with Small Beasts"
source = "Race (Forest Gnome)"
@@ -273,6 +296,7 @@ class ArtificersLore(Feature):
apply. Tinker.
"""
name = "Artificer's Lore"
source = "Race (Rock Gnome)"
@@ -299,6 +323,7 @@ class Tinker(Feature):
volume. The box stops playing when it reaches the song's end or when
"""
name = "Tinker"
source = "Race (Rock Gnome)"
@@ -307,30 +332,11 @@ class StoneCamouflage(Feature):
"""
You have advantage on Dexterity (stealth) checks to hide in rocky terrain.
"""
name = "Stone Camouflage"
source = "Race (Deep Gnome)"
# Goblins
class FuryOfTheSmall(Feature):
"""
When you damage a creature with an attack or a spell and the creature's
size is larger than yours, you can cause the attack or spell to deal extra
damage to the creature. The extra damage equals your level. Once you use
this trait, you can't use it again until you finish a short or long rest.
"""
name = "Fury of the Small"
source = "Race (Goblin)"
class NimbleEscape(Feature):
"""
You can take the Disengage or Hide action as a bonus action on each of your
turns.
"""
name = "Nimble Escape"
source = "Race (Goblin)"
# Half-Elves
# Half-Orcs
@@ -340,6 +346,7 @@ class RelentlessEndurance(Feature):
long rest.
"""
name = "Relentless Endurance"
source = "Race (Half-Orc)"
@@ -350,15 +357,15 @@ class SavageAttacks(Feature):
damage of the critical hit.
"""
name = "Savage Attacks"
source = "Race (Half-Orc)"
# Tiefling
class HellishResistance(Feature):
"""You have resistance to fire damage.
"""You have resistance to fire damage."""
"""
name = "Hellish Resistance"
source = "Race (Tiefling)"
@@ -370,6 +377,7 @@ class InfernalLegacy(Feature):
your spellcasting ability for these spells.
"""
name = "Infernal Legacy"
source = "Race (Tiefling)"
spells_known = spells_prepared = (spells.Thaumaturgy,)
@@ -381,6 +389,7 @@ class CelestialResistance(Feature):
You have resistance to necrotic damage and radiant damage.
"""
name = "Celestial Resistance"
source = "Race (Aasimar)"
@@ -391,14 +400,14 @@ class HealingHands(Feature):
again until you finish a long rest.
"""
name = "Healing Hands"
source = "Race (Aasimar)"
class LightBearer(Feature):
"""You know the light cantrip. Charisma is your spellcasting ability for it.
"""You know the light cantrip. Charisma is your spellcasting ability for it."""
"""
name = "Light Bearer"
source = "Race (Aasimar)"
@@ -418,6 +427,7 @@ class RadiantSoul(Feature):
rest.
"""
name = "Radiant Soul"
source = "Race (Protector Aasimar)"
@@ -439,6 +449,7 @@ class RadiantConsumption(Feature):
rest.
"""
name = "Radiant Consumption"
source = "Race (Scourge Aasimar)"
@@ -461,6 +472,7 @@ class NecroticShroud(Feature):
rest.
"""
name = "Necrotic Shroud"
source = "Race (Fallen Aasimar)"
@@ -475,6 +487,7 @@ class FirbolgMagic(Feature):
elves.
"""
name = "Firbolg Magic"
source = "Race (Firbolg)"
@@ -486,6 +499,7 @@ class HiddenStep(Feature):
finish a short or long rest.
"""
name = "Hidden Step"
source = "Race (Firbolg)"
@@ -497,6 +511,7 @@ class SpeechOfBeastAndLeaf(Feature):
Charisma checks you make to influence them.
"""
name = "Speech of Beast and Leaf"
source = "Race (Firbolg)"
@@ -510,6 +525,7 @@ class StonesEndurance(Feature):
rest.
"""
name = "Stones Endurance"
source = "Race (Goliath)"
@@ -520,6 +536,7 @@ class MountainBorn(Feature):
chapter 5 of the Dungeon Master's Guide.
"""
name = "Mountain Born"
source = "Race (Goliath)"
@@ -531,6 +548,7 @@ class ExpertForgery(Feature):
objects.
"""
name = "Expert Forgery"
source = "Race (Kenku)"
@@ -541,6 +559,7 @@ class Mimicry(Feature):
Wisdom (Insight) check opposed by your Charisma (Deception) check.
"""
name = "Mimicry"
source = "Race (Kenku)"
@@ -555,6 +574,7 @@ class CunningArtisan(Feature):
tools.
"""
name = "Cunning Artisan"
source = "Race (Lizardfolk)"
@@ -563,6 +583,7 @@ class HoldBreath(Feature):
"""
You can hold your breath for up to 15 minutes at a time.
"""
name = "Hold Breath"
source = "Race (Lizardfolk)"
@@ -574,17 +595,18 @@ class NaturalArmor(Feature):
benefits apply as normal while you use your natural armor.
"""
name = "Natural Armor"
source = "Race (Lizardfolk)"
def AC_func(self, char, **kwargs):
"""
Implement the Natural Armor AC option
"""
ac = 13 + char.dexterity.modifier
if ((char.shield is not None)):
ac += char.shield.base_armor_class
return ac
"""
Implement the Natural Armor AC option
"""
ac = 13 + char.dexterity.modifier
if char.shield is not None:
ac += char.shield.base_armor_class
return ac
class HungryJaws(Feature):
@@ -595,6 +617,7 @@ class HungryJaws(Feature):
until you finish a short or long rest.
"""
name = "Hungry Jaws"
source = "Race (Lizardfolk)"
@@ -607,12 +630,14 @@ class FelineAgility(Feature):
on one of your turns.
"""
name = "Feline Agility"
source = "Race (Tabaxi)"
# Triton
class ControlAirAndWater(Feature):
"""A child of the sea, you can call on the magic of elemental air and
water. You can cast fog cloud with this trait. Starting at 3rd level, you
@@ -622,6 +647,7 @@ class ControlAirAndWater(Feature):
rest. Charisma is your spellcasting ability for these spells.
"""
name = "Control Air and Water"
source = "Race (Triton)"
@@ -633,6 +659,7 @@ class EmissaryOfTheSea(Feature):
understand them in return.
"""
name = "Emissary Of The Sea"
source = "Race (Triton)"
@@ -643,6 +670,7 @@ class GuardiansOfTheDepths(Feature):
environment.
"""
name = "Guardians of the Depths"
source = "Race (Triton)"
@@ -651,9 +679,8 @@ class GuardiansOfTheDepths(Feature):
# Genasi
class UnendingBreath(Feature):
"""You can hold your breath indefinitely while you're not incapacitated.
"""You can hold your breath indefinitely while you're not incapacitated."""
"""
name = "Unending Breath"
source = "Race (Air Genasi)"
@@ -664,6 +691,7 @@ class MingleWithTheWind(Feature):
a long rest. Constitution is your spellcasting ability for this spell.
"""
name = "Mingle with the Wind"
source = "Race (Air Genasi)"
@@ -673,6 +701,7 @@ class EarthWalk(Feature):
expending extra movement.
"""
name = "Earth Walk"
source = "Race (Earth Genasi)"
@@ -684,6 +713,7 @@ class MergeWithStone(Feature):
spell.
"""
name = "Merge with Stone"
source = "Race (Earth Genasi)"
@@ -692,6 +722,7 @@ class FireResistance(Feature):
"""
You have resistance to fire damage.
"""
name = "Fire Resistance"
source = "Race (Fire Genasi)"
@@ -703,6 +734,7 @@ class ReachToTheBlaze(Feature):
rest. Constitution is your spellcasting ability for these spells.
"""
name = "Reach to the Blaze"
source = "Race (Fire Genasi)"
@@ -712,6 +744,7 @@ class AcidResistance(Feature):
You have resistance to acid damage.
"""
name = "Acid Resistance"
source = "Race (Water Genasi)"
@@ -724,27 +757,34 @@ class CallToTheWave(Feature):
spells.
"""
name = "Call to the Wave"
source = "Race (Water Genasi)"
# RFTLW Races
class DualMind(Feature):
"""
You have advantage on all Wisdom saving throws.
"""
name = "Dual Mind"
source = "Race (Kalashtar)"
class MentalDiscipline(Feature):
"""
You have resistance to psychic damage.
"""
name = "Mental Discipline"
source = "Race (Kalashtar)"
class MindLink(Feature):
"""
You can speak telepathically to any creature you can see, provided
@@ -762,9 +802,11 @@ class MindLink(Feature):
takes it away from another creature who has it.
"""
name = "Mind Link"
source = "Race (Kalashtar)"
class SeveredFromDreams(Feature):
"""
Kalashtar sleep, but they don't connect to the plane of dreams as
@@ -775,46 +817,58 @@ class SeveredFromDreams(Feature):
you to sleep, like 'sleep'.
"""
name = "Severed from Dreams"
source = "Race (Kalashtar)"
#monsterous races
#bugbear
# monsterous races
# bugbear
class LongLimbed(Feature):
""" When you make a melee attack on your turn, your reach for it is 5 feet greater than normal.
"""When you make a melee attack on your turn, your reach for it is 5
feet greater than normal.
"""
name = "Long-Limbed"
source = "Race (BugBear)"
class SupriseAttack(Feature):
""" If you surprise a creature and hit it with an attack on your first turn
"""If you surprise a creature and hit it with an attack on your first turn
in combat, the attack deals an extra 2d6 damage to it. You can use this trait
only once per combat.
"""
name = "Suprise Attack"
source = "Race (BugBear)"
#goblin
class FuryOfTheSmall(Feature):
"""When you damage a creature with an attack or a spell and the creature's size
is larger than yours, you can cause the attack or spell to deal extra damage to
the creature. The extra damage equals your level. Once you use this trait, you
can't use it again until you finish a short or long rest.
# Goblins
class FuryOfTheSmall(Feature):
"""
When you damage a creature with an attack or a spell and the creature's
size is larger than yours, you can cause the attack or spell to deal extra
damage to the creature. The extra damage equals your level. Once you use
this trait, you can't use it again until you finish a short or long rest.
"""
name = "Fury of the Small"
source = "Race (Goblin)"
class NimbleEscape(Feature):
""" You can take the Disengage or Hide action as a bonus action on each of your turns.
class NimbleEscape(Feature):
"""
You can take the Disengage or Hide action as a bonus action on each of your
turns.
"""
name = "Nimble Escape"
source = "Race (Goblin)"
#HobGoblin
# HobGoblin
class SavingFace(Feature):
"""Hobgoblins are careful not to show weakness in front of their allies, for fear
of losing status. If you miss with an attack roll or fail an ability check or a
@@ -823,19 +877,24 @@ class SavingFace(Feature):
can't use it again until you finish a short or long rest.
"""
name = "Saving Face"
source = "Race (HobGoblin)"
class MartialTraining(Feature): #you have to add the weapons of choice to your sheet
"""You are proficient with two martial weapons of your choice and with light armor.
class MartialTraining(Feature): # you have to add the weapons of choice to your sheet
"""You are proficient with two martial weapons of your choice and with
light armor.
"""
name = "Martial Training"
source = "Race (HobGoblin)"
#kobold
# kobold
class GrovelCowerAndBeg(Feature):
""" As an action on your turn, you can cower pathetically to
"""As an action on your turn, you can cower pathetically to
distract nearby foes. Until the end of your next turn, your
allies gain advantage on attack rolls against enemies
within 10 feet of you that can see you. Once you use this
@@ -843,27 +902,33 @@ class GrovelCowerAndBeg(Feature):
or long rest
"""
name = "Grovel Cower and Beg"
source = "Race (Kobold)"
class PackTactics(Feature):
"""You have advantage on an attack roll against a creature
if at least one of your allies is within 5 feet of the
creature and the ally isn't incapacitated.
"""
name = "Pack Tactics"
source = "Race (Kobold)"
class Aggressive(Feature):
""" As a bonus action, you can move up to your speed
"""As a bonus action, you can move up to your speed
toward an enemy of your choice that you can see or hear.
You must end this move closer to the enemy than you started.
"""
name = "Aggressive"
source = "Race (Orc)"
#yuan-ti pureblood
# yuan-ti pureblood
class InnateSpellcasting(Feature):
"""You know the poison spray cantrip. You can cast animal
friendship an unlimited number of times with this trait,
@@ -873,19 +938,20 @@ class InnateSpellcasting(Feature):
your spellcasting ability for these spells.
"""
name = "Innate Spellcasting"
source = "Race (Yuan-Ti Pureblood)"
class MagicResistance(Feature):
""" You have advantage on saving throws against spells and other magical effects.
"""
class MagicResistance(Feature):
"""You have advantage on saving throws against spells and other magical effects."""
name = "Magic Resistance"
source = "Race (Yuan_Ti Pureblood)"
class PoisonImmunity(Feature):
"""You are immune to poison damage and the poi~oned condition.
"""
class PoisonImmunity(Feature):
"""You are immune to poison damage and the poi~oned condition."""
name = "Poison Immunity"
source = "Race (Yuan_Ti Pureblood)"
+111 -47
View File
@@ -1,4 +1,4 @@
from dungeonsheets import armor, weapons
from dungeonsheets import weapons
from dungeonsheets.features.features import Feature, FeatureSelector
from dungeonsheets.features.rogue import Evasion, UncannyDodge
@@ -22,6 +22,7 @@ class FavoredEnemy(Feature):
monsters you have encountered on your adventures.
"""
name = "Favored Enemy"
source = "Ranger"
languages = ("[Select One]",)
@@ -33,13 +34,13 @@ class NaturalExplorer(Feature):
one type of favored terrain: arctic, coast, desert, forest,
grassland, mountain, swamp, or the Underdark. You choose
additional favored terrain types at 6th and 10th
When you make an Intelligence or Wisdom check related to your
favored terrain, your proficiency bonus is doubled if you are
using a skill that you're proficient in. While traveling for an
hour or more in your favored terrain, you gain the following
benefits:
- Difficult terrain doesn't slow your group's travel.
- Your group can't become lost except by magical means.
- Even when you are engaged in another activity while traveling
@@ -54,6 +55,7 @@ class NaturalExplorer(Feature):
area.
"""
name = "Natural Explorer"
source = "Ranger"
@@ -63,15 +65,16 @@ class Archery(Feature):
You gain a +2 bonus to attack rolls you make
with ranged weapons (included in stats on Character Sheet).
"""
name = "Fighting Style (Archery)"
source = "Ranger"
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""
+2 attack roll bonus if weapon is ranged
"""
if isinstance(weapon, weapons.RangedWeapon):
weapon.attack_bonus += 2
"""
+2 attack roll bonus if weapon is ranged
"""
if isinstance(weapon, weapons.RangedWeapon):
weapon.attack_bonus += 2
class Defense(Feature):
@@ -79,6 +82,7 @@ class Defense(Feature):
While you are wearing armor, you gain a +1 bonus to AC (included in
stats on Character Sheet).
"""
name = "Fighting Style (Defense)"
source = "Ranger"
@@ -88,16 +92,19 @@ class Dueling(Feature):
gain a +2 bonus to damage rolls with that weapon.
"""
name = "Fighting Style (Dueling)"
source = "Ranger"
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""
+2 attack roll bonus if melee weapon is not two handed
"""
if (isinstance(weapon, weapons.MeleeWeapon)
and "two-handed" not in weapon.properties.lower()):
weapon.damage_bonus += 2
"""
+2 attack roll bonus if melee weapon is not two handed
"""
if (
isinstance(weapon, weapons.MeleeWeapon)
and "two-handed" not in weapon.properties.lower()
):
weapon.damage_bonus += 2
class TwoWeaponFighting(Feature):
@@ -105,6 +112,7 @@ class TwoWeaponFighting(Feature):
to the damage of the second attack.
"""
name = "Fighting Style (Two-Weapon Fighting)"
source = "Ranger"
@@ -121,12 +129,15 @@ class RangerFightingStyle(FeatureSelector):
two-weapon fighting
"""
options = {'archery': Archery,
'defense': Defense,
'dueling': Dueling,
'two-weapon fighting': TwoWeaponFighting,
'two-weapon': TwoWeaponFighting,
'dual wield': TwoWeaponFighting}
options = {
"archery": Archery,
"defense": Defense,
"dueling": Dueling,
"two-weapon fighting": TwoWeaponFighting,
"two-weapon": TwoWeaponFighting,
"dual wield": TwoWeaponFighting,
}
name = "Fighting Style (Select One)"
source = "Ranger"
@@ -141,6 +152,7 @@ class PrimevalAwareness(Feature):
the creatures' location or number.
"""
name = "Primeval Awareness"
source = "Ranger"
@@ -150,6 +162,7 @@ class ExtraAttackRanger(Feature):
take the Attack action on your turn.
"""
name = "Extra Attack (2x)"
source = "Ranger"
@@ -167,6 +180,7 @@ class HideInPlainSight(Feature):
a reaction, you must camouflage yourself again to gain this benefit
"""
name = "Hide in Plain Sight"
source = "Ranger"
@@ -177,6 +191,7 @@ class Vanish(Feature):
choose to leave a trail.
"""
name = "Vanish"
source = "Ranger"
@@ -190,6 +205,7 @@ class FeralSenses(Feature):
deafened
"""
name = "Feral Senses"
source = "Ranger"
@@ -202,6 +218,7 @@ class FoeSlayer(Feature):
before any effects of the roll are applied.
"""
name = "Foe Slayer"
source = "Ranger"
@@ -213,6 +230,7 @@ class ColossusSlayer(Feature):
its hit point maximum. You can deal this extra damage only once per turn.
"""
name = "Colossus Slayer"
source = "Ranger (Hunter)"
@@ -223,6 +241,7 @@ class GiantKiller(Feature):
immediately after its attack, provided that you can see the creature.
"""
name = "Giant Killer"
source = "Ranger (Hunter)"
@@ -233,6 +252,7 @@ class HordeBreaker(Feature):
within 5 feet of the original target and within range of your weapon.
"""
name = "Horde Breaker"
source = "Ranger (Hunter)"
@@ -248,17 +268,19 @@ class HuntersPrey(FeatureSelector):
horde breaker
"""
options = {'colossus slayer': ColossusSlayer,
'giant killer': GiantKiller,
'horde breaker': HordeBreaker}
options = {
"colossus slayer": ColossusSlayer,
"giant killer": GiantKiller,
"horde breaker": HordeBreaker,
}
name = "Hunter's Prey (Select One)"
source = "Ranger (Hunter)"
class EscapeTheHorde(Feature):
"""Opportunity attacks against you are made with disadvantage
"""Opportunity attacks against you are made with disadvantage"""
"""
name = "Escape the Horde"
source = "Ranger (Hunter)"
@@ -268,14 +290,14 @@ class MultiattackDefense(Feature):
all subsequent attacks made by that creature for the rest of the turn.
"""
name = "Multiattack Defense"
source = "Ranger (Hunter)"
class SteelWill(Feature):
"""You have advantage on saving throws against being frightened.
"""You have advantage on saving throws against being frightened."""
"""
name = "Steel Will"
source = "Ranger (Hunter)"
@@ -291,9 +313,12 @@ class DefensiveTactics(FeatureSelector):
steel will
"""
options = {'escape the horde': EscapeTheHorde,
'multiattack defense': MultiattackDefense,
'steel will': SteelWill}
options = {
"escape the horde": EscapeTheHorde,
"multiattack defense": MultiattackDefense,
"steel will": SteelWill,
}
name = "Defensive Tactics (Select One)"
source = "Ranger (Hunter)"
@@ -305,6 +330,7 @@ class Volley(Feature):
separate attack roll for each target
"""
name = "Volley"
source = "Ranger (Hunter)"
@@ -314,6 +340,7 @@ class WhirlwindAttack(Feature):
creatures within 5 feet of you, with a separate attack roll for each target
"""
name = "Whirlwind Attack"
source = "Ranger (Hunter)"
@@ -327,8 +354,8 @@ class MultiattackRanger(FeatureSelector):
whirlwind attack
"""
options = {'volley': Volley,
'whirlwind attack': WhirlwindAttack}
options = {"volley": Volley, "whirlwind attack": WhirlwindAttack}
name = "Multiattack (Select One)"
source = "Ranger (Hunter)"
@@ -339,6 +366,7 @@ class StandAgainstTheTide(Feature):
creature (other than itself) of your choice
"""
name = "Stand Against the Tide"
source = "Ranger (Hunter)"
@@ -354,9 +382,12 @@ class SuperiorHuntersDefense(FeatureSelector):
uncanny dodge
"""
options = {'evasion': Evasion,
'stand against of the tide': StandAgainstTheTide,
'uncanny dodge': UncannyDodge}
options = {
"evasion": Evasion,
"stand against of the tide": StandAgainstTheTide,
"uncanny dodge": UncannyDodge,
}
name = "Superior Hunter's Defense (Select One)"
source = "Ranger (Hunter)"
@@ -386,6 +417,7 @@ class RangersCompanion(Feature):
hostile to you, either the same type of beast as before or a different one.
"""
name = "Ranger's Companion"
source = "Ranger (Beast Master)"
@@ -396,6 +428,7 @@ class ExceptionalTraining(Feature):
Dash, Disengage, Dodge, or Help action on its turn
"""
name = "Exceptional Training"
source = "Ranger (Beast Master)"
@@ -405,6 +438,7 @@ class BestialFury(Feature):
command it to use the Attack action.
"""
name = "Bestial Fury"
source = "Ranger (Beast Master)"
@@ -415,6 +449,7 @@ class ShareSpells(Feature):
feet of you
"""
name = "Share Spells"
source = "Ranger (Beast Master)"
@@ -430,7 +465,8 @@ class DreadAmbusher(Feature):
weapons damage type.
"""
name = 'Dread Ambusher'
name = "Dread Ambusher"
source = "Ranger (Gloom Stalker)"
@@ -442,6 +478,7 @@ class UmbralSight(Feature):
that darkness.
"""
name = "Umbral Sight"
source = "Ranger (Gloom Stalker)"
@@ -453,12 +490,13 @@ class IronMind(Feature):
Intelligence or Charisma saving throws (your choice)
"""
name = "Iron Mind"
source = "Ranger (Gloom Stalker)"
needs_implementation = True
def __init__(self, owner=None):
super().__init__(owner=owner)
super().__init__(owner=owner)
class StalkersFlurry(Feature):
@@ -468,6 +506,7 @@ class StalkersFlurry(Feature):
same action
"""
name = "Stalker's Flurry"
source = "Ranger (Gloom Stalker)"
@@ -480,6 +519,7 @@ class ShadowyDodge(Feature):
know the outcome of the attack roll.
"""
name = "Shadowy Dodge"
source = "Ranger (Gloom Stalker)"
@@ -492,6 +532,7 @@ class DetectPortal(Feature):
can't use it again until you finish a short or long rest.
"""
name = "Detect Portal"
source = "Ranger (Horizon Walker)"
@@ -505,15 +546,16 @@ class PlanarWarrior(Feature):
reach 11th level in this class, the extra damage increases to 2d8.
"""
_name = "Planar Warrior"
source = "Ranger (Horizon Walker)"
@property
def name(self):
if self.owner.Ranger.level < 11:
return self._name + " (1d8/f)"
else:
return self._name + " (2d8/f)"
if self.owner.Ranger.level < 11:
return self._name + " (1d8/f)"
else:
return self._name + " (2d8/f)"
class EtherealStep(Feature):
@@ -524,6 +566,7 @@ class EtherealStep(Feature):
short or long rest
"""
name = "Ethereal Step"
source = "Ranger (Horizon Walker)"
@@ -536,6 +579,7 @@ class DistantStrike(Feature):
attack with it against a third creature.
"""
name = "Distant Strike"
source = "Ranger (Horizon Walker)"
@@ -547,6 +591,7 @@ class SpectralDefense(Feature):
give yourself resistance to all of that attack's damage on this turn
"""
name = "Spectral Defense"
source = "Ranger (Horizon Walker)"
@@ -563,13 +608,14 @@ class HuntersSense(Feature):
once). You regain all expended uses of it when you finish a long rest.
"""
_name = "Hunter's Sense"
source = "Ranger (Monster Slayer)"
@property
def name(self):
num = max(1, self.owner.wisdom.modifier)
return self._num + " ({:d}x/LR)".format(num)
num = max(1, self.owner.wisdom.modifier)
return self._num + " ({:d}x/LR)".format(num)
class SlayersPrey(Feature):
@@ -581,6 +627,7 @@ class SlayersPrey(Feature):
long rest. It ends early if you designate a different creature
"""
name = "Slayer's Prey"
source = "Ranger (Monster Slayer)"
@@ -592,6 +639,7 @@ class SupernaturalDefense(Feature):
targets grapple, add 1d6 to your roll
"""
name = "Supernatural Defense"
source = "Ranger (Monster Slayer)"
@@ -605,6 +653,7 @@ class MagicUsersNemesis(Feature):
it again until you finish a short or long rest.
"""
name = "Magic User's Nemesis"
source = "Ranger (Monster Slayer)"
@@ -618,6 +667,7 @@ class SlayersCounter(Feature):
to the attack's normal effects
"""
name = "Slayer's Counter"
source = "Ranger (Monster Slayer)"
@@ -639,6 +689,7 @@ class FavoredEnemyRevised(Feature):
it. However, you are free to pick any language you wish to learn
"""
name = "Favored Enemy"
source = "Revised Ranger"
@@ -647,15 +698,15 @@ class NaturalExplorerRevised(Feature):
"""You are a master of navigating the natural world, and you react
with swift and decisive action when attacked. This grants you the
following benefits:
- You ignore difficult terrain.
- You have advantage on initiative rolls.
- On your first turn during combat, you have advantage on attack rolls
against creatures that have not yet acted.
In addition, you are skilled at navigating the wilderness. You
gain the following benefits when traveling for an hour or more:
- Difficult terrain doesn't slow your group's travel.
- Your group can't become lost except by magical means.
- Even when you are engaged in another activity while traveling
@@ -668,8 +719,9 @@ class NaturalExplorerRevised(Feature):
- While tracking other creatures, you also learn their exact
number, their sizes, and how long ago they passed through the
area.
"""
name = "Natural Explorer"
source = "Revised Ranger"
@@ -699,6 +751,7 @@ class PrimevalAwarenessRevised(Feature):
learn this information for each group.
"""
name = "Primeval Awareness"
source = "Revised Ranger"
@@ -715,6 +768,7 @@ class GreaterFavoredEnemy(Feature):
abilities used by a greater favored enemy.
"""
name = "Greated Favored Enemy"
source = "Revised Ranger"
@@ -724,6 +778,7 @@ class FleetOfFoot(Feature):
your turn.
"""
name = "Fleet of Foot"
source = "Revised Ranger"
@@ -743,6 +798,7 @@ class HideInPlainSightRevised(Feature):
motionless and gain this benefit until you are detected
"""
name = "Hide in Plain Sight"
source = "Revised Ranger"
@@ -776,6 +832,7 @@ class AnimalCompanion(Feature):
is replaced by the restored companion
"""
name = "Animal Companion"
source = "Revised Ranger (Animal Companion)"
@@ -812,6 +869,7 @@ class CompanionsBond(Feature):
is a beloved companion for whom I would gladly give my life.\"
"""
name = "Companions Bond"
source = "Revised Ranger (Beast Conclave)"
@@ -821,6 +879,7 @@ class CoordinatedAttack(Feature):
fighting team. When you use the Attack action on your turn, if your
companion can see you, it can use its reaction to make a melee attack.
"""
name = "Coordinated Attack"
source = "Revised Ranger (Beast Conclave)"
@@ -830,6 +889,7 @@ class BeastsDefense(Feature):
saving throw
"""
name = "Beast's Defense"
source = "Revised Ranger (Beast Conclave)"
@@ -840,6 +900,7 @@ class StormOfClawsAndFangs(Feature):
attack roll for each target
"""
name = "Storm of Claws and Fangs"
source = "Revised Ranger (Beast Conclave)"
@@ -850,6 +911,7 @@ class SuperiorBeastsDefense(Feature):
against it.
"""
name = "Superior Beast's Defense"
source = "Revised Ranger (Beast Conclave)"
@@ -865,6 +927,7 @@ class UnderdarkScout(Feature):
benefit from its darkvision
"""
name = "Underdark Scout"
source = "Revised Ranger (Deep Stalker Conclave)"
@@ -876,5 +939,6 @@ class StalkersDodge(Feature):
is made, but it must be used before the outcome of the roll is determined
"""
name = "Stalker's Dodge"
source = "Revised Ranger (Deep Stalker Conclave)"
+53 -11
View File
@@ -16,6 +16,7 @@ class RogueExpertise(Feature):
Add these skills to "skill_expertise" in your character.py file
"""
name = "Expertise"
source = "Rogue"
@@ -33,15 +34,16 @@ class SneakAttack(Feature):
The amount of the extra damage increases as you gain levels in this class,
as shown in the Sneak Attack column of the Rogue table.
"""
_name = "Sneak Attack"
source = "Rogue"
@property
def name(self):
level = self.owner.Rogue.level
dice = ceil(level / 2.)
name = self._name + " ({:d}d6)".format(dice)
return name
level = self.owner.Rogue.level
dice = ceil(level / 2.0)
name = self._name + " ({:d}d6)".format(dice)
return name
class CunningAction(Feature):
@@ -51,6 +53,7 @@ class CunningAction(Feature):
action.
"""
name = "Cunning Action"
source = "Rogue"
@@ -60,6 +63,7 @@ class UncannyDodge(Feature):
attack, you can use your reaction to halve the attack's damage against you.
"""
name = "Uncanny Dodge"
source = "Class (many)"
@@ -72,6 +76,7 @@ class Evasion(Feature):
if you succeed on the saving throw, and only half damage if you fail.
"""
name = "Evasion"
source = "Class (many)"
@@ -82,6 +87,7 @@ class ReliableTalent(Feature):
proficiency bonus, you can treat a d20 roll of 9 or lower as a 10.
"""
name = "Reliable Talent"
source = "Rogue"
@@ -90,6 +96,7 @@ class BlindSense(Feature):
"""Starting at 14th level, if you are able to hear, you are aware of the
location of any hidden or invisible creature within 10 feet of you.
"""
name = "Blind Sense"
source = "Rogue"
@@ -99,7 +106,8 @@ class SlipperyMind(Feature):
proficiency in W isdom saving throws.
"""
name = 'Slippery Mind'
name = "Slippery Mind"
source = "Rogue"
@@ -109,6 +117,7 @@ class Elusive(Feature):
aren't incapacitated.
"""
name = "Elusive"
source = "Rogue"
@@ -123,6 +132,7 @@ class StrokeOfLuck(Feature):
or long rest.
"""
name = "Stroke of Luck"
source = "Rogue"
@@ -134,6 +144,7 @@ class FastHands(Feature):
to disarm a trap or open a lock, or take the Use an Object action.
"""
name = "Fast Hands"
source = "Rogue (Thief)"
@@ -145,6 +156,7 @@ class SecondStoryWork(Feature):
a number of feet equal to your Dexterity modifier.
"""
name = "Second-Story Work"
source = "Rogue (Thief)"
@@ -154,6 +166,7 @@ class SupremeSneak(Feature):
you move no more than half your speed on the same turn
"""
name = "Supreme Sneak"
source = "Rogue (Thief)"
@@ -164,6 +177,7 @@ class UseMagicDevice(Feature):
ignore all class, race, and level requirements on the use of magic items
"""
name = "Use Magic Device"
source = "Rogue (Thief)"
@@ -176,6 +190,7 @@ class ThiefsReflexes(Feature):
you are surprised.
"""
name = "Thief's Reflexes"
source = "Rogue (Thief)"
@@ -188,6 +203,7 @@ class Assassinate(Feature):
against a creature that is surprised is a critical hit.
"""
name = "Assassinate"
source = "Rogue (Assassin)"
@@ -205,6 +221,7 @@ class InfiltrationExpertise(Feature):
to.
"""
name = "Infiltration Expertise"
source = "Rogue (Assassin)"
@@ -219,6 +236,7 @@ class Imposter(Feature):
detection
"""
name = "Imposter"
source = "Rogue (Assassin)"
@@ -230,6 +248,7 @@ class DeathStrike(Feature):
a failed save, double the damage of your attack against the creature
"""
name = "Death Strike"
source = "Rogue (Assassin)"
@@ -239,21 +258,22 @@ class MageHandLegerdemain(Feature):
"""Starting at 3rd level, when you cast mage hand, you can make the
spectral hand invisible, and you can perform the following
additional tasks with it:
- You can stow one object the hand is holding in a container worn
or carried by another creature.
- You can retrieve an object in a container worn or carried by
another creature.
- You can use thieves' tools to pick locks and disarm traps at
range
You can perform one of these tasks without being noticed by a
creature if you succeed on a Dexterity (Sleight of Hand) check
contested by the creature's Wisdom (Perception) check. In
addition, you can use the bonus action granted by your Cunning
Action to control the hand.
"""
name = "Mage Hand Legerdemain"
source = "Rogue (Arcane Trickster)"
@@ -264,6 +284,7 @@ class MagicalAmbush(Feature):
against the spell this turn
"""
name = "Magical Ambush"
source = "Rogue (Arcane Trickster)"
@@ -275,6 +296,7 @@ class VersatileTrickster(Feature):
advantage on attack rolls against that creature until the end of the turn.
"""
name = "Versatile Trickster"
source = "Rogue (Arcane Trickster)"
@@ -294,6 +316,7 @@ class SpellThief(Feature):
you can't use it again until you finish a long rest
"""
name = "Spell Thief"
source = "Rogue (Arcane Trickster)"
@@ -306,6 +329,7 @@ class EarForDeceit(Feature):
8.
"""
name = "Ear for Deceit"
source = "Rogue (Inquisitive)"
@@ -316,6 +340,7 @@ class EyeForDetail(Feature):
Intelligence (Investigation) check to uncover or decipher clues
"""
name = "Eye for Detail"
source = "Rogue (Inquisitive)"
@@ -331,6 +356,7 @@ class InsightfulFighting(Feature):
against a different target
"""
name = "Insightful Fighting"
source = "Rogue (Inquisitive)"
@@ -341,6 +367,7 @@ class SteadyEye(Feature):
on the same turn
"""
name = "Steady Eye"
source = "Rogue (Inquisitive)"
@@ -356,6 +383,7 @@ class UnerringEye(Feature):
expended uses of it when you finish a long rest
"""
name = "Unerring Eye"
source = "Rogue (Inquisitive)"
@@ -367,6 +395,7 @@ class EyeForWeakness(Feature):
increases by 3d6
"""
name = "Eye for Weakness"
source = "Rogue (Inquisitive)"
@@ -381,6 +410,7 @@ class MasterOfIntrigue(Feature):
particular land, provided that you know the language.
"""
name = "Master of Intrigue"
source = "Rogue (Mastermind)"
@@ -392,6 +422,7 @@ class MasterOfTactics(Feature):
you, rather than within 5 feet of you, if the target can see or hear you
"""
name = "Master of Tactics"
source = "Rogue (Mastermind)"
@@ -415,6 +446,7 @@ class InsightfulManipulator(Feature):
creature's history or one of its personality traits, if it has any
"""
name = "Insightful Manipulator"
source = "Rogue (Mastermind)"
@@ -427,6 +459,7 @@ class Misdirection(Feature):
of you
"""
name = "Misdirection"
source = "Rogue (Mastermind)"
@@ -440,6 +473,7 @@ class SoulOfDeceit(Feature):
you so choose, and you can't be compelled to tell the truth by magic
"""
name = "Soul of Deceit"
source = "Rogue (Masterind)"
@@ -451,6 +485,7 @@ class Skirmisher(Feature):
within 5 feet of you. This movement doesn't provoke opportunity attacks
"""
name = "Skirmisher"
source = "Rogue (Scout)"
@@ -464,8 +499,8 @@ class Survivalist(Feature):
"""
def __init__(self, owner=None):
super().__init__(owner=owner)
self.owner.skill_expertise += ("nature", "survival")
super().__init__(owner=owner)
self.owner.skill_expertise += ("nature", "survival")
class SuperiorMobility(Feature):
@@ -473,6 +508,7 @@ class SuperiorMobility(Feature):
climbing or swimming speed, this increase applies to that speed as well.
"""
name = "Superior Mobility"
source = "Rogue (Scout)"
needs_implementation = True # apply to climbing and swimming
@@ -486,6 +522,7 @@ class AmbushMaster(Feature):
the start ofyour next turn
"""
name = "Ambush Master"
source = "Rogue (Scout)"
@@ -498,6 +535,7 @@ class SuddenStrike(Feature):
same target more than once in a turn
"""
name = "Sudden Strike"
source = "Rogue (Scout)"
@@ -510,6 +548,7 @@ class FancyFootwork(Feature):
against you for the rest ofyour turn
"""
name = "Fancy Footwork"
source = "Rogue (Swashbuckler)"
@@ -524,6 +563,7 @@ class RakishAudacity(Feature):
other rules for Sneak Attack still apply to you.
"""
name = "Rakish Audacity"
source = "Rogue (Swashbuckler)"
@@ -545,6 +585,7 @@ class Panache(Feature):
or your companions do anything harmful to it
"""
name = "Panache"
source = "Rogue (Swashbuckler)"
@@ -555,6 +596,7 @@ class ElegantManeuver(Feature):
check you make during the same turn
"""
name = "Elegant Maneuver"
source = "Rogue (Swashbuckler)"
@@ -566,6 +608,6 @@ class MasterDuelist(Feature):
until you finish a short or long rest
"""
name = "Master Duelist"
source = "Rogue (Swashbuckler)"
+43 -6
View File
@@ -34,6 +34,7 @@ class FontOfMagic(Feature):
5th Level Slot <--> 7 sorcery points
"""
name = "Font of Magic"
source = "Sorceror"
@@ -45,6 +46,7 @@ class Metamagic(Feature):
option on a spell when you cast it, unless otherwise noted
"""
name = "Metamagic"
source = "Sorceror (Metamagic)"
@@ -54,6 +56,7 @@ class SorcerousRestoration(Feature):
short rest.
"""
name = "Sorcerous Restoration"
source = "Sorceror"
@@ -67,6 +70,7 @@ class CarefulSpell(Metamagic):
automatically succeeds on its saving throw against the spell.
"""
name = "Careful Spell"
@@ -77,6 +81,7 @@ class DistantSpell(Metamagic):
of the spell 30 feet
"""
name = "Distant Spell"
@@ -88,6 +93,7 @@ class EmpoweredSpell(Metamagic):
spell.
"""
name = "Empowered Spell"
@@ -97,6 +103,7 @@ class ExtendedSpell(Metamagic):
hours.
"""
name = "Extended Spell"
@@ -106,6 +113,7 @@ class HeightenedSpell(Metamagic):
the spell disadvantage on its first saving throw made against the spell
"""
name = "Heightened Spell"
@@ -115,6 +123,7 @@ class QuickenedSpell(Metamagic):
casting.
"""
name = "Quickened Spell"
@@ -123,6 +132,7 @@ class SubtleSpell(Metamagic):
somatic or verbal components.
"""
name = "Subtle Spell"
@@ -133,6 +143,7 @@ class TwinnedSpell(Metamagic):
sorcery point if the spell is a cantrip)
"""
name = "Twinned Spell"
@@ -144,6 +155,7 @@ class WildMagicSurge(Feature):
1, roll on the Wild Magic Surge table to create a random magical effect.
"""
name = "Wild Magic Surge"
source = "Sorceror (Wild Magic)"
@@ -158,6 +170,7 @@ class TidesOfChaos(Feature):
spell of 1st level or higher. You then regain the use of this feature.
"""
name = "Tides of Chaos"
source = "Sorceror (Wild Magic)"
@@ -171,8 +184,9 @@ class BendLuck(Feature):
before any effects of the roll occur.
"""
name = 'Bend Luck'
source = 'Sorceror (Wild Magic)'
name = "Bend Luck"
source = "Sorceror (Wild Magic)"
class ControlledChaos(Feature):
@@ -181,7 +195,8 @@ class ControlledChaos(Feature):
and use either number.
"""
name = 'Controlled Chaos'
name = "Controlled Chaos"
source = "Sorceror (Wild Magic)"
@@ -192,6 +207,7 @@ class SpellBombardment(Feature):
add that roll to the damage. You can use the feature only once per turn.
"""
name = "Spell Bombardment"
source = "Sorceror (Wild Magic)"
@@ -209,6 +225,7 @@ class DraconicResilience(Feature):
This bonus is computed in the AC given on the Character Sheet above.
"""
name = "Draconic Resilience"
source = "Sorceror (Draconic Bloodline)"
@@ -244,6 +261,7 @@ class DragonAncestor(Feature):
doubled if it applies to the check.
"""
name = "Dragon Ancestor"
source = "Sorceror (Draconic Bloodline)"
@@ -255,6 +273,7 @@ class ElementalAffinity(Feature):
to that damage type for 1 hour
"""
name = "Elemental Affinity"
source = "Sorceror (Draconic Bloodline)"
@@ -268,6 +287,7 @@ class ElementalAdept(Feature):
a different damage type.
"""
name = "Elemental Adept"
source = "Sorceror (Feats)"
@@ -282,6 +302,7 @@ class DragonWings(Feature):
manifest them
"""
name = "Dragon Wings"
source = "Sorceror (Draconic Bloodline)"
@@ -298,6 +319,7 @@ class DraconicPresence(Feature):
succeeds on this saving throw is immune to your aura for 24 hours.
"""
name = "Draconic Presence"
source = "Sorceror (Draconic Bloodline)"
@@ -329,6 +351,7 @@ class DivineMagic(Feature):
Neutrality : Protection from Evil and Good
"""
name = "Divine Magic"
source = "Sorceror (Divine Soul)"
@@ -339,6 +362,7 @@ class FavoredByTheGods(Feature):
the total, possibly changing
"""
name = "Favored by the Gods"
source = "Sorceror (Divine Soul)"
@@ -351,6 +375,7 @@ class EmpoweredHealing(Feature):
incapacitated. You can use this feature only once per turn.
"""
name = "Empowered Healing"
source = "Sorceror (Divine Soul)"
@@ -365,6 +390,7 @@ class OtherworldlyWings(Feature):
neutrality
"""
name = "Otherworldly Wings"
source = "Sorceror (Divine Soul)"
@@ -377,6 +403,7 @@ class UnearthlyRecovery(Feature):
a long rest
"""
name = "Unearthly Recovery"
source = "Sorceror (Divine Soul)"
@@ -390,6 +417,7 @@ class EyesOfTheDark(Feature):
created by the spell.
"""
name = "Eyes of the Dark"
source = "Sorceror (Shadow Magic)"
spells_known = (spells.Darkness,)
@@ -406,6 +434,7 @@ class StrengthOfTheGrave(Feature):
until you finish a long rest
"""
name = "Strength of the Grave"
source = "Sorceror (Shadow Magic)"
@@ -417,7 +446,7 @@ class HoundOfIllOmen(Feature):
can see within 120 feet of you. The hound uses the dire wolf's statistics
(see the Monster Manual or appendix C in the Player's Handbook), with the
following changes:
- The hound is size Medium, not Large, and it counts as a
monstrosity, not a beast.
- It appears with a number of temporary hit points equal to half
@@ -428,7 +457,7 @@ class HoundOfIllOmen(Feature):
- At the start of its turn, the hound automatically knows its
target's location. If the target was hidden, it is no longer
hidden from the hound.
The hound appears in an unoccupied space of your choice within 30
feet of the target. Roll initiative for the hound. On its turn, it
can move only toward its target by the most direct route, and it
@@ -438,8 +467,9 @@ class HoundOfIllOmen(Feature):
disadvantage on saving throws against any spell you cast. The
hound disappears if it is reduced to 0 hit points, if its target
is reduced to 0 hit points, or after 5 minutes.
"""
name = "Hound of Ill Omen"
source = "Sorceror (Shadow Magic)"
@@ -451,6 +481,7 @@ class ShadowWalk(Feature):
that is also in dim light or darkness
"""
name = "Shadow Walk"
source = "Sorceror (Shadow Magic)"
@@ -465,6 +496,7 @@ class UmbralForm(Feature):
or if you dismiss it as a bonus action.
"""
name = "Umbral Form"
source = "Sorceror (Shadow Magic)"
@@ -477,6 +509,7 @@ class TempestuousMagic(Feature):
fly up to 10 feet without provoking opportunity attacks
"""
name = "Tempestuous Magic"
source = "Sorceror (Storm Sorcery)"
@@ -490,6 +523,7 @@ class HeartOfTheStorm(Feature):
activates) equal to half your sorcerer level.
"""
name = "Heart of the Storm"
source = "Sorceror (Storm Sorcery)"
@@ -504,6 +538,7 @@ class StormGuide(Feature):
turn. This feature doesn't alter the speed of the wind.
"""
name = "Storm Guide"
source = "Sorceror (Storm Sorcery)"
@@ -516,6 +551,7 @@ class StormsFury(Feature):
pushed in a straight line up to 20 feet away from you.
"""
name = "Storm's Fury"
source = "Sorceror (Storm Sorcery)"
@@ -530,5 +566,6 @@ class WindSoul(Feature):
long rest
"""
name = "Wind Soul"
source = "Sorceror (Storm Sorcery)"
+132 -57
View File
@@ -18,6 +18,7 @@ class EldritchInvocation(Feature):
could learn at that level.
"""
name = "Eldritch Invocations"
source = "Warlock"
@@ -32,6 +33,7 @@ class PactOfTheChain(Feature):
of your own attacks to allow your familiar to make one attack of its own.
"""
name = "Pact of the Chain"
source = "Warlock"
spells_known = spells_prepared = (spells.FindFamiliar,)
@@ -60,6 +62,7 @@ class PactOfTheBlade(Feature):
breaks.
"""
name = "Pact of the Blade"
source = "Warlock"
@@ -76,6 +79,7 @@ class PactOfTheTome(Feature):
turns to ash when you die.
"""
name = "Pact of the Tome"
source = "Warlock"
@@ -90,12 +94,15 @@ class PactBoon(FeatureSelector):
pact of the tome
"""
options = {'chain': PactOfTheChain,
'pact of the chain': PactOfTheChain,
'blade': PactOfTheBlade,
'pact of the blade': PactOfTheBlade,
'tome': PactOfTheTome,
'pact of the tome': PactOfTheTome}
options = {
"chain": PactOfTheChain,
"pact of the chain": PactOfTheChain,
"blade": PactOfTheBlade,
"pact of the blade": PactOfTheBlade,
"tome": PactOfTheTome,
"pact of the tome": PactOfTheTome,
}
name = "Pact Boon (Select One)"
source = "Warlock"
@@ -114,6 +121,7 @@ class MysticArcanum(Feature):
your Mystic Arcanum when you finish a long rest.
"""
name = "Mystic Arcanum"
source = "Warlock"
@@ -126,6 +134,7 @@ class EldritchMaster(Feature):
feature, you must finish a long rest before you can do so again.
"""
name = "Eldritch Master"
source = "Warlock"
@@ -142,6 +151,7 @@ class FeyPresence(Feature):
feature, you can't use it again until you finish a short or long rest.
"""
name = "Fey Presence"
source = "Warlock (Archfey Patron)"
@@ -155,6 +165,7 @@ class MistyEscape(Feature):
short or long rest
"""
name = "Misty Escape"
source = "Warlock (Archfey Patron)"
@@ -168,6 +179,7 @@ class BeguilingDefenses(Feature):
be charmed by you for 1 minute or until the creature takes any damage.
"""
name = "Beguiling Defenses"
source = "Warlock (Archfey Patron)"
@@ -187,6 +199,7 @@ class DarkDelirium(Feature):
use this feature again.
"""
name = "Dark Delirium"
source = "Warlock (Archfey Patron)"
@@ -198,14 +211,15 @@ class DarkOnesBlessing(Feature):
warlock level (minimum of 1)
"""
_name = "Dark One's Blessing"
source = "Warlock (The Fiend Patron)"
@property
def name(self):
level = self.owner.Warlock.level
mod = self.owner.charisma.modifier
return self._name + ' ({:d} HP)'.format(level + mod)
level = self.owner.Warlock.level
mod = self.owner.charisma.modifier
return self._name + " ({:d} HP)".format(level + mod)
class DarkOnesOwnLuck(Feature):
@@ -218,6 +232,7 @@ class DarkOnesOwnLuck(Feature):
or long rest.
"""
name = "Dark One's Own Luck"
source = "Warlock (The Fiend Patron)"
@@ -229,6 +244,7 @@ class FiendishResilience(Feature):
silver weapons ignores this resistance.
"""
name = "Fiendish Resilience"
source = "Warlock (The Fiend Patron)"
@@ -246,6 +262,7 @@ class HurlThroughHell(Feature):
rest.
"""
name = "Hurl Through Hell"
source = "Warlock (The Fiend Patron)"
@@ -259,6 +276,7 @@ class AwakenedMind(Feature):
but the creature must be able to understand at least one language
"""
name = "Awakened Mind"
source = "Warlock (Great Old One Patron)"
@@ -273,6 +291,7 @@ class EntropicWard(Feature):
finish a short or long rest.
"""
name = "Entropic Ward"
source = "Warlock (Great Old One Patron)"
@@ -284,6 +303,7 @@ class ThoughtShield(Feature):
same amount of damage that you do
"""
name = "Thought Shield"
source = "Warlock (Great Old One Patron)"
@@ -297,6 +317,7 @@ class CreateThrall(Feature):
creature as long as the two of you are on the same plane of existence
"""
name = "Create Thrall"
source = "Warlock (Great Old One Patron)"
@@ -316,6 +337,7 @@ class AmongTheDead(Feature):
if you target it with an attack or a harmful spell.
"""
name = "Among the Dead"
source = "Warlock (The Undying Patron)"
spells_known = spells_prepared = (spells.SpareTheDying,)
@@ -330,6 +352,7 @@ class DefyDeath(Feature):
long rest
"""
name = "Defy Death"
source = "Warlock (The Undying Patron)"
@@ -342,6 +365,7 @@ class UndyingNature(Feature):
ages only 1 year, and you are immune to being magically aged
"""
name = "Undying Nature"
source = "Warlock (The Undying Patron)"
@@ -355,6 +379,7 @@ class IndestructibleLife(Feature):
use it again until you finish a short or long rest.
"""
name = "Indestructible Life"
source = "Warlock (The Undying Patron)"
@@ -372,13 +397,14 @@ class HealingLight(Feature):
rest
"""
_name = "Healing Light"
source = "Warlock (The Celestial Patron)"
@property
def name(self):
num = 1 + self.owner.Warlock.level
return self._name + " ({:d}d6/LR)".format(num)
num = 1 + self.owner.Warlock.level
return self._name + " ({:d}d6/LR)".format(num)
class RadiantSoul(Feature):
@@ -389,6 +415,7 @@ class RadiantSoul(Feature):
one of its targets.
"""
name = "Radiant Soul"
source = "Warlock (The Celestial Patron)"
@@ -401,6 +428,7 @@ class CelestialResilience(Feature):
equal to half your warlock level + your Charisma modifier
"""
_name = "Celestial Resilience"
source = "Warlock (The Celestial Patron)"
@@ -416,6 +444,7 @@ class SearingVengeance(Feature):
this feature, you can't use it again until you finish a long rest.
"""
name = "Searing Vengeance"
source = "Warlock (The Celestial Patron)"
@@ -427,17 +456,18 @@ class HexbladesCurse(Feature):
of you. The target is cursed for 1 minute. The curse ends early if the
target dies, you die, or you are incapacitated. Until the curse ends, you
gain the following benefits:
- You gain a bonus to damage rolls against the cursed target. The
bonus equals your proficiency bonus.
- Any attack roll you make against the cursed target is a critical
hit on a roll of 19 or 20 on the d20.
- If the cursed target dies, you regain hit points equal to your
warlock level + your Charisma modifier (minimum of 1 hit point).
You can't use this feature again until you finish a short or long rest.
"""
name = "Hexblades Curse"
source = "Warlock (Hexblade)"
@@ -457,22 +487,27 @@ class HexWarrior(Feature):
you conjure with that feature, no matter the weapon's type
"""
name = 'Hex Warrior'
name = "Hex Warrior"
source = "Warlock (Hexblade)"
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""
Swap the weapon's attack bonus modifier for Charisma if
it is higher than STR/DEX bonus
"""
if weapon.is_finesse:
abils = {'strength': self.owner.strength.modifier,
'dexterity': self.owner.dexterity.modifier,
'charisma': self.owner.charisma.modifier}
else:
abils = {weapon.ability: getattr(self.owner, weapon.ability).modifier,
'charisma': self.owner.charisma.modifier}
weapon.ability = max(abils, key=abils.get)
"""
Swap the weapon's attack bonus modifier for Charisma if
it is higher than STR/DEX bonus
"""
if weapon.is_finesse:
abils = {
"strength": self.owner.strength.modifier,
"dexterity": self.owner.dexterity.modifier,
"charisma": self.owner.charisma.modifier,
}
else:
abils = {
weapon.ability: getattr(self.owner, weapon.ability).modifier,
"charisma": self.owner.charisma.modifier,
}
weapon.ability = max(abils, key=abils.get)
class AccursedSpecter(Feature):
@@ -492,6 +527,7 @@ class AccursedSpecter(Feature):
until you finish a long rest.
"""
name = "Accursed Specter"
source = "Warlock (Hexblade)"
@@ -503,6 +539,7 @@ class ArmorOfHexes(Feature):
its roll.
"""
name = "Armor of Hexes"
source = "Warlock (Hexblade)"
@@ -516,6 +553,7 @@ class MasterOfHexes(Feature):
previously cursed creature.
"""
name = "Master of Hexes"
source = "Warlock (Hexblade)"
@@ -525,24 +563,25 @@ class Invocation(Feature):
"""
A generic Eldritch Invocation. Add details in features/warlock.py
"""
name = 'Unnamed Invocation'
name = "Unnamed Invocation"
source = "Warlock (Eldritch Invocations)"
at_will_spells = ()
def cast_spell_at_will(self, spell):
s = spell()
s.level = 0
if 'M' in s.components:
c = list(s.components)
c.remove('M')
s.components = tuple(c)
self.spells_known += (s,)
self.spells_prepared += (s,)
s = spell()
s.level = 0
if "M" in s.components:
c = list(s.components)
c.remove("M")
s.components = tuple(c)
self.spells_known += (s,)
self.spells_prepared += (s,)
def __init__(self, owner):
super().__init__(owner)
for s in self.at_will_spells:
self.cast_spell_at_will(s)
super().__init__(owner)
for s in self.at_will_spells:
self.cast_spell_at_will(s)
# PHB
@@ -551,6 +590,7 @@ class AgonizingBlast(Invocation):
deals on a hit.
"""
name = "Agonizing Blast"
@@ -559,6 +599,7 @@ class ArmorOfShadows(Invocation):
or material components
"""
name = "Armor of Shadows"
at_will_spells = (spells.MageArmor,)
@@ -570,22 +611,21 @@ class AscendantStep(Invocation):
**Prerequisite: 9th level**
"""
name = 'Ascendant Step'
name = "Ascendant Step"
at_will_spells = (spells.Levitate,)
class BeastSpeech(Invocation):
"""You can cast speak with animals at will, without expending a spell slot.
"""You can cast speak with animals at will, without expending a spell slot."""
"""
name = "Beast Speech"
at_will_spells = (spells.SpeakWithAnimals,)
class BeguilingInfluence(Invocation):
"""You gain proficiency in the Deception and Persuasion skills.
"""You gain proficiency in the Deception and Persuasion skills."""
"""
name = "Beguiling Influence"
needs_implementation = True
@@ -596,6 +636,7 @@ class BewitchingWhispers(Invocation):
**Prerequisite**: 7th Level
"""
name = "Bewitching Whispers"
@@ -616,6 +657,7 @@ class BookOfAncientSecrets(Invocation):
rare inks needed to inscribe it
"""
name = "Book of Ancient Secrets"
@@ -627,6 +669,7 @@ class ChainsOfCarceri(Invocation):
**Prerequisites**: 15th level, Pact of the Chain Feature
"""
name = "Chains of Carceri"
@@ -635,6 +678,7 @@ class DevilsSight(Invocation):
distance of 120 feet.
"""
name = "Devil's Sight"
@@ -643,21 +687,20 @@ class DreadfulWord(Invocation):
again until you finish a long rest.
"""
name = "Dreadful Word"
class EldritchSight(Invocation):
"""You can cast detect magic at will, without expending a spell slot.
"""You can cast detect magic at will, without expending a spell slot."""
"""
name = "Eldritch Sight"
at_will_spells = (spells.DetectMagic,)
class EldritchSpear(Invocation):
"""When you cast eldritch blast, its range is 300 feet.
"""When you cast eldritch blast, its range is 300 feet."""
"""
name = "Eldritch Spear"
@@ -666,6 +709,7 @@ class EyesOfTheRuneKeeper(Invocation):
You can read all writing.
"""
name = "Eyes of the Rune Keeper"
@@ -674,6 +718,7 @@ class FiendishVigor(Invocation):
expending a spell slot or material components.
"""
name = "Fiendish Vigor"
at_will_spells = (spells.FalseLife,)
@@ -688,6 +733,7 @@ class GazeOfTwoMinds(Invocation):
blinded and deafened to your own surroundings.
"""
name = "Gaze of Two Minds"
@@ -697,14 +743,14 @@ class LifeDrinker(Invocation):
**Prerequisite**: 12th Level, Pact of the Blade
"""
name = "Life Drinker"
needs_implementation = True
class MaskOfManyFaces(Invocation):
"""You can cast disguise self at will, without expending a spell slot.
"""You can cast disguise self at will, without expending a spell slot."""
"""
name = "Mask of Many Faces"
at_will_spells = (spells.DisguiseSelf,)
@@ -715,6 +761,7 @@ class MasterOfMyriadForms(Invocation):
**Prerequisite**: 15th Level
"""
name = "Master of Myriad Forms"
at_will_spells = (spells.AlterSelf,)
@@ -725,6 +772,7 @@ class MinionsOfChaos(Invocation):
**Prerequisite**: 9th Level
"""
name = "Minions of Chaos"
@@ -733,6 +781,7 @@ class MireTheMind(Invocation):
until you finish a long rest.
"""
name = "Mire the Mind"
@@ -741,6 +790,7 @@ class MistyVisions(Invocation):
material components.
"""
name = "Misty Visions"
at_will_spells = (spells.SilentImage,)
@@ -751,6 +801,7 @@ class OneWithShadows(Invocation):
**Prerequisite**: 5th Level
"""
name = "One with Shadows"
@@ -761,15 +812,17 @@ class OtherworldlyLeap(Invocation):
**Prerequisite**: 9th Level
"""
name = "Otherworldly Leap"
at_will_spells = (spells.Jump,)
class RepellingBlast(Invocation):
"""When you hit a creature with eldritch blast, you can push the creature up
to 10 feet away from you in a straight line.
to 10 feet away from you in a straight line.
"""
name = "Repelling Blast"
@@ -779,6 +832,7 @@ class SculptorOfFlesh(Invocation):
**Prerequisite**: 7th Level
"""
name = "Sculptor of Flesh"
@@ -789,6 +843,7 @@ class SignOfIllOmen(Invocation):
**Prerequisite**: 5th Level
"""
name = "Sign of Ill Omen"
@@ -797,6 +852,7 @@ class ThiefOfFiveFates(Invocation):
until you finish a long rest.
"""
name = "Thief of Five Fates"
@@ -806,6 +862,7 @@ class ThirstingBlade(Invocation):
**Prerequisite**: 5th Level, Pact of the Blade
"""
name = "Thirsting Blade"
@@ -815,6 +872,7 @@ class VisionsOfDistantRealms(Invocation):
**Prerequisite**: 15th level
"""
name = "Visions of Distant Realms"
at_will_spells = (spells.ArcaneEye,)
@@ -829,6 +887,7 @@ class VoiceOfTheChainMaster(Invocation):
**Prerequisite**: Pact of the Chain
"""
name = "Voice of the Chain Master"
@@ -838,6 +897,7 @@ class WhispersOfTheGrave(Invocation):
**Prerequsite**: 9th Level
"""
name = "Whispers of the Grave"
at_will_spells = (spells.SpeakWithDead,)
@@ -848,6 +908,7 @@ class WitchSight(Invocation):
and within line of sight.
"""
name = "Witch Sight"
@@ -859,6 +920,7 @@ class AspectOfTheMoon(Invocation):
**Prerequisite**: Pact of the Tome
"""
name = "Aspect of the Moon"
@@ -878,6 +940,7 @@ class CloakOfFlies(Invocation):
**Prerequisite**: 5th level
"""
name = "Cloak of Flies"
@@ -890,6 +953,7 @@ class EldritchSmite(Invocation):
**Prerequisite**: 5th level, Pact of the Blade
"""
name = "Eldritch Smite"
@@ -905,6 +969,7 @@ class GhostlyGaze(Invocation):
**Prerequisite**: 7th level
"""
name = "Ghostly Gaze"
@@ -915,6 +980,7 @@ class GiftOfTheDepths(Invocation):
**Prerequisite**: 5th level
"""
name = "Gift of the Depths"
@@ -925,6 +991,7 @@ class GiftOfTheEverLivingOnes(Invocation):
**Prerequisite**: Pact of the Chain
"""
name = "Gift of the Ever-Living Ones"
@@ -933,6 +1000,7 @@ class GraspOfHadar(Invocation):
blast, you can move that creature in a straight line 10 feet closer to you
"""
name = "Grasp of Hadar"
@@ -948,15 +1016,16 @@ class ImprovedPactWeapon(Invocation):
**Prerequisite**: Pact of the Blade
"""
name = "Improved Pact Weapon"
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""
Add +1 to attack and damage if magic is not already magic
"""
if (weapon.attack_bonus == 0) or (weapon.damage_bonus == 0):
weapon.attack_bonus += 1
weapon.damage_bonus += 1
"""
Add +1 to attack and damage if magic is not already magic
"""
if (weapon.attack_bonus == 0) or (weapon.damage_bonus == 0):
weapon.attack_bonus += 1
weapon.damage_bonus += 1
class LanceOfLethargy(Invocation):
@@ -965,6 +1034,7 @@ class LanceOfLethargy(Invocation):
next turn.
"""
name = "Lance of Lethargy"
@@ -979,6 +1049,7 @@ class MaddeningHex(Invocation):
**Prerequisite**: 5th level
"""
name = "Maddening Hex"
@@ -990,6 +1061,7 @@ class RelentlessHex(Invocation):
teleport in this way, you must be able to see the cursed target.
"""
name = "Relentless Hex"
@@ -999,6 +1071,7 @@ class ShroudOfShadow(Invocation):
**Prerequisite**: 15th Level
"""
at_will_spells = (spells.Invisibility,)
name = "Shroud of Shadow"
@@ -1018,6 +1091,7 @@ class TombOfLevistus(Invocation):
**Prerequisite**: 5th Level
"""
name = "Tomb of Levistus"
@@ -1026,4 +1100,5 @@ class TrickstersEscape(Invocation):
slot. You regain the ability to do so when you finish a long rest
"""
name = "Tricksters Escape"
+74 -21
View File
@@ -1,18 +1,20 @@
from dungeonsheets import spells, weapons
from dungeonsheets.features.features import Feature, FeatureSelector
from dungeonsheets import spells
from dungeonsheets.features.features import Feature
# PHB
class ArcaneRecovery(Feature):
"""You have learned to regain some of your magical energy by studying your
spellbook. Once per day when you finish a short rest, you can choose
expended spell slots to recover. The spell slots can have a combined level
that is equal to or less than half your wizard level (rounded up), and none
of the slots can be 6th level or higher. For example, if you're a 4th-level
wizard, you can recover up to two levels worth o f spell slots. You can
recover either a 2nd-level spell slot or two 1st-level spell slots
"""You have learned to regain some of your magical energy by studying
your spellbook. Once per day when you finish a short rest, you can
choose expended spell slots to recover. The spell slots can have a
combined level that is equal to or less than half your wizard
level (rounded up), and none of the slots can be 6th level or
higher. For example, if you're a 4th-level wizard, you can recover
up to two levels worth o f spell slots. You can recover either a
2nd-level spell slot or two 1st-level spell slots
"""
name = "Arcane Recovery"
source = "Wizard"
@@ -27,6 +29,7 @@ class SpellMastery(Feature):
o f the spells you chose for different spells of the same levels.
"""
name = "Spell Mastery"
source = "Wizard"
@@ -42,6 +45,7 @@ class SignatureSpells(Feature):
expend a spell slot as normal.
"""
name = "Signature Spells"
source = "Wizard"
@@ -52,6 +56,7 @@ class AbjurationSavant(Feature):
must spend to copy an abjuration spell into your spellbook is halved.
"""
name = "Abjuration Savant"
source = "Wizard (School of Abjuration)"
@@ -71,6 +76,7 @@ class ArcaneWard(Feature):
finish a long rest
"""
name = "Arcane Ward"
source = "Wizard (School of Abjuration)"
@@ -82,6 +88,7 @@ class ProjectedWard(Feature):
warded creature takes any remaining damage
"""
name = "Projected Ward"
source = "Wizard (School of Abjuration)"
@@ -93,6 +100,7 @@ class ImprovedAbjuration(Feature):
ability check.
"""
name = "Improved Abjuration"
source = "Wizard (School of Abjuration)"
@@ -102,6 +110,7 @@ class SpellResistance(Feature):
spells. Furthermore, you have resistance against the damage of spells
"""
name = "Spell Resistance"
source = "Wizard (School of Abjuration)"
@@ -112,6 +121,7 @@ class ConjurationSavant(Feature):
must spend to copy a conjuration spell into your spellbook is halved.
"""
name = "Conjuration Savant"
source = "Wizard (School of Conjuration)"
@@ -126,6 +136,7 @@ class MinorIllusion(Feature):
after 1 hour, when you use this feature again, or if it takes any damage.
"""
name = "Minor Illusion"
source = "Wizard (School of Conjuration)"
@@ -139,6 +150,7 @@ class BenignTransposition(Feature):
conjuration spell of 1st level or higher.
"""
name = "Benign Transposition"
source = "Wizard (School of Conjuration)"
@@ -148,6 +160,7 @@ class FocusedConjuration(Feature):
spell, your concentration can't be broken as a result of taking damage
"""
name = "Focused Conjuration"
source = "Wizard (School of Conjuration)"
@@ -157,6 +170,7 @@ class DurableSummons(Feature):
conjuration spell has 30 temporary hit points
"""
name = "Durable Summons"
source = "Wizard (School of Conjuration)"
@@ -167,6 +181,7 @@ class DivinationSavant(Feature):
must spend to copy a divination spell into your spellbook is halved. P
"""
name = "Divination Savant"
source = "Wizard (School of Divination)"
@@ -182,6 +197,7 @@ class Portent(Feature):
unused foretelling rolls
"""
name = "Portent"
source = "Wizard (School of Divination)"
@@ -194,6 +210,7 @@ class ExpertDivination(Feature):
the spell you cast and can't be higher than 5th level.
"""
name = "Expert Divination"
source = "Wizard (School of Divination)"
@@ -216,7 +233,8 @@ class TheThirdEye(Feature):
feet of you that are within line of sight
"""
name = 'The Third Eye'
name = "The Third Eye"
source = "Wizard (School of Divination)"
@@ -226,6 +244,7 @@ class GreaterPortent(Feature):
for your Portent feature, rather than two
"""
name = "Greater Portent"
source = "Wizard (School of Divination)"
@@ -236,6 +255,7 @@ class EnchantmentSavant(Feature):
must spend to copy an enchantment spell into your spellbook is halved
"""
name = "Enchantment Savant"
source = "Wizard (School of Enchantment)"
@@ -258,6 +278,7 @@ class HypnoticGaze(Feature):
until you finish a long rest
"""
name = "Hypnotic Gaze"
source = "Wizard (School of Enchantment)"
@@ -275,6 +296,7 @@ class InstinctiveGaze(Feature):
misses. Creatures that can't be charmed are immune to this effect.
"""
name = "Instinctive Gaze"
source = "Wizard (School of Enchanment)"
@@ -285,6 +307,7 @@ class SplitEnchantment(Feature):
creature.
"""
name = "Split Enchantment"
source = "Wizard (School of Enchanment)"
@@ -302,13 +325,14 @@ class AlterMemories(Feature):
time can't exceed the duration of your enchantment spell.
"""
_name = "Alter Memories"
source = "Wizard (School of Enchanment)"
@property
def name(self):
num = 1 + max(0, self.owner.charisma.modifier)
return self._name + " ({:d} hours)".format(num)
num = 1 + max(0, self.owner.charisma.modifier)
return self._name + " ({:d} hours)".format(num)
# Evocation
@@ -317,6 +341,7 @@ class EvocationSavant(Feature):
must spend to copy an evocation spell into your spellbook is halved.
"""
name = "Evocation Savant"
source = "Wizard (School of Evocation)"
@@ -330,6 +355,7 @@ class SculptSpells(Feature):
would normally take half damage on a successful save
"""
name = "Sculpt Spells"
source = "Wizard (School of Evocation)"
@@ -341,6 +367,7 @@ class PotentCantrip(Feature):
but suffers no additional effect from the cantrip
"""
name = "Potent Cantrip"
source = "Wizard (School of Evocation)"
@@ -350,6 +377,7 @@ class EmpoweredEvocation(Feature):
damage roll of any wizard evocation spell you cast
"""
name = "Empowered Evocation"
source = "Wizard (School of Evocation)"
@@ -365,6 +393,7 @@ class Overchannel(Feature):
by 1d12. This damage ignores resistance and immunity.
"""
name = "Overchannel"
source = "Wizard (School of Evocation)"
@@ -375,6 +404,7 @@ class IllusionSavant(Feature):
must spend to copy an illusion spell into your spellbook is halved.
"""
name = "Illusion Savant"
source = "Wizard (School of Illusion)"
@@ -387,6 +417,7 @@ class ImprovedMinorIllusion(Feature):
and an image with a single casting o f the spell.
"""
name = "Improved Minor Illusion"
source = "Wizard (School of Illusion)"
@@ -398,6 +429,7 @@ class MalleableIllusions(Feature):
that you can see the illusion
"""
name = "Malleable Illusions"
source = "Wizard (School of Illusion)"
@@ -411,6 +443,7 @@ class IllusorySelf(Feature):
feature, you can't use it again until you finish a short or long rest.
"""
name = "Illusory Self"
source = "Wizard (School of Illusion)"
@@ -426,6 +459,7 @@ class IllusoryReality(Feature):
cross. The object can't deal damage or otherwise directly harm anyone
"""
name = "Illusory Reality"
source = "Wizard (School of Illusion)"
@@ -436,6 +470,7 @@ class NecromancySavant(Feature):
must spend to copy an Necromancy spell into your spellbook is halved.
"""
name = "Necromancy Savant"
source = "Wizard (School of Necromancy)"
@@ -446,7 +481,8 @@ class GrimHarvest(Feature):
with a spell of 1st level or higher, you regain hit points equal to twice
the spell's level, or three times its level if the spell belongs to the
School of Necromancy. You don't gain this benefit for killing constructs or
undead """
undead"""
name = "Grim Harvest"
source = "Wizard (School of Necromancy)"
@@ -457,13 +493,14 @@ class UndeadThralls(Feature):
target one additional corpse or pile of bones, creating another
zombie or skeleton, as appropriate. Whenever you create an undead
using a necromancy spell, it has additional benefits:
- The creature's hit point maximum is increased by an amount equal
to your wizard level.
- The creature adds your proficiency bonus to its weapon damage
rolls
"""
name = "Undead Thralls"
source = "Wizard (School of Necromancy)"
spells_known = (spells.AnimateDead,)
@@ -476,6 +513,7 @@ class InuredToUndeath(Feature):
some of their worst effects
"""
name = "Inured to Undeath"
source = "Wizard (School of Necromancy)"
@@ -494,6 +532,7 @@ class CommandUndead(Feature):
breaks free
"""
name = "Command Undead"
source = "Wizard (School of Necromancy)"
@@ -504,6 +543,7 @@ class TransmutationSavant(Feature):
must spend to copy an Transmutation spell into your spellbook is halved.
"""
name = "Transmutation Savant"
source = "Wizard (School of Transmutation)"
@@ -520,6 +560,7 @@ class MinorAlchemy(Feature):
reverts to its original substance
"""
name = "Minor Alchemy"
source = "Wizard (School of Transmutation)"
@@ -531,20 +572,21 @@ class TransmutersStone(Feature):
creature gains a benefit of your choice as long as the stone is in
the creature's possession. When you create the stone, choose the
benefit from the following options:
- Darkvision out to a range of 60 feet, as described in chapter 8
- An increase to speed of 10 feet while the creature is
unencumbered
- Proficiency in Constitution saving throws
- Resistance to acid, cold, fire, lightning, or thunder damage
(your choice whenever you choose this benefit)
Each time you cast a transmutation spell of 1st level or higher,
you can change the effect of your stone if the stone is on your
person. If you create a new transmuter's stone, the previous one
ceases to function
"""
name = "Transmuter's Stone"
source = "Wizard (School of Transmutation)"
@@ -557,8 +599,9 @@ class Shapechanger(Feature):
you cast polymorph in this way, you can't do so again until you
finish a short or long rest, though you can still cast it normally
using an available spell slot
"""
name = "Shapechanger"
source = "Wizard (School of Transmutation)"
spells_known = spells_prepared = (spells.Polymorph,)
@@ -589,6 +632,7 @@ class MasterTransmuter(Feature):
13 years. This effect doesn't extend the creature's lifespan
"""
name = "Master Transmuter"
source = "Wizard (School of Transmutation)"
@@ -603,9 +647,9 @@ class Bladesong(Feature):
incapac- itated, if you don medium or heavy armor or a shield, or
if you use two hands to make an attack with a weapon. You can also
dismiss the Bladesong at any time you choose (no action required).
While your Bladesong is active, you gain the following benefits:
- You gain a bonus to your AC equal to your Intelligence modifier
(minimum of +1).
- Your walking speed increases by 10 feet.
@@ -613,11 +657,12 @@ class Bladesong(Feature):
- You gain a bonus to any Constitution saving throw you make to
maintain your concentration on a spell. The bonus equals your
Intelligence modifier (minimum of +l).
You can use this feature twice. You regain all expended uses of it
when you finish a short or long rest.
"""
name = "Bladesong (2x/SR)"
source = "Wizard (School of Bladesinging)"
@@ -627,6 +672,7 @@ class ExtraAttackBladesinging(Feature):
take the Attack action on your turn.
"""
name = "Extra Attack (2x)"
source = "Wizard (School of Bladesinging)"
@@ -638,6 +684,7 @@ class SongOfDefense(Feature):
amount equal to five times the spell slot's level.
"""
name = "Song of Defense"
source = "Wizard (School of Bladesinging)"
@@ -647,6 +694,7 @@ class SongOfVictory(Feature):
to the damage of your melee weapon attacks while you r Bladesong is active
"""
name = "Song of Victory"
source = "Wizard (School of Bladesinging)"
@@ -660,6 +708,7 @@ class ArcaneDeflection(Feature):
cast spells other than cantrips until the end of your next turn.
"""
name = "Arcane Deflection"
source = "Wizard (School of War Magic)"
@@ -671,6 +720,7 @@ class TacticalWit(Feature):
character sheet).
"""
name = "Tactical Wit"
source = "Wizard (School of War Magic)"
@@ -690,6 +740,7 @@ class PowerSurge(Feature):
target. The ex- tra damage equals half your wizard level.
"""
name = "Power Surge"
source = "Wizard (School of War Magic)"
@@ -700,6 +751,7 @@ class DurableMagic(Feature):
saving throws.
"""
name = "Durable Magic"
source = "Wizard (School of War Magic)"
@@ -712,5 +764,6 @@ class DeflectingShroud(Feature):
level.
"""
name = "Deflecting Shroud"
source = "Wizard (School of War Magic)"