Around the Corner bends every spell, hairpins included
Two holes, found when a SAFE cast at a treasure 'around the 180 degree corner' refused with no line of sight (room LZ5R). First: the bend was honored only in the attack path — every neutral resolve (creations, summons, utilities, edge targets) checked straight sight and ignored the attached card, though the card says 'any line of sight spell'. castSight/castSightEdge now thread the bend through all of them, and the chronicle narrates the neutral bend too. Second: the bend itself pivoted only at cell centers, so the card's flagship shot — doubling back up to 180 degrees around a wall's end — never resolved: both legs graze the corner and die. The pivot may now sit in the wall's open gap itself (bentSightThroughGap), which is what rounding a corner physically is. Closed doors still block; two corners still refuse. The client lights bent-reachable squares for real now instead of the old one-step-adjacency guess, creations included. Pure widening, so no rev bump: every one of these casts was refused before, so no ledger holds one. All 26 production ledgers replay clean; the LZ5R moment itself replayed and the exact refused cast now lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
co-authored by
Claude Fable 5
parent
f53f26ace9
commit
3bf3c33fdc
@@ -480,3 +480,34 @@ export function sightBetween(
|
||||
return hasLineOfSight(board, from, to, blockedCells) ||
|
||||
hasWarpLineOfSight(board, from, to, blockedCells);
|
||||
}
|
||||
|
||||
/**
|
||||
* AROUND THE CORNER's full reach: "around one corner (up to 180 degrees)".
|
||||
* A hairpin around the end of a wall pivots IN the wall's gap, not at any
|
||||
* cell's center — so try the midpoint of every open edge as the bend point,
|
||||
* with a clear straight segment from caster to pivot and pivot to target.
|
||||
*/
|
||||
export function bentSightThroughGap(
|
||||
board: AssembledBoard,
|
||||
from: Cell,
|
||||
to: Cell,
|
||||
blockedCells?: Record<string, true>,
|
||||
): boolean {
|
||||
const fx = from.x + 0.5, fy = from.y + 0.5;
|
||||
const tx = to.x + 0.5, ty = to.y + 0.5;
|
||||
const skip = [cellKey(from), cellKey(to)];
|
||||
for (const key of Object.keys(board.cells)) {
|
||||
const [x, y] = key.split(",").map(Number) as [number, number];
|
||||
const c = { x, y };
|
||||
for (const side of ["E", "S"] as Side[]) {
|
||||
if (!board.cells[cellKey(neighbor(c, side))]) continue;
|
||||
if (edgeState(board, c, side) !== "open") continue;
|
||||
const [px, py] = side === "E" ? [x + 1, y + 0.5] : [x + 0.5, y + 1];
|
||||
if (segmentClear(board, fx, fy, px, py, blockedCells, skip) &&
|
||||
segmentClear(board, px, py, tx, ty, blockedCells, skip)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user