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:
140
src/lib/game/store/prestigeSlice.ts
Executable file
140
src/lib/game/store/prestigeSlice.ts
Executable file
@@ -0,0 +1,140 @@
|
||||
// ─── Prestige Slice ───────────────────────────────────────────────────────────
|
||||
// Manages insight, prestige upgrades, and loop resources
|
||||
|
||||
import type { StateCreator } from 'zustand';
|
||||
import type { GameState } from '../types';
|
||||
import { PRESTIGE_DEF } from '../constants';
|
||||
|
||||
export interface PrestigeSlice {
|
||||
// State
|
||||
insight: number;
|
||||
totalInsight: number;
|
||||
prestigeUpgrades: Record<string, number>;
|
||||
loopInsight: number;
|
||||
memorySlots: number;
|
||||
memories: string[];
|
||||
|
||||
// Actions
|
||||
doPrestige: (id: string) => void;
|
||||
startNewLoop: () => void;
|
||||
}
|
||||
|
||||
export const createPrestigeSlice = (
|
||||
set: StateCreator<GameState>['set'],
|
||||
get: () => GameState
|
||||
): PrestigeSlice => ({
|
||||
insight: 0,
|
||||
totalInsight: 0,
|
||||
prestigeUpgrades: {},
|
||||
loopInsight: 0,
|
||||
memorySlots: 3,
|
||||
memories: [],
|
||||
|
||||
doPrestige: (id: string) => {
|
||||
const state = get();
|
||||
const pd = PRESTIGE_DEF[id];
|
||||
if (!pd) return;
|
||||
|
||||
const lvl = state.prestigeUpgrades[id] || 0;
|
||||
if (lvl >= pd.max || state.insight < pd.cost) return;
|
||||
|
||||
const newPU = { ...state.prestigeUpgrades, [id]: lvl + 1 };
|
||||
|
||||
set({
|
||||
insight: state.insight - pd.cost,
|
||||
prestigeUpgrades: newPU,
|
||||
memorySlots: id === 'deepMemory' ? state.memorySlots + 1 : state.memorySlots,
|
||||
maxPacts: id === 'pactCapacity' ? state.maxPacts + 1 : state.maxPacts,
|
||||
pactInterferenceMitigation: id === 'pactInterference' ? (state.pactInterferenceMitigation || 0) + 1 : state.pactInterferenceMitigation,
|
||||
log: [`⭐ ${pd.name} upgraded to Lv.${lvl + 1}!`, ...state.log.slice(0, 49)],
|
||||
});
|
||||
},
|
||||
|
||||
startNewLoop: () => {
|
||||
const state = get();
|
||||
const insightGained = state.loopInsight || calcInsight(state);
|
||||
const total = state.insight + insightGained;
|
||||
|
||||
// Keep some spells through temporal memory
|
||||
const spellsToKeep: string[] = [];
|
||||
if (state.skills.temporalMemory) {
|
||||
const learnedSpells = Object.entries(state.spells)
|
||||
.filter(([, s]) => s.learned)
|
||||
.map(([id]) => id);
|
||||
spellsToKeep.push(...learnedSpells.slice(0, state.skills.temporalMemory));
|
||||
}
|
||||
|
||||
// Reset to initial state with insight carried over
|
||||
const pu = state.prestigeUpgrades;
|
||||
const startFloor = 1 + (pu.spireKey || 0) * 2;
|
||||
const startRawMana = 10 + (pu.manaWell || 0) * 500 + (pu.quickStart || 0) * 100;
|
||||
|
||||
// Reset elements
|
||||
const elements: Record<string, { current: number; max: number; unlocked: boolean }> = {};
|
||||
Object.keys(ELEMENTS).forEach((k) => {
|
||||
elements[k] = {
|
||||
current: 0,
|
||||
max: 10 + (pu.elementalAttune || 0) * 25,
|
||||
unlocked: false,
|
||||
};
|
||||
});
|
||||
|
||||
// Reset spells
|
||||
const spells: Record<string, { learned: boolean; level: number; studyProgress: number }> = {
|
||||
manaBolt: { learned: true, level: 1, studyProgress: 0 },
|
||||
};
|
||||
spellsToKeep.forEach(spellId => {
|
||||
spells[spellId] = { learned: true, level: 1, studyProgress: 0 };
|
||||
});
|
||||
|
||||
// Add random starting spells from spell memory upgrade
|
||||
if (pu.spellMemory) {
|
||||
const availableSpells = Object.keys(SPELLS_DEF).filter(s => s !== 'manaBolt' && !spellsToKeep.includes(s));
|
||||
const shuffled = availableSpells.sort(() => Math.random() - 0.5);
|
||||
for (let i = 0; i < Math.min(pu.spellMemory, shuffled.length); i++) {
|
||||
spells[shuffled[i]] = { learned: true, level: 1, studyProgress: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
set({
|
||||
day: 1,
|
||||
hour: 0,
|
||||
gameOver: false,
|
||||
victory: false,
|
||||
loopCount: state.loopCount + 1,
|
||||
rawMana: startRawMana,
|
||||
totalManaGathered: 0,
|
||||
meditateTicks: 0,
|
||||
elements,
|
||||
currentFloor: startFloor,
|
||||
floorHP: getFloorMaxHP(startFloor),
|
||||
floorMaxHP: getFloorMaxHP(startFloor),
|
||||
maxFloorReached: startFloor,
|
||||
signedPacts: [],
|
||||
pendingPactOffer: null,
|
||||
pactSigningProgress: null,
|
||||
signedPactDetails: {},
|
||||
activeSpell: 'manaBolt',
|
||||
currentAction: 'meditate',
|
||||
castProgress: 0,
|
||||
spells,
|
||||
skills: {},
|
||||
skillProgress: {},
|
||||
skillUpgrades: {},
|
||||
skillTiers: {},
|
||||
currentStudyTarget: null,
|
||||
parallelStudyTarget: null,
|
||||
insight: total,
|
||||
totalInsight: (state.totalInsight || 0) + insightGained,
|
||||
loopInsight: 0,
|
||||
maxPacts: 1 + (pu.pactCapacity || 0),
|
||||
pactInterferenceMitigation: pu.pactInterference || 0,
|
||||
memorySlots: 3 + (pu.deepMemory || 0),
|
||||
log: ['✨ A new loop begins. Your insight grows...', '✨ The loop begins. You start with Mana Bolt.'],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// Need to import these
|
||||
import { ELEMENTS, SPELLS_DEF } from '../constants';
|
||||
import { getFloorMaxHP, calcInsight } from './computed';
|
||||
Reference in New Issue
Block a user