Fix mana conversion visibility and UI improvements
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 3m9s
All checks were successful
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 3m9s
- Increase attunement mana conversion rates (0.2 -> 2 for Enchanter) - Hide mana types with current < 1 in ManaDisplay and LabTab - Only show owned equipment types when designing enchantments
This commit is contained in:
266
src/lib/game/stores/prestigeStore.ts
Executable file
266
src/lib/game/stores/prestigeStore.ts
Executable file
@@ -0,0 +1,266 @@
|
||||
// ─── 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<string, number>;
|
||||
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<string, number>,
|
||||
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<string, number>,
|
||||
memorySlots: 3,
|
||||
pactSlots: 1,
|
||||
memories: [] as Memory[],
|
||||
defeatedGuardians: [] as number[],
|
||||
signedPacts: [] as number[],
|
||||
pactRitualFloor: null as number | null,
|
||||
pactRitualProgress: 0,
|
||||
};
|
||||
|
||||
export const usePrestigeStore = create<PrestigeState>()(
|
||||
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<string, number>,
|
||||
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,
|
||||
}),
|
||||
}
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user