import { getCard, initCards } from "./cards.js"; import { checkCombatEnd, resolveEnemyTurn, startTurn } from "./combat.js"; import { initEnemies } from "./enemies.js"; import { render } from "./render.js"; import { createRunState, pickReward, revealRewards, skipRewards, } from "./run.js"; import { createCombatFromRun, endTurn, playCard } from "./state.js"; let state = null; let run = null; let revealed = null; async function init() { await Promise.all([initCards(), initEnemies()]); startNewRun(); bindEvents(); } function startNewRun() { run = createRunState("ironclad"); revealed = null; startNextCombat(); } 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(); const result = revealRewards(run); revealed = result.revealed; run = result.run; state = { ...state, combat: { ...state.combat, phase: "rewards" }, }; render(state, revealed); } function handleDefeat() { syncRunHp(); state = { ...state, combat: { ...state.combat, phase: "ended", result: "defeat" }, }; render(state, revealed); } function checkEnd() { const end = checkCombatEnd(state); if (end === "victory") { handleVictory(); return true; } if (end === "defeat") { handleDefeat(); return true; } return false; } function bindEvents() { document.getElementById("hand").addEventListener("click", (e) => { const cardEl = e.target.closest(".card"); if (!cardEl || state.combat.phase !== "player_turn") return; const index = Number(cardEl.dataset.index); if (state.combat.selectedCard === index) { state = { ...state, combat: { ...state.combat, selectedCard: null } }; render(state, revealed); return; } state = { ...state, combat: { ...state.combat, selectedCard: index } }; const cardId = state.player.hand[index]; const card = getCard(cardId); if (card.type === "skill") { const result = playCard(state, index); if (result === null) { state = { ...state, combat: { ...state.combat, selectedCard: null } }; render(state, revealed); return; } state = { ...result, combat: { ...result.combat, selectedCard: null } }; if (!checkEnd()) render(state, revealed); return; } render(state, revealed); }); document.getElementById("enemy-zone").addEventListener("click", () => { if (state.combat.selectedCard === null) return; if (state.combat.phase !== "player_turn") return; const result = playCard(state, state.combat.selectedCard); if (result === null) { state = { ...state, combat: { ...state.combat, selectedCard: null } }; render(state, revealed); return; } state = { ...result, combat: { ...result.combat, selectedCard: null } }; if (!checkEnd()) render(state, revealed); }); document .getElementById("end-turn-btn") .addEventListener("click", async () => { if (state.combat.phase !== "player_turn") return; state = endTurn(state); render(state, revealed); await delay(800); state = resolveEnemyTurn(state); if (!checkEnd()) { state = startTurn(state); render(state, revealed); } }); document.getElementById("reward-cards").addEventListener("click", (e) => { const img = e.target.closest(".reward-card"); if (!img || !revealed) return; const cardId = img.dataset.cardId; const index = revealed.indexOf(cardId); if (index === -1) return; run = pickReward(run, revealed, index); startNextCombat(); }); document.getElementById("skip-btn").addEventListener("click", () => { if (!revealed) return; run = skipRewards(run, revealed); startNextCombat(); }); 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(); }); } function delay(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } init();