From febb05764b780894ce039059b6403e4260a551dd Mon Sep 17 00:00:00 2001 From: Jared Miller Date: Wed, 25 Feb 2026 09:54:55 -0500 Subject: [PATCH] Wire map into game loop with node-driven combat --- src/main.js | 62 ++++++++++++++++++++++++++++++++++++++++++--------- src/render.js | 11 +++++---- src/run.js | 2 ++ 3 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/main.js b/src/main.js index 1834b84..be4122e 100644 --- a/src/main.js +++ b/src/main.js @@ -1,7 +1,8 @@ import { getCard, initCards } from "./cards.js"; import { checkCombatEnd, resolveEnemyTurn, startTurn } from "./combat.js"; import { initEnemies } from "./enemies.js"; -import { render } from "./render.js"; +import { advanceMap, getCurrentNode, getNodeEnemy } from "./map.js"; +import { render, renderMap, showGame } from "./render.js"; import { createRunState, endCombat, @@ -24,18 +25,47 @@ async function init() { function startNewRun() { run = createRunState("ironclad"); revealed = null; - startNextCombat(); + showMapScreen(); } -function startNextCombat() { - state = createCombatFromRun(run, "jaw_worm"); +function showMapScreen() { + renderMap(run.map); +} + +function proceedFromMap() { + const node = getCurrentNode(run.map); + if (node.type === "campfire") { + console.debug("campfire — rest not yet implemented"); + run = { ...run, map: advanceMap(run.map) }; + showMapScreen(); + return; + } + const enemyId = getNodeEnemy(node.type); + startNextCombat(enemyId); +} + +function startNextCombat(enemyId) { + showGame(); + state = createCombatFromRun(run, enemyId); state = startTurn(state); revealed = null; render(state, revealed); } function handleVictory() { + const clearedNode = getCurrentNode(run.map); run = endCombat(run, state.players[0].hp); + run = { ...run, map: advanceMap(run.map) }; + + if (clearedNode.type === "boss") { + state = { + ...state, + combat: { ...state.combat, phase: "ended", result: "act_complete" }, + }; + render(state, revealed); + return; + } + const result = revealRewards(run); revealed = result.revealed; run = result.run; @@ -139,22 +169,34 @@ function bindEvents() { const index = revealed.indexOf(cardId); if (index === -1) return; run = pickReward(run, revealed, index); - startNextCombat(); + showMapScreen(); }); document.getElementById("skip-btn").addEventListener("click", () => { if (!revealed) return; run = skipRewards(run, revealed); - startNextCombat(); + showMapScreen(); }); + document + .getElementById("map-proceed-btn") + .addEventListener("click", proceedFromMap); + document.getElementById("overlay").addEventListener("click", (e) => { - // only restart on defeat overlay click (not reward cards or skip btn) - if (state.combat.phase !== "ended" || state.combat.result !== "defeat") - return; if (e.target.closest("#reward-cards") || e.target.closest("#skip-btn")) return; - startNewRun(); + // restart on defeat overlay click + if (state.combat.phase === "ended" && state.combat.result === "defeat") { + startNewRun(); + return; + } + // restart on act complete overlay click + if ( + state.combat.phase === "ended" && + state.combat.result === "act_complete" + ) { + startNewRun(); + } }); } diff --git a/src/render.js b/src/render.js index a8313ce..c4dffb5 100644 --- a/src/render.js +++ b/src/render.js @@ -156,10 +156,13 @@ function renderOverlay(state, revealed) { skipBtn.hidden = false; } else if (state.combat.phase === "ended") { overlay.hidden = false; - overlayText.textContent = - state.combat.result === "defeat" - ? "defeat — click to restart" - : "victory"; + if (state.combat.result === "defeat") { + overlayText.textContent = "defeat — click to restart"; + } else if (state.combat.result === "act_complete") { + overlayText.textContent = "act 1 complete! — click to start new run"; + } else { + overlayText.textContent = "victory"; + } rewardCards.innerHTML = ""; skipBtn.hidden = true; } else { diff --git a/src/run.js b/src/run.js index 9f7f9fa..cfc6a6d 100644 --- a/src/run.js +++ b/src/run.js @@ -1,4 +1,5 @@ import { getAllCards, getStarterDeck } from "./cards.js"; +import { createMap } from "./map.js"; import { shuffle } from "./state.js"; export function createRunState(character) { @@ -10,6 +11,7 @@ export function createRunState(character) { cardRewardsDeck: buildRewardsDeck(character), potions: [], combatCount: 0, + map: createMap(), }; }