// ─── Prestige Store ─────────────────────────────────────────────────────────── // Handles insight, prestige upgrades, memories, loops, pacts import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import type { Memory } from '../types'; import { GUARDIANS, PRESTIGE_DEF } from '../constants'; export interface PrestigeState { // Loop counter loopCount: number; // Insight insight: number; totalInsight: number; loopInsight: number; // Insight earned at end of current loop // Prestige upgrades prestigeUpgrades: Record; memorySlots: number; pactSlots: number; // Memories (skills preserved across loops) memories: Memory[]; // Guardian pacts defeatedGuardians: number[]; signedPacts: number[]; pactRitualFloor: number | null; pactRitualProgress: number; // Actions doPrestige: (id: string) => void; addMemory: (memory: Memory) => void; removeMemory: (skillId: string) => void; clearMemories: () => void; startPactRitual: (floor: number, rawMana: number) => boolean; cancelPactRitual: () => void; completePactRitual: (addLog: (msg: string) => void) => void; updatePactRitualProgress: (hours: number) => void; removePact: (floor: number) => void; defeatGuardian: (floor: number) => void; // Methods called by gameStore addSignedPact: (floor: number) => void; removeDefeatedGuardian: (floor: number) => void; setPactRitualFloor: (floor: number | null) => void; addDefeatedGuardian: (floor: number) => void; incrementLoopCount: () => void; resetPrestigeForNewLoop: ( totalInsight: number, prestigeUpgrades: Record, memories: Memory[], memorySlots: number ) => void; // Loop management startNewLoop: (insightGained: number) => void; setLoopInsight: (insight: number) => void; // Reset resetPrestige: () => void; } const initialState = { loopCount: 0, insight: 0, totalInsight: 0, loopInsight: 0, prestigeUpgrades: {} as Record, memorySlots: 3, pactSlots: 1, memories: [] as Memory[], defeatedGuardians: [] as number[], signedPacts: [] as number[], pactRitualFloor: null as number | null, pactRitualProgress: 0, }; export const usePrestigeStore = create()( persist( (set, get) => ({ ...initialState, doPrestige: (id: string) => { const state = get(); const pd = PRESTIGE_DEF[id]; if (!pd) return false; const lvl = state.prestigeUpgrades[id] || 0; if (lvl >= pd.max || state.insight < pd.cost) return false; const newPU = { ...state.prestigeUpgrades, [id]: lvl + 1 }; set({ insight: state.insight - pd.cost, prestigeUpgrades: newPU, memorySlots: id === 'deepMemory' ? state.memorySlots + 1 : state.memorySlots, pactSlots: id === 'pactBinding' ? state.pactSlots + 1 : state.pactSlots, }); return true; }, addMemory: (memory: Memory) => { const state = get(); if (state.memories.length >= state.memorySlots) return; if (state.memories.some(m => m.skillId === memory.skillId)) return; set({ memories: [...state.memories, memory] }); }, removeMemory: (skillId: string) => { set((state) => ({ memories: state.memories.filter(m => m.skillId !== skillId), })); }, clearMemories: () => { set({ memories: [] }); }, startPactRitual: (floor: number, rawMana: number) => { const state = get(); const guardian = GUARDIANS[floor]; if (!guardian) return false; if (!state.defeatedGuardians.includes(floor)) return false; if (state.signedPacts.includes(floor)) return false; if (state.signedPacts.length >= state.pactSlots) return false; if (rawMana < guardian.pactCost) return false; if (state.pactRitualFloor !== null) return false; set({ pactRitualFloor: floor, pactRitualProgress: 0, }); return true; }, cancelPactRitual: () => { set({ pactRitualFloor: null, pactRitualProgress: 0, }); }, completePactRitual: (addLog: (msg: string) => void) => { const state = get(); if (state.pactRitualFloor === null) return; const guardian = GUARDIANS[state.pactRitualFloor]; if (!guardian) return; set({ signedPacts: [...state.signedPacts, state.pactRitualFloor], defeatedGuardians: state.defeatedGuardians.filter(f => f !== state.pactRitualFloor), pactRitualFloor: null, pactRitualProgress: 0, }); addLog(`📜 Pact signed with ${guardian.name}! You have gained their boons.`); }, updatePactRitualProgress: (hours: number) => { set((state) => ({ pactRitualProgress: state.pactRitualProgress + hours, })); }, removePact: (floor: number) => { set((state) => ({ signedPacts: state.signedPacts.filter(f => f !== floor), })); }, defeatGuardian: (floor: number) => { const state = get(); if (state.defeatedGuardians.includes(floor) || state.signedPacts.includes(floor)) return; set({ defeatedGuardians: [...state.defeatedGuardians, floor], }); }, addSignedPact: (floor: number) => { const state = get(); if (state.signedPacts.includes(floor)) return; set({ signedPacts: [...state.signedPacts, floor] }); }, removeDefeatedGuardian: (floor: number) => { set((state) => ({ defeatedGuardians: state.defeatedGuardians.filter(f => f !== floor), })); }, setPactRitualFloor: (floor: number | null) => { set({ pactRitualFloor: floor, pactRitualProgress: 0 }); }, addDefeatedGuardian: (floor: number) => { const state = get(); if (state.defeatedGuardians.includes(floor) || state.signedPacts.includes(floor)) return; set({ defeatedGuardians: [...state.defeatedGuardians, floor] }); }, incrementLoopCount: () => { set((state) => ({ loopCount: state.loopCount + 1 })); }, resetPrestigeForNewLoop: ( totalInsight: number, prestigeUpgrades: Record, memories: Memory[], memorySlots: number ) => { set({ insight: totalInsight, prestigeUpgrades, memories, memorySlots, // Reset loop-specific state defeatedGuardians: [], signedPacts: [], pactRitualFloor: null, pactRitualProgress: 0, loopInsight: 0, }); }, startNewLoop: (insightGained: number) => { const state = get(); set({ loopCount: state.loopCount + 1, insight: state.insight + insightGained, totalInsight: state.totalInsight + insightGained, loopInsight: 0, // Reset loop-specific state defeatedGuardians: [], signedPacts: [], pactRitualFloor: null, pactRitualProgress: 0, }); }, setLoopInsight: (insight: number) => { set({ loopInsight: insight }); }, resetPrestige: () => { set(initialState); }, }), { name: 'mana-loop-prestige', partialize: (state) => ({ loopCount: state.loopCount, insight: state.insight, totalInsight: state.totalInsight, prestigeUpgrades: state.prestigeUpgrades, memorySlots: state.memorySlots, pactSlots: state.pactSlots, memories: state.memories, }), } ) );