refactor(combat): single source active_buffs/active_conditions

This commit is contained in:
ctan
2026-08-31 14:24:57 +02:00
parent 12c76a1396
commit 3cebf43642
2 changed files with 23 additions and 16 deletions
+23 -5
View File
@@ -255,14 +255,14 @@ class TestHoldPerson:
target = _make_target()
engine, c, t = _make_engine(caster, target, [2])
engine._cast_spell(c, t, "Hold Person")
assert any(cond.name == "paralyzed" for cond in t.conditions)
assert any(ac.condition.name == "paralyzed" for ac in t.active_conditions)
def test_successful_save_no_condition(self) -> None:
caster = _make_caster()
target = _make_target()
engine, c, t = _make_engine(caster, target, [20])
engine._cast_spell(c, t, "Hold Person")
assert not any(cond.name == "paralyzed" for cond in t.conditions)
assert not any(ac.condition.name == "paralyzed" for ac in t.active_conditions)
def test_transcript_shows_negated_on_save(self) -> None:
caster = _make_caster()
@@ -282,7 +282,7 @@ class TestFear:
target = _make_target()
engine, c, t = _make_engine(caster, target, [2])
engine._cast_spell(c, t, "Fear")
assert any(cond.name == "frightened" for cond in t.conditions)
assert any(ac.condition.name == "frightened" for ac in t.active_conditions)
class TestCureLightWounds:
@@ -317,8 +317,9 @@ class TestBullsStrength:
target = _make_target()
engine, c, t = _make_engine(caster, target, [3, 3], target_pos=(1, 0))
engine._cast_spell(c, t, "Bull's Strength")
atk_mods = [e for e in t.effects if e.target == "attack"]
dmg_mods = [e for e in t.effects if e.target == "damage"]
buff_mods = [m for b in t.active_buffs for m in b.modifiers]
atk_mods = [e for e in buff_mods if e.target == "attack"]
dmg_mods = [e for e in buff_mods if e.target == "damage"]
assert len(atk_mods) == 1
assert len(dmg_mods) == 1
assert atk_mods[0].value == 1
@@ -461,3 +462,20 @@ class TestSpellSlots:
engine._cast_spell(c, t, "Magic Missile") # spends the only level-1 slot
assert c.spell_slots_left[1] == 0
assert _choose_spell_action(engine, c, t) is None
class TestActiveIsSingleSource:
"""Given: active_* is the single source of truth for conditions and buffs
When: _cast_spell applies a condition and a buff
Then: the legacy conditions/effects lists stay empty while the active_* lists are populated."""
def test_legacy_lists_stay_empty_active_lists_populated(self) -> None:
caster = _make_caster()
target = _make_target()
engine, c, t = _make_engine(caster, target, [2, 3, 3], target_pos=(1, 0))
engine._cast_spell(c, t, "Hold Person")
engine._cast_spell(c, t, "Bull's Strength")
assert t.conditions == []
assert t.effects == []
assert any(ac.condition.name == "paralyzed" for ac in t.active_conditions)
assert any(b.source.startswith("spell:") for b in t.active_buffs)