mirror of
https://github.com/Threnklyn/dungeon-sheets.git
synced 2026-05-22 21:58:28 +02:00
296 lines
11 KiB
Python
296 lines
11 KiB
Python
__all__ = ('Ranger', 'RevisedRanger')
|
|
|
|
from .. import (weapons, features, spells)
|
|
from .classes import CharClass, SubClass
|
|
from collections import defaultdict
|
|
|
|
|
|
# PHB
|
|
class Hunter(SubClass):
|
|
"""Emulating the Hunter archetype means accepting your place as a bulwark
|
|
between civilization and the terrors of the wilderness. As you walk the
|
|
Hunter's path, you learn specialized techniques for fighting the threats
|
|
you face, from rampaging ogres and hordes of orcs to towering giants and
|
|
terrifying dragons.
|
|
|
|
"""
|
|
name = "Hunter"
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[3] = [features.HuntersPrey]
|
|
features_by_level[7] = [features.DefensiveTactics]
|
|
features_by_level[11] = [features.MultiattackRanger]
|
|
features_by_level[15] = [features.SuperiorHuntersDefense]
|
|
|
|
|
|
class BeastMaster(SubClass):
|
|
"""The Beast Master archetype embodies a friendship between the civilized
|
|
races and the beasts of the world. United in focus, beast and ranger work
|
|
as one to fight the monstrous foes that threaten civilization and the
|
|
wilderness alike. Emulating the Beast Master archetype means committing
|
|
yourself to this ideal, working in partnership with an animal as its
|
|
companion and friend.
|
|
|
|
"""
|
|
name = "Beast Master"
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[3] = [features.RangersCompanion]
|
|
features_by_level[7] = [features.ExceptionalTraining]
|
|
features_by_level[11] = [features.BestialFury]
|
|
features_by_level[15] = [features.ShareSpells]
|
|
|
|
|
|
# XGTE
|
|
class GloomStalker(SubClass):
|
|
"""Gloom Stalkers are at home in the darkest places: deep under the earth, in
|
|
gloomy alleyways, in primeval forests, and wherever else the light
|
|
dims. Most folk enter such places with trepidation, but a Gloom Stalker
|
|
ventures boldly into the darkness, seeking to ambush threats before they
|
|
can reach the broader world. Such rangers are often found in the Underdark,
|
|
but they will go any place Where evil lurks in the shadows
|
|
|
|
"""
|
|
name = "Gloom Stalker"
|
|
features_by_level = defaultdict(list)
|
|
_spells = {3: [spells.DisguiseSelf],
|
|
5: [spells.RopeTrick],
|
|
9: [spells.Fear],
|
|
13: [spells.GreaterInvisibility],
|
|
17: [spells.Seeming]}
|
|
features_by_level[3] = [features.DreadAmbusher, features.UmbralSight,
|
|
features.Darkvision]
|
|
features_by_level[7] = [features.IronMind]
|
|
features_by_level[11] = [features.StalkersFlurry]
|
|
features_by_level[15] = [features.ShadowyDodge]
|
|
|
|
@property
|
|
def level(self):
|
|
return self.owner.Ranger.level
|
|
|
|
@property
|
|
def spells_known(self):
|
|
spells = []
|
|
for lvl, sps in self._spells.items():
|
|
if self.level >= lvl:
|
|
spells.extend(sps)
|
|
return spells
|
|
|
|
@property
|
|
def spells_prepared(self):
|
|
return self.spells_known
|
|
|
|
|
|
class HorizonWalker(SubClass):
|
|
"""Horizon Walkers guard the world against threats that originate from other
|
|
planes or that seek to ravage the mortal realm with otherworldly
|
|
magic. They seek out planar portals and keep watch over them, venturing to
|
|
the Inner Planes and the Outer Planes as needed to pursue their foes. These
|
|
rangers are also friends to any forces in the multiverse-especially
|
|
benevolent dragons, fey, and elementals-that work to preserve life and the
|
|
order of the planes
|
|
|
|
"""
|
|
name = "Horizon Walker"
|
|
_spells = {3: [spells.ProtectionFromEvilAndGood],
|
|
5: [spells.MistyStep],
|
|
9: [spells.Haste],
|
|
13: [spells.Banishment],
|
|
17: [spells.TeleportationCircle]}
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[3] = [features.DetectPortal, features.PlanarWarrior]
|
|
features_by_level[7] = [features.EtherealStep]
|
|
features_by_level[11] = [features.DistantStrike]
|
|
features_by_level[15] = [features.SpectralDefense]
|
|
|
|
@property
|
|
def level(self):
|
|
return self.owner.Ranger.level
|
|
|
|
@property
|
|
def spells_known(self):
|
|
spells = []
|
|
for lvl, sps in self._spells.items():
|
|
if self.level >= lvl:
|
|
spells.extend(sps)
|
|
return spells
|
|
|
|
@property
|
|
def spells_prepared(self):
|
|
return self.spells_known
|
|
|
|
|
|
class MonsterSlayer(SubClass):
|
|
"""You have dedicated yourself to hunting down creatures of the night and
|
|
wielders of grim magic. A Monster Slayer seeks out vampires, dragons, evil
|
|
fey, fiends, and other magical threats. Trained in supernatural tech-
|
|
niques to overcome such monsters, Slayers are experts at unearthing and
|
|
defeating mighty, mystical foes.
|
|
|
|
"""
|
|
name = "Monster Slayer"
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[3] = [features.HuntersSense, features.SlayersPrey]
|
|
features_by_level[7] = [features.SupernaturalDefense]
|
|
features_by_level[11] = [features.MagicUsersNemesis]
|
|
features_by_level[15] = [features.SlayersCounter]
|
|
_spells = {3: [spells.ProtectionFromEvilAndGood],
|
|
5: [spells.ZoneOfTruth],
|
|
9: [spells.MagicCircle],
|
|
13: [spells.Banishment],
|
|
17: [spells.HoldMonster]}
|
|
|
|
@property
|
|
def level(self):
|
|
return self.owner.Ranger.level
|
|
|
|
@property
|
|
def spells_known(self):
|
|
spells = []
|
|
for lvl, sps in self._spells.items():
|
|
if self.level >= lvl:
|
|
spells.extend(sps)
|
|
return spells
|
|
|
|
@property
|
|
def spells_prepared(self):
|
|
return self.spells_known
|
|
|
|
|
|
class Ranger(CharClass):
|
|
name = 'Ranger'
|
|
hit_dice_faces = 10
|
|
saving_throw_proficiencies = ('strength', 'dexterity')
|
|
primary_abilities = ('dexterity', 'wisdom')
|
|
_proficiencies_text = ("light armor", "medium armor", "shields",
|
|
"simple weapons", "martial weapons")
|
|
weapon_proficiencies = (weapons.SimpleWeapon, weapons.MartialWeapon)
|
|
multiclass_weapon_proficiencies = weapon_proficiencies
|
|
_multiclass_proficiencies_text = ('light armor', 'medium armor', 'shields',
|
|
'simple weapons', 'martial weapons',
|
|
'[choose one skill from Ranger list]')
|
|
class_skill_choices = ('Animal Handling', 'Athletics', 'Insight',
|
|
'Investigation', 'Nature', 'Perception', 'Stealth',
|
|
'Survival')
|
|
num_skill_choices = 3
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[1] = [features.FavoredEnemy, features.NaturalExplorer]
|
|
features_by_level[2] = [features.RangerFightingStyle]
|
|
features_by_level[3] = [features.PrimevalAwareness]
|
|
features_by_level[5] = [features.ExtraAttackRanger]
|
|
features_by_level[8] = [features.LandsStride]
|
|
features_by_level[10] = [features.HideInPlainSight]
|
|
features_by_level[14] = [features.Vanish]
|
|
features_by_level[18] = [features.FeralSenses]
|
|
features_by_level[20] = [features.FoeSlayer]
|
|
subclasses_available = (Hunter, BeastMaster, GloomStalker,
|
|
HorizonWalker, MonsterSlayer)
|
|
spellcasting_ability = 'wisdom'
|
|
spell_slots_by_level = {
|
|
# char_lvl: (cantrips, 1st, 2nd, 3rd, ...)
|
|
1: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
2: (0, 2, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
3: (0, 3, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
4: (0, 3, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
5: (0, 4, 2, 0, 0, 0, 0, 0, 0, 0),
|
|
6: (0, 4, 2, 0, 0, 0, 0, 0, 0, 0),
|
|
7: (0, 4, 3, 0, 0, 0, 0, 0, 0, 0),
|
|
8: (0, 4, 3, 0, 0, 0, 0, 0, 0, 0),
|
|
9: (0, 4, 3, 2, 0, 0, 0, 0, 0, 0),
|
|
10: (0, 4, 3, 2, 0, 0, 0, 0, 0, 0),
|
|
11: (0, 4, 3, 3, 0, 0, 0, 0, 0, 0),
|
|
12: (0, 4, 3, 3, 0, 0, 0, 0, 0, 0),
|
|
13: (0, 4, 3, 3, 1, 0, 0, 0, 0, 0),
|
|
14: (0, 4, 3, 3, 1, 0, 0, 0, 0, 0),
|
|
15: (0, 4, 3, 3, 2, 0, 0, 0, 0, 0),
|
|
16: (0, 4, 3, 3, 2, 0, 0, 0, 0, 0),
|
|
17: (0, 4, 3, 3, 3, 1, 0, 0, 0, 0),
|
|
18: (0, 4, 3, 3, 3, 1, 0, 0, 0, 0),
|
|
19: (0, 4, 3, 3, 3, 2, 0, 0, 0, 0),
|
|
20: (0, 4, 3, 3, 3, 2, 0, 0, 0, 0),
|
|
}
|
|
|
|
|
|
# Revised Ranger
|
|
class BeastConclave(SubClass):
|
|
"""Many rangers are more at home in the wilds than in civilization, to the
|
|
point where animals consider them kin. Rangers of the Beast Conclave
|
|
develop a close bond with a beast, then further strengthen that bond
|
|
through the use of magic.
|
|
|
|
"""
|
|
name = "Beast Conclave"
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[3] = [features.AnimalCompanion, features.CompanionsBond]
|
|
features_by_level[5] = [features.CoordinatedAttack]
|
|
features_by_level[7] = [features.BeastsDefense]
|
|
features_by_level[11] = [features.StormOfClawsAndFangs]
|
|
features_by_level[15] = [features.SuperiorBeastsDefense]
|
|
|
|
|
|
class HunterConclave(SubClass):
|
|
"""Some rangers seek to master weapons to better protect civilization from the
|
|
terrors of the wilderness. Members of the Hunter Conclave learn specialized
|
|
fighting techniques for use against the most dire threats, from rampaging
|
|
ogres and hordes of orcs to towering giants and terrifying dragons
|
|
|
|
"""
|
|
name = "Hunter Conclave"
|
|
features_by_level = defaultdict(list)
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[3] = [features.HuntersPrey]
|
|
features_by_level[5] = [features.ExtraAttackRanger]
|
|
features_by_level[7] = [features.DefensiveTactics]
|
|
features_by_level[11] = [features.MultiattackRanger]
|
|
features_by_level[15] = [features.SuperiorHuntersDefense]
|
|
|
|
|
|
class DeepStalkerConclave(SubClass):
|
|
"""Most folk descend into the depths of the Underdark only under the most
|
|
pressing conditions, undertaking some desperate quest or following the
|
|
promise of vast riches. All too often, evil festers beneath the earth
|
|
unnoticed, and rangers of the Deep Stalker Conclave strive to uncover and
|
|
defeat such threats before they can reach the surface.
|
|
|
|
"""
|
|
name = "Deep Stalker Conclave"
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[3] = [features.UnderdarkScout]
|
|
features_by_level[5] = [features.ExtraAttackRanger]
|
|
features_by_level[7] = [features.IronMind]
|
|
features_by_level[11] = [features.StalkersFlurry]
|
|
features_by_level[15] = [features.StalkersDodge]
|
|
_spells = {3: [spells.DisguiseSelf],
|
|
5: [spells.RopeTrick],
|
|
9: [spells.GlyphOfWarding],
|
|
13: [spells.GreaterInvisibility],
|
|
17: [spells.Seeming]}
|
|
|
|
@property
|
|
def spells_prepared(self):
|
|
level = self.owner.Ranger.level
|
|
my_spells = []
|
|
for lvl, sps in self._spells.items():
|
|
if level >= lvl:
|
|
my_spells.extend(sps)
|
|
return my_spells
|
|
|
|
@property
|
|
def spells_known(self):
|
|
return self.spells_prepared
|
|
|
|
|
|
class RevisedRanger(Ranger):
|
|
name = 'Revised Ranger'
|
|
features_by_level = defaultdict(list)
|
|
features_by_level[1] = [features.FavoredEnemyRevised,
|
|
features.NaturalExplorerRevised]
|
|
features_by_level[2] = [features.RangerFightingStyle]
|
|
features_by_level[3] = [features.PrimevalAwarenessRevised]
|
|
features_by_level[6] = [features.GreaterFavoredEnemy]
|
|
features_by_level[8] = [features.FleetOfFoot]
|
|
features_by_level[10] = [features.HideInPlainSightRevised]
|
|
features_by_level[14] = [features.Vanish]
|
|
features_by_level[18] = [features.FeralSenses]
|
|
features_by_level[20] = [features.FoeSlayer]
|
|
subclasses_available = (BeastConclave, HunterConclave, DeepStalkerConclave)
|
|
|