Rev 15: the held doorway carries sight — the whole point of holding it
The table holds doors open to cast back through them at pursuers; our held door opened for feet but not for eyes. From rev 15 a held door is an open doorway to sight — casting at players, creatures, and squares sees through it, the client's dimming aid and the automatons alike (they share sightedCellsFor). REMOVE LOCK's "still considered to block L.O.S." stands: that speaks of a CLOSED door, and an unheld unlocked door still blocks. Rev-gated because rev-14 ledgers may already contain holds and must replay blind. Pinned three ways: the holder blasts a pursuer through the held doorway; an unheld unlocked door still blocks; rev 14 stays blind. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a0c65413ef
commit
adf463effa
@@ -409,3 +409,68 @@ describe("holding the door open (Pick Lock / Master Key)", () => {
|
||||
expect(released).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a held door is an open doorway to the eye (rules rev 15)", () => {
|
||||
function sightRig(deckRev: number) {
|
||||
let { state } = createGame({ playerIds: ["holder", "pursuer"], seed: 42, sets: ["basic"], deckRev });
|
||||
state = toRound2(state);
|
||||
const view = boardView(state);
|
||||
for (const [key, edge] of Object.entries(view.edges)) {
|
||||
if (edge !== "door") continue;
|
||||
const [kind, coords] = key.split(":") as [string, string];
|
||||
const [x, y] = coords.split(",").map(Number) as [number, number];
|
||||
const cell = { x, y };
|
||||
const side = kind === "V" ? ("E" as Side) : ("S" as Side);
|
||||
const holder = activePlayer(state);
|
||||
const pursuer = state.players.find((p) => p.id !== holder.id)!;
|
||||
holder.position = { ...cell };
|
||||
pursuer.position = neighbor(cell, side);
|
||||
return { state, cell, side, holder: holder.id, pursuer: pursuer.id };
|
||||
}
|
||||
throw new Error("setup: seed 42 grew a maze with no doors");
|
||||
}
|
||||
|
||||
it("rev 15: the holder blasts the pursuer through the doorway", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig(15);
|
||||
const pick = giveCard(state, holder, "pick-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: pick.instanceId,
|
||||
target: { kind: "edge", cell, side }, params: { hold: true },
|
||||
});
|
||||
const fb = giveCard(state, holder, "fireball", "FB", 1);
|
||||
const lifeBefore = state.players.find((p) => p.id === pursuer)!.life;
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: pursuer },
|
||||
});
|
||||
state = must(state, pursuer, { type: "pass" });
|
||||
expect(state.players.find((p) => p.id === pursuer)!.life).toBeLessThan(lifeBefore);
|
||||
});
|
||||
|
||||
it("an unheld unlocked door still blocks sight", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig(15);
|
||||
const pick = giveCard(state, holder, "pick-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: pick.instanceId,
|
||||
target: { kind: "edge", cell, side },
|
||||
});
|
||||
const fb = giveCard(state, holder, "fireball", "FB", 1);
|
||||
const refused = applyCommand(state, holder, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: pursuer },
|
||||
});
|
||||
expect(refused.ok).toBe(false);
|
||||
});
|
||||
|
||||
it("earlier revisions keep the blocked sightline, hold or no", () => {
|
||||
let { state, cell, side, holder, pursuer } = sightRig(14);
|
||||
const pick = giveCard(state, holder, "pick-lock");
|
||||
state = must(state, holder, {
|
||||
type: "cast", instanceId: pick.instanceId,
|
||||
target: { kind: "edge", cell, side }, params: { hold: true },
|
||||
});
|
||||
const fb = giveCard(state, holder, "fireball", "FB", 1);
|
||||
const refused = applyCommand(state, holder, {
|
||||
type: "cast", instanceId: fb.instanceId, target: { kind: "player", playerId: pursuer },
|
||||
});
|
||||
expect(refused.ok).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user