fix(rules): correct metamagic slots, touch-spell delivery, and defensive/grapple casting
This commit is contained in:
+12
-6
@@ -114,9 +114,10 @@ def _make_engine(
|
||||
caster_pos: tuple[int, int] = (0, 0),
|
||||
target_pos: tuple[int, int] = (3, 0),
|
||||
spell_registry: dict[str, SpellSpec] | None = None,
|
||||
target_side: str = "monsters",
|
||||
) -> tuple[CombatEngine, CombatantState, CombatantState]:
|
||||
c = CombatantState(combatant=caster, side="players", pos=caster_pos, hp=caster.hp_max)
|
||||
t = CombatantState(combatant=target, side="monsters", pos=target_pos, hp=target.hp_max)
|
||||
t = CombatantState(combatant=target, side=target_side, pos=target_pos, hp=target.hp_max)
|
||||
legend = {".": TerrainType(type="floor", move_cost=1)}
|
||||
spec = MapSpec(name="test", terrain=tuple(["." * 12] * 12), legend=legend)
|
||||
grid = Grid.from_spec(spec)
|
||||
@@ -435,7 +436,8 @@ 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, 3, 5], target_pos=(1, 0))
|
||||
engine, c, t = _make_engine(caster, target, [3, 5], target_pos=(1, 0),
|
||||
target_side="players")
|
||||
t.hp = 10
|
||||
engine._cast_spell(c, t, "Cure Light Wounds")
|
||||
assert t.hp == 10 + (5 + 1)
|
||||
@@ -443,7 +445,8 @@ 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, 3, 6], target_pos=(1, 0),
|
||||
target_side="players")
|
||||
t.hp = 28
|
||||
engine._cast_spell(c, t, "Cure Light Wounds")
|
||||
assert t.hp == 30
|
||||
@@ -457,7 +460,8 @@ class TestBullsStrength:
|
||||
def test_applies_buff_effects(self) -> None:
|
||||
caster = _make_caster()
|
||||
target = _make_target()
|
||||
engine, c, t = _make_engine(caster, target, [3, 3], target_pos=(1, 0))
|
||||
engine, c, t = _make_engine(caster, target, [3, 3], target_pos=(1, 0),
|
||||
target_side="players")
|
||||
engine._cast_spell(c, t, "Bull's Strength")
|
||||
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"]
|
||||
@@ -470,7 +474,8 @@ class TestBullsStrength:
|
||||
def test_transcript_shows_buff(self) -> None:
|
||||
caster = _make_caster()
|
||||
target = _make_target()
|
||||
engine, c, t = _make_engine(caster, target, [3, 3], target_pos=(1, 0))
|
||||
engine, c, t = _make_engine(caster, target, [3, 3], target_pos=(1, 0),
|
||||
target_side="players")
|
||||
engine._cast_spell(c, t, "Bull's Strength")
|
||||
assert any("buff" in line for line in engine._transcript)
|
||||
|
||||
@@ -614,7 +619,8 @@ class TestActiveIsSingleSource:
|
||||
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, c, t = _make_engine(caster, target, [2, 3, 3], target_pos=(1, 0),
|
||||
target_side="players")
|
||||
engine._cast_spell(c, t, "Hold Person")
|
||||
engine._cast_spell(c, t, "Bull's Strength")
|
||||
assert t.conditions == []
|
||||
|
||||
Reference in New Issue
Block a user