fix(rules): bursts cannot affect creatures in total cover from the point of origin (SRD aiming-a-spell.md: a burst "can't affect creatures with total cover from its point of origin (in other words, its effects don't extend around corners)"; Line of Effect: a burst affects only what it has LoE to from its origin) - _area_creatures skips creatures whose occupied cells have no line of effect from the burst center

This commit is contained in:
2026-09-19 14:08:24 +02:00
parent 389e160627
commit 948edc1815
3 changed files with 61 additions and 5 deletions
+45 -1
View File
@@ -327,10 +327,54 @@ def test_line_behind_a_wall_does_not_hit_sheltered_creatures() -> None:
# ---------------------------------------------------------------------------
# burst: unchanged circle around the resolved center
# burst: circle around the center, minus creatures in total cover of it
# ---------------------------------------------------------------------------
def test_burst_does_not_extend_around_a_solid_barrier() -> None:
"""Given: a 20-ft burst point-cast at center (6,3); wall cells at col 5
(rows 5-7); foe_open (4,3) inside the radius with clear LoE, foe_behind
(6,7) inside the radius but behind the wall (total cover from the
center)
When: the burst resolves (caster at (6,2) is in the radius too)
Then: the caster and foe_open take damage (two 1d6 consumed); foe_behind
is untouched - a burst "can't affect creatures with total cover from its
point of origin" (its effects don't extend around corners)."""
caster = _caster()
walls = frozenset({(5, 5), (6, 5), (7, 5)})
foe_open = make_state(make_combatant("foe_open", hp=100), "monsters", (4, 3))
foe_behind = make_state(make_combatant("foe_behind", hp=100), "monsters", (6, 7))
eng = CombatEngine(
ScriptedRng([4, 4]), _walled_grid(walls), [caster, foe_open, foe_behind],
spell_registry=_REGISTRY,
)
result = eng._execute(
caster, Action(kind="cast_spell", spell_name="Burst Sparks", target_pos=(6, 3))
)
assert result.ok
assert caster.hp == 100 - 4
assert foe_open.hp == 100 - 4
assert foe_behind.hp == 100
def test_burst_open_field_control_hits_creatures_behind_the_center() -> None:
"""Given: the same layout on an OPEN grid (no walls)
When: the 20-ft burst point-cast at (6,3) resolves
Then: all three creatures (caster, foe_open, foe_behind at distance 4)
are inside the radius and affected - the LoE filter drops nothing when
there is no barrier."""
caster = _caster()
foe_open = make_state(make_combatant("foe_open", hp=100), "monsters", (4, 3))
foe_behind = make_state(make_combatant("foe_behind", hp=100), "monsters", (6, 7))
eng = _engine([caster, foe_open, foe_behind], [4, 4, 4])
eng._execute(
caster, Action(kind="cast_spell", spell_name="Burst Sparks", target_pos=(6, 3))
)
assert caster.hp == 100 - 4
assert foe_open.hp == 100 - 4
assert foe_behind.hp == 100 - 4
def test_burst_still_centers_on_the_target_and_ignores_the_caster_side() -> None:
"""Given: caster (6,2); foe_in (4,4) and foe_out (2,0) around a burst
centered on target_id=foe_in (radius 20 ft = 4 cells)