From ac45cb87583f249b7cf9433be11be1845aa6274b Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Wed, 25 Feb 2026 09:26:14 -0500 Subject: [PATCH] Add ironclad end-of-combat heal passive --- src/main.js | 10 +++------- src/run.js | 8 ++++++++ src/run.test.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/main.js b/src/main.js index 9f54bba..1834b84 100644 --- a/src/main.js +++ b/src/main.js @@ -4,6 +4,7 @@ import { initEnemies } from "./enemies.js"; import { render } from "./render.js"; import { createRunState, + endCombat, pickReward, revealRewards, skipRewards, @@ -27,19 +28,14 @@ function startNewRun() { } function startNextCombat() { - run = { ...run, combatCount: run.combatCount + 1 }; state = createCombatFromRun(run, "jaw_worm"); state = startTurn(state); revealed = null; render(state, revealed); } -function syncRunHp() { - run = { ...run, hp: state.players[0].hp }; -} - function handleVictory() { - syncRunHp(); + run = endCombat(run, state.players[0].hp); const result = revealRewards(run); revealed = result.revealed; run = result.run; @@ -51,7 +47,7 @@ function handleVictory() { } function handleDefeat() { - syncRunHp(); + run = { ...run, hp: state.players[0].hp }; state = { ...state, combat: { ...state.combat, phase: "ended", result: "defeat" }, diff --git a/src/run.js b/src/run.js index be0daa2..9f7f9fa 100644 --- a/src/run.js +++ b/src/run.js @@ -13,6 +13,14 @@ export function createRunState(character) { }; } +export function endCombat(run, combatHp) { + let hp = combatHp; + if (run.character === "ironclad") { + hp = Math.min(hp + 1, run.maxHp); + } + return { ...run, hp, combatCount: run.combatCount + 1 }; +} + export function revealRewards(run) { const count = Math.min(3, run.cardRewardsDeck.length); const revealed = run.cardRewardsDeck.slice(0, count); diff --git a/src/run.test.js b/src/run.test.js index 59ae0db..b872066 100644 --- a/src/run.test.js +++ b/src/run.test.js @@ -3,6 +3,7 @@ import { getAllCards, initCards } from "./cards.js"; import { initEnemies } from "./enemies.js"; import { createRunState, + endCombat, pickReward, revealRewards, skipRewards, @@ -55,6 +56,39 @@ describe("createRunState", () => { }); }); +describe("endCombat", () => { + test("ironclad heals 1 HP after combat", () => { + const run = { ...createRunState("ironclad"), hp: 8 }; + const updated = endCombat(run, 8); + expect(updated.hp).toBe(9); + expect(updated.combatCount).toBe(1); + }); + + test("ironclad heal does not exceed maxHp", () => { + const run = { ...createRunState("ironclad"), hp: 11, maxHp: 11 }; + const updated = endCombat(run, 11); + expect(updated.hp).toBe(11); + }); + + test("non-ironclad characters do not heal", () => { + const run = { + character: "silent", + hp: 8, + maxHp: 13, + combatCount: 0, + }; + const updated = endCombat(run, 8); + expect(updated.hp).toBe(8); + }); + + test("combatCount increments", () => { + const run = createRunState("ironclad"); + const after1 = endCombat(run, run.hp); + const after2 = endCombat(after1, after1.hp); + expect(after2.combatCount).toBe(2); + }); +}); + describe("rewards", () => { test("revealRewards removes 3 from rewards deck and returns them", () => { const run = createRunState("ironclad");