diff --git a/packages/engine/src/game.ts b/packages/engine/src/game.ts index 843fb0f..b152b94 100644 --- a/packages/engine/src/game.ts +++ b/packages/engine/src/game.ts @@ -2062,6 +2062,29 @@ const CARD_EFFECTS: Record kind: "neutral", resolve: () => "played out of turn — use it during another player's turn", }, + "swap-home-bases": { + kind: "neutral", + // "Swap your home base with any other player, as long as you both have an + // equal number of treasures on your home bases. You must be within L.O.S." + resolve: (state, events, caster, cmd) => { + if (!cmd.target || cmd.target.kind !== "player") return "choose whose home to take"; + const other = state.players.find((p) => p.id === (cmd.target as { playerId: PlayerId }).playerId); + if (!other || !other.alive) return "no such living player"; + if (other.id === caster.id) return "that is already your home"; + if (!gameLos(state, caster.position, other.position)) return "no line of sight to them"; + const onHome = (home: Cell) => + state.treasures.filter((t) => t.position && cellKey(t.position) === cellKey(home)).length; + if (onHome(caster.home) !== onHome(other.home)) { + return "your home bases must hold an equal number of treasures"; + } + const mine = caster.home; + caster.home = other.home; + other.home = mine; + events.push({ type: "positionsSwapped", a: caster.id, b: other.id, aTo: caster.home, bTo: other.home }); + checkVictory(state, events); + return null; + }, + }, "reuse-spell": { kind: "neutral", // "You may retrieve any spell you use immediately after you use it (but diff --git a/packages/engine/test/expansion-combat.test.ts b/packages/engine/test/expansion-combat.test.ts index f75f7d4..6665a41 100644 --- a/packages/engine/test/expansion-combat.test.ts +++ b/packages/engine/test/expansion-combat.test.ts @@ -209,3 +209,20 @@ describe("expansion combat cards", () => { } }); }); + +describe("swap home bases", () => { + it("trades homes when both bases hold equal treasures", () => { + let { state } = newGame(); + const me = activePlayer(state); + const other = state.players.find((p) => p.id !== me.id)!; + other.position = { ...me.position }; // LOS guaranteed + const myHome = { ...me.home }; + const theirHome = { ...other.home }; + const shb = giveCard(state, me.id, "swap-home-bases"); + state = must(state, me.id, { + type: "cast", instanceId: shb.instanceId, target: { kind: "player", playerId: other.id }, + }); + expect(cellKey(state.players.find((p) => p.id === me.id)!.home)).toBe(cellKey(theirHome)); + expect(cellKey(state.players.find((p) => p.id === other.id)!.home)).toBe(cellKey(myHome)); + }); +});