fix(rules): exclude the caster from a line spell's area

CRB Magic - Aiming a Spell: a line 'starts from any corner of your square', so the caster's own square is outside the template (SRD Lightning Bolt: 'The bolt begins at your fingertips' - it leaves the square, it does not fill it). line_cells now drops the origin and takes the length_cells squares beyond it; a degenerate aim affects nothing. Updated the Lightning Bolt and Line Sparks tests (caster no longer caught) and the README.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-09-13 11:30:30 +02:00
parent ee8c8f80ff
commit 642f449b9e
4 changed files with 38 additions and 24 deletions
+4 -3
View File
@@ -197,8 +197,9 @@ def test_line_hits_the_straight_ray_only() -> None:
"""Given: caster (6,2) aiming east at foe_ray (6,5); foe_off (5,5) sits a
row away, foe_west (6,0) is behind the caster
When: cast the 120-ft line aimed at foe_ray
Then: every creature ON the ray (the caster's own cell — the line starts
at your fingertips — and foe_ray) takes damage; the off-row and the
Then: every creature ON the ray beyond the caster's own square (foe_ray)
takes damage; the caster's own cell is NOT part of the line (CRB: it
"starts from any corner of your square"), and the off-row and the
behind-caster foes are outside the 5-ft-wide template."""
caster = _caster()
foe_ray = make_state(make_combatant("foe_ray", hp=100), "monsters", (6, 5))
@@ -210,7 +211,7 @@ def test_line_hits_the_straight_ray_only() -> None:
)
assert result.ok
assert foe_ray.hp == 100 - 4
assert caster.hp == 100 - 4 # the line's first square is the caster's own
assert caster.hp == 100 # the caster's own square is outside the line
assert foe_off.hp == 100
assert foe_west.hp == 100