Expansion wave 3: twelve terrain cards
KILLER OOZE (1 damage on entry, slip on 1-2: drop treasure, 2 more, flat on your face until you roll to stand), CREATE PIT (jumps roll a D4 — clear it on 2-4, fall in on a 1 and climb out on later rolls), ROSEBUSH (3-point passage, blocks sight), DUST CLOUD (a permanent zone of blindness: direction rolls inside, no LOS through, defeats Visionstone), FILL SQUARE WITH SLIME (entering ends your actions, blocks sight), HANDFUL OF TACKS (adjacent-only scatter, 3 points to cross), CREATE DOOR (a new locked door in any wall or corridor), BOOBYTRAP (four face-down tokens, one secretly real — 4 points under anyone but the caster; the caster's view alone marks the true token), GLUE (objects pinned for twice the number card), SAFE (items locked away from everyone but the creator), TRADER (swap two floor items in sight; glue and safes hold fast), and STONE TO WATER (walls melt into range-2 waves, stone blocks into range-4 bursts). LOS blocking is now per-terrain-kind. The board renders all of it, boobytrap placement is a four-click ritual, and Trader is two. 108 tests passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
28949bdb7d
commit
3a35922a40
@@ -56,6 +56,8 @@ export interface GameView {
|
||||
creatures: CreatureState[];
|
||||
/** Charges left on displayed wands (public), by card instance id. */
|
||||
wandCharges: Record<string, number>;
|
||||
/** Boobytrap tokens: everyone sees the four; only the caster sees which is real. */
|
||||
boobytraps: { casterId: PlayerId; cells: { x: number; y: number }[]; realCell: { x: number; y: number } | null }[];
|
||||
}
|
||||
|
||||
export function viewFor(state: GameState, playerId: PlayerId): GameView {
|
||||
@@ -109,5 +111,13 @@ export function viewFor(state: GameState, playerId: PlayerId): GameView {
|
||||
knownIllusionEdges,
|
||||
creatures: state.creatures.map((c) => ({ ...c, scorchedThisTurn: [...c.scorchedThisTurn] })),
|
||||
wandCharges: { ...state.wandCharges },
|
||||
boobytraps: state.boobytraps.map((t) => {
|
||||
const [rx, ry] = t.realKey.split(",").map(Number) as [number, number];
|
||||
return {
|
||||
casterId: t.casterId,
|
||||
cells: t.cells.map((c) => ({ ...c })),
|
||||
realCell: t.casterId === playerId ? { x: rx, y: ry } : null,
|
||||
};
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user