fix(rules): harmless spells on willing targets forgo the save roll - SpellSpec gains a data-driven 'harmless' flag set on the 29 SRD '(harmless)' spells (verified one by one against the KB); a same-side/self target consumes NO save die (SRD saving-throw.md: '(harmless) ... can attempt a saving throw if it desires' + 'Voluntarily Giving up a Saving Throw'), while hostile targets and undead receiving a cure (harmful to them, Will half for undead damage) keep the roll; snapshot spell summaries expose 'harmless'; golden transcript unchanged (no harmless-save cast in it); +8 tests, 3 fixtures re-pinned for the removed die

This commit is contained in:
2026-09-19 22:27:46 +02:00
parent ea835293a0
commit 4665a1c245
37 changed files with 266 additions and 12 deletions
+5 -2
View File
@@ -665,7 +665,10 @@ class TestCureLightWounds:
def test_heals_damage(self) -> None:
caster = _make_caster()
target = _make_target(hp_max=30)
engine, c, t = _make_engine(caster, target, [3, 5], target_pos=(1, 0),
# Willing same-side target of a (harmless) spell: no Will die is
# consumed (SRD saving-throw.md "(harmless)" + "Voluntarily Giving up
# a Saving Throw") — the queue holds only the heal die.
engine, c, t = _make_engine(caster, target, [5], target_pos=(1, 0),
target_side="players")
t.hp = 10
engine._cast_spell(c, t, "Cure Light Wounds")
@@ -676,7 +679,7 @@ class TestCureLightWounds:
def test_heal_capped_at_max(self) -> None:
caster = _make_caster()
target = _make_target(hp_max=30)
engine, c, t = _make_engine(caster, target, [3, 3, 6], target_pos=(1, 0),
engine, c, t = _make_engine(caster, target, [3], target_pos=(1, 0),
target_side="players")
t.hp = 28
engine._cast_spell(c, t, "Cure Light Wounds")