// ─── Golem Combat Pipeline (Component-Based) ───────────────────────────────── // Pipeline integration for the component-based golem combat system. // Extracts golem combat setup from gameStore.ts tick() to keep the coordinator // under the 400-line file limit. import { useCombatStore } from '../combatStore'; import { useManaStore } from '../manaStore'; import { summonGolemsOnRoomEntry, processGolemMaintenance, processGolemManaRegen, processGolemAttacks, countdownGolemRoomDuration, } from '../golem-combat-actions'; import { useAttunementStore } from '../attunementStore'; import type { RuntimeActiveGolem } from '../../types'; export interface GolemCombatContext { addLog: (msg: string) => void; ctx: { combat: { currentFloor: number; currentRoom: { roomType: string; enemies: Array<{ name: string; hp: number; maxHP: number; armor: number }> }; }; prestige: { signedPacts: number[] }; }; rawMana: number; elements: Record; maxMana: number; } export interface GolemCombatPipelineResult { rawMana: number; elements: Record; activeGolems: RuntimeActiveGolem[]; logMessages: string[]; } /** * Build the golem combat pipeline for the current tick. */ export function buildGolemCombatPipeline(_addLog: (msg: string) => void): { activeGolems: RuntimeActiveGolem[]; golemDesigns: Record; golemApplyDamageToRoom: (dmg: number) => { floorHP: number; floorMaxHP: number; roomCleared: boolean }; } { const combatState = useCombatStore.getState(); const golemancy = combatState.golemancy; // New component-based active golems const activeGolems = golemancy?.activeGolems ?? []; // Reconstruct golem designs from store const golemDesigns = golemancy?.golemDesigns ?? {}; const golemApplyDamageToRoom = (dmg: number) => { const cs = useCombatStore.getState(); const room = cs.currentRoom; if (!room || room.enemies.length === 0 || dmg <= 0) { return { floorHP: cs.floorHP, floorMaxHP: cs.floorMaxHP, roomCleared: false }; } // Focus-fire targeting: target lowest HP enemy let target = room.enemies[0]; for (const e of room.enemies) { if (e.hp > 0 && e.hp < (target?.hp ?? Infinity)) { target = e; } } if (!target || target.hp <= 0) { return { floorHP: cs.floorHP, floorMaxHP: cs.floorMaxHP, roomCleared: false }; } const updatedEnemies = room.enemies.map((enemy) => { if (enemy.id === target!.id && enemy.hp > 0) { return { ...enemy, hp: Math.max(0, enemy.hp - dmg) }; } return enemy; }); const newFloorHP = updatedEnemies.reduce((sum, e) => sum + e.hp, 0); const allDead = updatedEnemies.every((e) => e.hp <= 0); useCombatStore.setState({ currentRoom: { ...room, enemies: updatedEnemies }, floorHP: newFloorHP, }); return { floorHP: newFloorHP, floorMaxHP: cs.floorMaxHP, roomCleared: allDead }; }; return { activeGolems, golemDesigns, golemApplyDamageToRoom }; } /** * Process golem summoning on room entry. */ export function processGolemRoomEntry( loadout: { enabled: boolean; designId: string; design: { name: string } }[], currentFloor: number, ): { rawMana: number; elements: Record; activeGolems: RuntimeActiveGolem[]; logMessages: string[]; } { const cs = useCombatStore.getState(); const attStore = useAttunementStore.getState(); const fabLevel = attStore.attunements?.fabricator?.level ?? 0; const discBonus = 0; // TODO: compute from discipline return summonGolemsOnRoomEntry( loadout as any, useManaStore.getState().rawMana, useManaStore.getState().elements as any, currentFloor, cs.golemancy.activeGolems as any[], discBonus, ); }