import { CombatState, EffectTable, EnemyEntity, PlayerEntity, } from "../combat/types"; import { generateDeckFromInventory } from "../deck"; import { GridInventory } from "../grid-inventory"; import { GameItemMeta } from "../grid-inventory/types"; import { EffectData, EncounterData, EnemyData, IntentData } from "../types"; import { CombatEncounterState, RunState } from "./types"; export function buildCombatState( runState: RunState, inventory: GridInventory, encounter: CombatEncounterState, ): CombatState { const deck = generateDeckFromInventory(inventory); const player = createPlayerEntity(runState, deck); const enemies = createEnemyEntities(encounter.data); return { enemies, player, phase: "playerTurn", turnNumber: 1, result: null, loot: [], }; } export function buildCombatEncounterState( data: EncounterData<"minion" | "elite">, ): CombatEncounterState { return { data, blocked: false }; } function createEnemyEntities(encounter: EncounterData): EnemyEntity[] { const enemies: EnemyEntity[] = []; let instanceCounter = 0; for (const [enemyData, hp, encounterBuffs] of encounter.enemies) { const instanceId = `${enemyData.id}-${instanceCounter++}`; const intents = buildIntentMap(enemyData); const initialIntent = findInitialIntent(enemyData); const effects = buildEffectTable(encounterBuffs); const entity: EnemyEntity = { id: instanceId, enemy: enemyData, hp, maxHp: hp, isAlive: true, effects, intents, currentIntent: initialIntent, }; enemies.push(entity); } return enemies; } /** * Builds a map of intent ID -> IntentData for an enemy. */ function buildIntentMap(enemy: EnemyData): Record { const intents: Record = {}; for (const intent of enemy.intents) { intents[intent.id] = intent; } return intents; } /** * Finds the initial intent ID for an enemy. */ function findInitialIntent(enemy: EnemyData): IntentData { for (const intent of enemy.intents) { if (intent.initialIntent) { return intent; } } if (enemy.intents.length === 0) { throw new Error(`Enemy "${enemy.id}" has no intents`); } return enemy.intents[0]; } function buildEffectTable(buffs: readonly [EffectData, number][]): EffectTable { const table: EffectTable = {}; for (const [effect, stacks] of buffs) { table[effect.id] = { data: effect, stacks }; } return table; } function createPlayerEntity( runState: RunState, deck: ReturnType, ): PlayerEntity { return { id: "player", hp: runState.currentHp, maxHp: runState.maxHp, isAlive: runState.currentHp > 0, energy: 3, maxEnergy: 3, deck, itemEffects: {}, effects: {}, }; }