import { useEffect } from 'react'; import { useGameStore } from './gameStore'; import { useManaStore } from './manaStore'; import { usePrestigeStore } from './prestigeStore'; import { useCraftingStore } from './craftingStore'; import { getUnifiedEffects } from '../effects'; import { computeDisciplineEffects } from '../effects/discipline-effects'; import { computeMaxMana, computeRegen, computeClickMana, getMeditationBonus, getIncursionStrength, } from '../utils'; import { TICK_MS } from '../constants'; export function useGameLoop() { useEffect(() => { const interval = setInterval(() => useGameStore.getState().tick(), TICK_MS); return () => clearInterval(interval); }, []); } // ─── Shared Selector Hooks for Common Derived State ──────────────────────────── /** * Get unified effects from equipment only (skills removed) */ export function useUnifiedEffects() { const equippedInstances = useCraftingStore((s) => s.equippedInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances); const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades); const disciplineEffects = computeDisciplineEffects(); return { ...getUnifiedEffects({ equippedInstances, equipmentInstances, prestigeUpgrades, }), disciplineEffects, }; } /** * Get computed mana stats (maxMana, baseRegen, clickMana, meditationMultiplier, effectiveRegen) */ export function useManaStats() { const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades); const meditateTicks = useManaStore((s) => s.meditateTicks); const day = useGameStore((s) => s.day); const hour = useGameStore((s) => s.hour); const equippedInstances = useCraftingStore((s) => s.equippedInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances); const disciplineEffects = computeDisciplineEffects(); const upgradeEffects = getUnifiedEffects({ equippedInstances, equipmentInstances, prestigeUpgrades, }); const maxMana = computeMaxMana( { prestigeUpgrades }, upgradeEffects, disciplineEffects, ); const baseRegen = computeRegen( { prestigeUpgrades, attunements: {} }, upgradeEffects, disciplineEffects, ); const clickMana = computeClickMana(disciplineEffects); const meditationMultiplier = getMeditationBonus(meditateTicks, upgradeEffects.meditationEfficiency, disciplineEffects.meditationCapBonus); const incursionStrength = getIncursionStrength(day, hour); const effectiveRegenWithSpecials = baseRegen * (1 - incursionStrength); // Mana Cascade bonus const manaCascadeBonus = upgradeEffects.specials.has('mana_cascade') ? Math.floor(maxMana / 100) * 0.1 : 0; // Mana Waterfall bonus const manaWaterfallBonus = upgradeEffects.specials.has('mana_waterfall') ? Math.floor(maxMana / 100) * 0.25 : 0; const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus + manaWaterfallBonus) * meditationMultiplier; return { maxMana, baseRegen, effectiveRegen, incursionStrength, clickMana, meditationMultiplier, manaCascadeBonus, manaWaterfallBonus, upgradeEffects, }; } /** * Get combat-related derived state */ export function useCombatStats() { const signedPacts = usePrestigeStore((s) => s.signedPacts); const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades); const equippedInstances = useCraftingStore((s) => s.equippedInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances); const upgradeEffects = getUnifiedEffects({ equippedInstances, equipmentInstances, prestigeUpgrades, }); return { signedPacts, equippedInstances, equipmentInstances, upgradeEffects, }; } /** * Get equipment-related derived state */ export function useEquipmentState() { const equippedInstances = useCraftingStore((s) => s.equippedInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances); const elements = useManaStore((s) => s.elements); return { equippedInstances, equipmentInstances, elements, }; }