fix(rules): document the burst center-to-center convention as a deferred SRD approximation - the SRD (aiming-a-spell.md) measures a burst from a grid INTERSECTION with the far-edge rule ('count from intersection to intersection'; a square is inside only 'if the far edge of a square is within the spell's area'), but the engine's burst origin is a CELL (target_pos, centered_on_caster, resolved target) counted center-to-center 5-10-5 in _creatures_in_range; matching RAW exactly needs an intersection coordinate added to AreaEffect/Action.target_pos/the observation area snapshot contract plus a per-caster corner choice (the far-edge boundary result depends entirely on which of the cell's four corners is the origin), so it is DEFERRED with a precise explanation in areas.py and a pointer from _creatures_in_range; no behavior change, golden untouched
This commit is contained in:
@@ -32,6 +32,37 @@ PF1e (CRB, Magic — Aiming a Spell):
|
|||||||
Bursts need no template here: they are circles around a center cell and are
|
Bursts need no template here: they are circles around a center cell and are
|
||||||
resolved by ``CombatEngine._area_creatures`` (which additionally drops
|
resolved by ``CombatEngine._area_creatures`` (which additionally drops
|
||||||
creatures without line of effect from the burst's center).
|
creatures without line of effect from the burst's center).
|
||||||
|
|
||||||
|
BURST MEASUREMENT - DOCUMENTED DEFERRED APPROXIMATION (cell vs intersection).
|
||||||
|
The SRD ("Aiming a Spell - Area") measures a burst from a point of origin that
|
||||||
|
is ALWAYS a grid intersection: "instead of counting from the center of one
|
||||||
|
square to the center of the next, you count from intersection to intersection",
|
||||||
|
and a square is inside the area only "if the far edge of a square is within the
|
||||||
|
spell's area" (a square the area "only touches ... [at] the near edge" is
|
||||||
|
unaffected). The engine cannot apply that rule faithfully because its burst
|
||||||
|
origin is a CELL, not an intersection: ``Action.target_pos``, the
|
||||||
|
``centered_on_caster`` caster square and the resolved target's square are all
|
||||||
|
cells, and ``CombatEngine._creatures_in_range`` counts center-to-center 5-10-5
|
||||||
|
(``grid.distance(center, cell) <= radius_cells``). Two consequences make a
|
||||||
|
faithful fix out of scope for a contract-preserving pass:
|
||||||
|
|
||||||
|
1. A cell has four corner intersections, and which one is the point of origin
|
||||||
|
is a caster choice the engine never records. The far-edge rule's boundary
|
||||||
|
result (which diagonal squares are in vs out) depends entirely on that
|
||||||
|
choice, so there is no single "SRD-correct" square set to compute from a
|
||||||
|
cell center without first adding an intersection coordinate to the data
|
||||||
|
model.
|
||||||
|
2. Representing the origin as an intersection would change ``AreaEffect``,
|
||||||
|
``Action.target_pos`` and the observation ``area`` snapshot contract (a
|
||||||
|
documented Phase 2 LLM frontier), and would rework the burst line-of-effect
|
||||||
|
and Reflex-cover origins (``{aim}`` / ``{center}`` cells).
|
||||||
|
|
||||||
|
Until that representation change is made, bursts stay centered on the resolved
|
||||||
|
cell and measured center-to-center under 5-10-5 - a symmetric, conservative
|
||||||
|
approximation whose boundary squares can differ from RAW by one square on
|
||||||
|
diagonals (e.g. a 15/20-ft burst's far diagonal cells). This is the residual
|
||||||
|
recorded in docs/conformance-srd.md ("origin mesuré centre-à-centre plutôt
|
||||||
|
qu'intersection-à-intersection").
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|||||||
@@ -7573,6 +7573,12 @@ class CombatEngine:
|
|||||||
) -> list[CombatantState]:
|
) -> list[CombatantState]:
|
||||||
"""Return creatures within radius_cells of center.
|
"""Return creatures within radius_cells of center.
|
||||||
|
|
||||||
|
The burst center is a CELL and the radius is counted center-to-center
|
||||||
|
under 5-10-5 - a documented approximation of the SRD's
|
||||||
|
intersection-to-intersection far-edge measurement (see the
|
||||||
|
"BURST MEASUREMENT" note in ``areas.py`` for why a faithful
|
||||||
|
intersection origin is deferred).
|
||||||
|
|
||||||
``active_only`` (default) keeps only acting creatures; an area spell
|
``active_only`` (default) keeps only acting creatures; an area spell
|
||||||
passes False so its burst also catches dying/unconscious creatures
|
passes False so its burst also catches dying/unconscious creatures
|
||||||
(SRD aiming-a-spell.md: a burst "affects whatever it catches in its
|
(SRD aiming-a-spell.md: a burst "affects whatever it catches in its
|
||||||
|
|||||||
Reference in New Issue
Block a user