fix(rules): condition durations scale with caster level (hold person, doom, touch of fatigue, vanish)
ConditionEffect gains duration_rounds_per_level and max_duration_rounds (mirroring PenaltyEffect), applied as caster_level * per_level rounds capped at max: hold person 1 rd/lvl, doom 1 min/lvl, touch of fatigue 1 rd/lvl, vanish 1 rd/lvl (max 5). Extend Spell doubles both the per-level rate and the cap. Tests cover scaling and the vanish cap.
This commit is contained in:
@@ -551,6 +551,40 @@ class TestHoldPerson:
|
||||
assert any("negated" in line for line in engine._transcript)
|
||||
|
||||
|
||||
class TestConditionDurationScaling:
|
||||
"""Given: a ConditionEffect with duration_rounds_per_level (SRD hold person
|
||||
"1 round/level", doom "1 min./level", vanish "1 round/level (maximum 5)")
|
||||
When: the spell is cast
|
||||
Then: the condition lasts caster_level * per_level rounds, capped at max."""
|
||||
|
||||
def test_hold_person_scales_with_caster_level(self) -> None:
|
||||
caster = _make_caster(level=5)
|
||||
target = _make_target()
|
||||
engine, c, t = _make_engine(caster, target, [2])
|
||||
engine._cast_spell(c, t, "Hold Person")
|
||||
ac = next(ac for ac in t.active_conditions if ac.condition.name == "paralyzed")
|
||||
assert ac.rounds_left == 5 # 1 round/level
|
||||
|
||||
def test_vanish_caps_at_maximum(self) -> None:
|
||||
caster = _make_caster(level=8)
|
||||
target = _make_target()
|
||||
# Vanish is range touch: the target must be adjacent (5 ft).
|
||||
engine, c, t = _make_engine(
|
||||
caster, target, [2], target_pos=(1, 0), target_side="players"
|
||||
)
|
||||
engine._cast_spell(c, t, "Vanish")
|
||||
ac = next(ac for ac in t.active_conditions if ac.condition.name == "invisible")
|
||||
assert ac.rounds_left == 5 # 1 round/level, maximum 5
|
||||
|
||||
def test_doom_scales_to_minutes(self) -> None:
|
||||
caster = _make_caster(level=5)
|
||||
target = _make_target()
|
||||
engine, c, t = _make_engine(caster, target, [2])
|
||||
engine._cast_spell(c, t, "Doom")
|
||||
ac = next(ac for ac in t.active_conditions if ac.condition.name == "shaken")
|
||||
assert ac.rounds_left == 50 # 1 min/level = 10 rounds/level
|
||||
|
||||
|
||||
class TestFear:
|
||||
"""Given: a caster casting Fear (SRD spells/fear.md: panicked unless the
|
||||
Will save succeeds; a successful save makes the creature shaken 1 round)
|
||||
|
||||
Reference in New Issue
Block a user