/** * @license * SPDX-License-Identifier: Apache-2.0 */ import { Player, Enemy, MapArea, InventorySlot, Item, SavedGameState } from './types'; import { MAX_LOG_MESSAGES, SAVE_PREFIX } from './constants'; import { addMessageToArea, populateLoadSlotsListUI, updatePlayerStatsUI, updateEnemyUI, updateInventoryUI, updateEquippedUI, populateShopUI, updateMapSelectUI, updateMapUI, toggleCombatAreaVisibility, updateButtonDisabledStates, clearSaveSlotInput, getSaveSlotInputValue, confirmDelete } from './ui'; import { calculatePlayerStats, levelUpPlayer, generateAllMaps, completeCurrentMapLogic } from './gameLogic'; import { startCombatLogic, endCombatLogic, handlePlayerAttackLogic, handleEnemyAttackLogic, handleRunLogic } from './combatLogic'; import { handleExploreAction, handleRestAction, handleBuyItemAction, handleUseItemAction, handleMapTravelAction, handleSaveGameRequestAction, handleLoadGameRequestAction, handleDeleteSaveSlotAction // Import new delete handler } from './actions'; // --- Global Game State --- export let player: Player = { level: 1, hp: 100, baseMaxHp: 100, maxHp: 100, baseAttack: 6, attackPower: 6, baseDefense: 0, defense: 0, xp: 0, nextLevelXp: 50, money: 20, equipment: {}, inventory: [], }; export let allMaps: MapArea[] = []; export let currentMapIndex: number = 0; export let explorationActionsDoneOnMap: number = 0; export let currentEnemy: Enemy | null = null; export let isInCombat: boolean = false; export let isGameOver: boolean = false; // Used to disable actions, not for permanent game over from combat // --- DOM Element References --- export let messageArea: HTMLElement | null; export let playerLevelDisplay: HTMLElement | null; export let playerHpDisplay: HTMLElement | null; export let playerMaxHpDisplay: HTMLElement | null; export let playerAttackDisplay: HTMLElement | null; export let playerDefenseDisplay: HTMLElement | null; export let playerXpDisplay: HTMLElement | null; export let playerNextLevelXpDisplay: HTMLElement | null; export let playerMoneyDisplay: HTMLElement | null; export let exploreButton: HTMLButtonElement | null; export let restButton: HTMLButtonElement | null; export let shopItemsContainer: HTMLElement | null; export let inventoryListDisplay: HTMLElement | null; export let equippedWeaponDisplay: HTMLElement | null; export let equippedArmorDisplay: HTMLElement | null; export let mapSelectElement: HTMLSelectElement | null; export let combatArea: HTMLElement | null; export let enemyNameDisplay: HTMLElement | null; export let enemyHpDisplay: HTMLElement | null; export let enemyMaxHpDisplay: HTMLElement | null; export let attackButton: HTMLButtonElement | null; export let runButton: HTMLButtonElement | null; export let currentMapNameDisplay: HTMLElement | null; export let mapProgressDisplay: HTMLElement | null; export let saveSlotInput: HTMLInputElement | null; export let saveGameActionButton: HTMLButtonElement | null; export let loadSlotsList: HTMLElement | null; export let noSavesFoundMessage: HTMLElement | null; // --- State Modifiers (to be called by other modules) --- export function setPlayer(newPlayerState: Player) { player = newPlayerState; } export function setCurrentEnemy(newEnemy: Enemy | null) { currentEnemy = newEnemy; } export function setIsInCombat(combatStatus: boolean) { isInCombat = combatStatus; } export function setIsGameOver(gameOverStatus: boolean) { // Though combat game over is now revival isGameOver = gameOverStatus; } export function setAllMaps(newAllMaps: MapArea[]) { allMaps = newAllMaps; } export function setCurrentMapIndex(index: number) { currentMapIndex = index; } export function setExplorationActionsDoneOnMap(actions: number) { explorationActionsDoneOnMap = actions; } export function incrementExplorationActionsDoneOnMap(amount: number) { explorationActionsDoneOnMap += amount; } // --- Central UI Update Function --- export function updateGameDisplay(): void { calculatePlayerStats(player); // Calculate stats first updatePlayerStatsUI(player, { playerLevelDisplay, playerHpDisplay, playerMaxHpDisplay, playerAttackDisplay, playerDefenseDisplay, playerXpDisplay, playerNextLevelXpDisplay, playerMoneyDisplay }); updateEquippedUI(player.equipment, { equippedWeaponDisplay, equippedArmorDisplay }); updateInventoryUI(player.inventory, { inventoryListDisplay }, isInCombat, isGameOver, (itemId, index) => handleUseItemAction(itemId, index)); updateMapUI(allMaps[currentMapIndex], explorationActionsDoneOnMap, { currentMapNameDisplay, mapProgressDisplay }); populateShopUI(allMaps[currentMapIndex]?.availableShopItemIds || [], player.money, { shopItemsContainer }, isInCombat, isGameOver, (itemId) => handleBuyItemAction(itemId)); updateMapSelectUI(allMaps, currentMapIndex, { mapSelectElement }, isInCombat, isGameOver); updateButtonDisabledStates({ exploreButton, restButton, attackButton, runButton, saveGameActionButton, saveSlotInput, loadSlotsList, mapSelectElement }, isInCombat, isGameOver); if (isInCombat && currentEnemy) { updateEnemyUI(currentEnemy, { enemyNameDisplay, enemyHpDisplay, enemyMaxHpDisplay }); } } // --- Core Game Actions (now thin wrappers calling action handlers) --- function explore(): void { handleExploreAction(); } function rest(): void { handleRestAction(); } function attack(): void { handlePlayerAttackLogic(); } function runFromCombat(): void { handleRunLogic(); } function travelMap(): void { handleMapTravelAction(); } function requestSaveGame(): void { handleSaveGameRequestAction(); } // Publicly accessible for UI module to call for messages export function addMessage(message: string, type: 'info' | 'event' | 'damage' | 'heal' | 'combat' | 'victory' | 'boss' = 'info'): void { addMessageToArea(message, type, messageArea, MAX_LOG_MESSAGES); } // --- Initialization --- function initializeGame(): void { // Get DOM elements messageArea = document.getElementById('message-area'); playerLevelDisplay = document.getElementById('player-level'); playerHpDisplay = document.getElementById('player-hp'); playerMaxHpDisplay = document.getElementById('player-max-hp'); playerAttackDisplay = document.getElementById('player-attack'); playerDefenseDisplay = document.getElementById('player-defense'); playerXpDisplay = document.getElementById('player-xp'); playerNextLevelXpDisplay = document.getElementById('player-next-level-xp'); playerMoneyDisplay = document.getElementById('player-money'); exploreButton = document.getElementById('explore-button') as HTMLButtonElement; restButton = document.getElementById('rest-button') as HTMLButtonElement; shopItemsContainer = document.getElementById('shop-items'); inventoryListDisplay = document.getElementById('inventory-list'); equippedWeaponDisplay = document.getElementById('equipped-weapon'); equippedArmorDisplay = document.getElementById('equipped-armor'); mapSelectElement = document.getElementById('map-select') as HTMLSelectElement; combatArea = document.getElementById('combat-area'); enemyNameDisplay = document.getElementById('enemy-name'); enemyHpDisplay = document.getElementById('enemy-hp'); enemyMaxHpDisplay = document.getElementById('enemy-max-hp'); attackButton = document.getElementById('attack-button') as HTMLButtonElement; runButton = document.getElementById('run-button') as HTMLButtonElement; currentMapNameDisplay = document.getElementById('current-map-name'); mapProgressDisplay = document.getElementById('map-progress'); saveSlotInput = document.getElementById('save-slot-input') as HTMLInputElement; saveGameActionButton = document.getElementById('save-game-action-button') as HTMLButtonElement; loadSlotsList = document.getElementById('load-slots-list'); noSavesFoundMessage = document.getElementById('no-saves-found'); // Initialize game state generateAllMaps(); // This now uses setAllMaps setCurrentMapIndex(0); setExplorationActionsDoneOnMap(0); setIsGameOver(false); toggleCombatAreaVisibility(false, combatArea); // Setup event listeners exploreButton?.addEventListener('click', explore); restButton?.addEventListener('click', rest); attackButton?.addEventListener('click', attack); runButton?.addEventListener('click', runFromCombat); mapSelectElement?.addEventListener('change', travelMap); saveGameActionButton?.addEventListener('click', requestSaveGame); // Initial UI setup populateLoadSlotsListUI({ loadSlotsList, noSavesFoundMessage }, isInCombat, isGameOver, handleLoadGameRequestAction, handleDeleteSaveSlotAction, // Use the new centralized delete handler null // Pass null to use default getSavedSlotNames ); updateGameDisplay(); addMessage("ゲームが初期化されました。冒険を始めよう!", "event"); } document.addEventListener('DOMContentLoaded', initializeGame);