refactor: resolve structural inconsistencies and dead code
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 55s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 55s
- Fix broken barrel exports in components/game/index.ts - Remove skill system from stores (gameStore, gameActions, gameLoopActions, gameHooks, craftingStore, combat) - Remove skill system from components (page.tsx, LeftPanel, StatsTab, SpellsTab, EnchantmentDesigner, EnchantmentPreparer, GameContext/Provider) - Delete dead code: stats/ directory, attunements/ directory, layout/ Header+TabBar, shared/ StudyProgress+UpgradeDialog duplicates, effects.ts.fix, study-slice.ts, navigation-slice.ts - Delete legacy store/ and store-modules/ directories, redirect remaining callers - Merge root formatting.ts into utils/formatting.ts - Move effects files (dynamic-compute, upgrade-effects, special-effects, upgrade-effects.types) into effects/ directory - Move debug-context.tsx into components/game/debug/ - Create tabs/index.ts barrel for tab components - Fix page.tsx lazy imports to use tabs barrel - Fix all broken import paths across codebase - Remove SKILLS_DEF and skill-evolution references - Trim store.ts to under 400 lines by removing dead skill actions
This commit is contained in:
+80
-116
@@ -1,41 +1,96 @@
|
||||
// ─── Game Store (Refactored) ──────────────────────────────────────────────
|
||||
// Main entry point - imports from modular store components
|
||||
// Target: Under 400 lines
|
||||
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import type { GameState, GameAction, StudyTarget, SpellCost, SkillUpgradeChoice, ActivityLogEntry } from './types';
|
||||
import type { GameState, GameAction, ActivityLogEntry } from './types';
|
||||
|
||||
// Import from modular store components
|
||||
import { makeInitial } from './store-modules/initial-state';
|
||||
import { addActivityLogEntry } from './store-modules/activity-log';
|
||||
import {
|
||||
computeMaxMana, computeRegen, computeClickMana, calcDamage, calcInsight,
|
||||
getMeditationBonus, getIncursionStrength, canAffordSpellCost
|
||||
} from './store-modules/computed-stats';
|
||||
import { generateFloorState, getPuzzleProgressSpeed } from './store-modules/room-utils';
|
||||
import { addActivityLogEntry } from './utils/activity-log';
|
||||
import {
|
||||
computeMaxMana, computeRegen, computeClickMana,
|
||||
getMeditationBonus,
|
||||
} from './utils/mana-utils';
|
||||
import {
|
||||
calcDamage, calcInsight, getIncursionStrength, canAffordSpellCost, deductSpellCost,
|
||||
} from './utils/combat-utils';
|
||||
import { generateFloorState } from './utils/room-utils';
|
||||
|
||||
// Re-export formatting functions for backward compatibility
|
||||
export { fmt, fmtDec } from './utils/formatting';
|
||||
export { getFloorMaxHP, getFloorElement } from './utils/floor-utils';
|
||||
|
||||
// Re-export computed stats functions for backward compatibility and tests
|
||||
export { computeMaxMana, computeElementMax, computeRegen, computeClickMana, calcDamage, calcInsight, getMeditationBonus, getIncursionStrength, canAffordSpellCost, deductSpellCost } from './store-modules/computed-stats';
|
||||
export {
|
||||
computeMaxMana, computeRegen, computeClickMana,
|
||||
getMeditationBonus,
|
||||
} from './utils/mana-utils';
|
||||
export {
|
||||
calcDamage, calcInsight, getIncursionStrength, canAffordSpellCost, deductSpellCost,
|
||||
} from './utils/combat-utils';
|
||||
|
||||
// ─── Initial State ───────────────────────────────────────────────────────
|
||||
|
||||
interface MakeInitialOptions {
|
||||
loopCount?: number;
|
||||
totalInsight?: number;
|
||||
insight?: number;
|
||||
prestigeUpgrades?: Record<string, number>;
|
||||
}
|
||||
|
||||
export function makeInitial(opts?: MakeInitialOptions): GameState {
|
||||
return {
|
||||
day: 1,
|
||||
hour: 0,
|
||||
rawMana: 100,
|
||||
maxMana: 100,
|
||||
elements: {},
|
||||
skills: {},
|
||||
skillUpgrades: {},
|
||||
skillTiers: {},
|
||||
spells: {},
|
||||
currentAction: 'meditate' as GameAction,
|
||||
currentStudyTarget: null,
|
||||
parallelStudyTarget: null,
|
||||
activeSpell: null,
|
||||
currentFloor: 100,
|
||||
floorHP: 1000,
|
||||
floorMaxHP: 1000,
|
||||
currentRoom: generateFloorState(100),
|
||||
maxFloorReached: 100,
|
||||
paused: false,
|
||||
gameOver: false,
|
||||
victory: false,
|
||||
loopCount: opts?.loopCount ?? 0,
|
||||
totalInsight: opts?.totalInsight ?? 0,
|
||||
insight: opts?.insight ?? 0,
|
||||
loopInsight: 0,
|
||||
prestigeUpgrades: opts?.prestigeUpgrades ?? {},
|
||||
signedPacts: [],
|
||||
attunements: {},
|
||||
golemancy: { enabledGolems: [] },
|
||||
memories: [],
|
||||
memorySlots: 0,
|
||||
log: [],
|
||||
activityLog: [],
|
||||
meditateTicks: 0,
|
||||
totalManaGathered: 0,
|
||||
equippedInstances: {},
|
||||
equipmentInstances: {},
|
||||
lootInventory: {},
|
||||
blueprints: {},
|
||||
spireMode: false,
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Game Store Interface ─────────────────────────────────────────────────
|
||||
|
||||
export interface GameStore extends GameState {
|
||||
// Actions
|
||||
tick: () => void;
|
||||
gatherMana: () => void;
|
||||
setAction: (action: GameAction) => void;
|
||||
addActivityLog: (eventType: string, message: string, details?: ActivityLogEntry['details']) => void;
|
||||
setSpell: (spellId: string) => void;
|
||||
startStudyingSkill: (skillId: string) => void;
|
||||
startStudyingSpell: (spellId: string) => void;
|
||||
startParallelStudySkill: (skillId: string) => void;
|
||||
cancelStudy: () => void;
|
||||
cancelParallelStudy: () => void;
|
||||
convertMana: (element: string, amount: number) => void;
|
||||
unlockElement: (element: string) => void;
|
||||
doPrestige: (id: string, selectedManaType?: string) => void;
|
||||
@@ -43,36 +98,21 @@ export interface GameStore extends GameState {
|
||||
togglePause: () => void;
|
||||
resetGame: () => void;
|
||||
addLog: (message: string) => void;
|
||||
selectSkillUpgrade: (skillId: string, upgradeId: string) => void;
|
||||
deselectSkillUpgrade: (skillId: string, upgradeId: string) => void;
|
||||
commitSkillUpgrades: (skillId: string, upgradeIds: string[], milestone?: 5 | 10) => void;
|
||||
tierUpSkill: (skillId: string) => void;
|
||||
|
||||
// Attunement XP and leveling
|
||||
addAttunementXP: (attunementId: string, amount: number) => void;
|
||||
|
||||
// Golemancy actions
|
||||
toggleGolem: (golemId: string) => void;
|
||||
setEnabledGolems: (golemIds: string[]) => void;
|
||||
|
||||
// Debug functions
|
||||
debugUnlockAttunement: (attunementId: string) => void;
|
||||
debugAddElementalMana: (element: string, amount: number) => void;
|
||||
debugSetTime: (day: number, hour: number) => void;
|
||||
debugAddAttunementXP: (attunementId: string, amount: number) => void;
|
||||
debugSetFloor: (floor: number) => void;
|
||||
resetFloorHP: () => void;
|
||||
|
||||
// Computed getters
|
||||
getMaxMana: () => number;
|
||||
getRegen: () => number;
|
||||
getClickMana: () => number;
|
||||
getDamage: (spellId: string) => number;
|
||||
getMeditationMultiplier: () => number;
|
||||
canCastSpell: (spellId: string) => boolean;
|
||||
getSkillUpgradeChoices: (skillId: string, milestone: 5 | 10) => { available: SkillUpgradeChoice[]; selected: string[] };
|
||||
|
||||
// Spire Mode actions
|
||||
enterSpireMode: () => void;
|
||||
climbDownFloor: () => void;
|
||||
exitSpireMode: () => void;
|
||||
@@ -85,18 +125,16 @@ export const useGameStore = create<GameStore>()(
|
||||
(set, get) => ({
|
||||
...makeInitial(),
|
||||
|
||||
// Computed getters
|
||||
getMaxMana: () => computeMaxMana(get()),
|
||||
getRegen: () => computeRegen(get()),
|
||||
getClickMana: () => computeClickMana(get()),
|
||||
getDamage: (spellId: string) => calcDamage(get(), spellId),
|
||||
getMeditationMultiplier: () => getMeditationBonus(get().meditateTicks, get().skills),
|
||||
|
||||
getMeditationMultiplier: () => getMeditationBonus(get().meditateTicks, {}),
|
||||
|
||||
canCastSpell: (spellId: string) => {
|
||||
const state = get();
|
||||
const spell = state.spells?.[spellId];
|
||||
if (!spell) return false;
|
||||
// Would check spell cost here
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -112,23 +150,18 @@ export const useGameStore = create<GameStore>()(
|
||||
}));
|
||||
},
|
||||
|
||||
// ─── Core Tick Logic ───────────────────────────────────────────
|
||||
tick: () => {
|
||||
const state = get();
|
||||
if (state.gameOver || state.paused) return;
|
||||
|
||||
// Import and use tick logic from module
|
||||
// For now, simplified version here
|
||||
const maxMana = computeMaxMana(state);
|
||||
const baseRegen = computeRegen(state);
|
||||
|
||||
// Time progression
|
||||
let hour = state.hour + 1; // Simplified: HOURS_PER_TICK
|
||||
let hour = state.hour + 1;
|
||||
let day = state.day;
|
||||
if (hour >= 24) { hour -= 24; day += 1; }
|
||||
|
||||
// Check for loop end
|
||||
if (day > 100) { // MAX_DAY
|
||||
if (day > 100) {
|
||||
const insightGained = calcInsight(state);
|
||||
set({
|
||||
day, hour, gameOver: true, victory: false, loopInsight: insightGained,
|
||||
@@ -137,7 +170,6 @@ export const useGameStore = create<GameStore>()(
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate regen
|
||||
let rawMana = state.rawMana + baseRegen;
|
||||
rawMana = Math.min(rawMana, maxMana);
|
||||
|
||||
@@ -147,7 +179,6 @@ export const useGameStore = create<GameStore>()(
|
||||
});
|
||||
},
|
||||
|
||||
// ─── Actions ────────────────────────────────────────────────
|
||||
gatherMana: () => {
|
||||
const state = get();
|
||||
const clickMana = computeClickMana(state);
|
||||
@@ -166,34 +197,10 @@ export const useGameStore = create<GameStore>()(
|
||||
set({ activeSpell: spellId });
|
||||
},
|
||||
|
||||
startStudyingSkill: (skillId: string) => {
|
||||
set({
|
||||
currentStudyTarget: { type: 'skill', id: skillId, progress: 0, required: 60 },
|
||||
currentAction: 'study',
|
||||
});
|
||||
},
|
||||
|
||||
startStudyingSpell: (spellId: string) => {
|
||||
set({
|
||||
currentStudyTarget: { type: 'spell', id: spellId, progress: 0, required: 60 },
|
||||
currentAction: 'study',
|
||||
});
|
||||
},
|
||||
|
||||
startParallelStudySkill: (skillId: string) => {
|
||||
set({
|
||||
parallelStudyTarget: { type: 'skill', id: skillId, progress: 0, required: 120 },
|
||||
});
|
||||
},
|
||||
|
||||
cancelStudy: () => {
|
||||
set({ currentStudyTarget: null, currentAction: 'meditate' });
|
||||
},
|
||||
|
||||
cancelParallelStudy: () => {
|
||||
set({ parallelStudyTarget: null });
|
||||
},
|
||||
|
||||
convertMana: (element: string, amount: number) => {
|
||||
set((s) => {
|
||||
const elem = s.elements?.[element];
|
||||
@@ -216,7 +223,6 @@ export const useGameStore = create<GameStore>()(
|
||||
},
|
||||
|
||||
doPrestige: (id: string, selectedManaType?: string) => {
|
||||
// Simplified prestige logic
|
||||
set((s) => ({
|
||||
prestigeUpgrades: { ...s.prestigeUpgrades, [id]: (s.prestigeUpgrades[id] || 0) + 1 },
|
||||
}));
|
||||
@@ -226,8 +232,8 @@ export const useGameStore = create<GameStore>()(
|
||||
const state = get();
|
||||
const insightGained = state.loopInsight || 0;
|
||||
set({
|
||||
...makeInitial({
|
||||
loopCount: state.loopCount + 1,
|
||||
...makeInitial({
|
||||
loopCount: state.loopCount + 1,
|
||||
totalInsight: (state.totalInsight || 0) + insightGained,
|
||||
insight: (state.insight || 0) + insightGained,
|
||||
prestigeUpgrades: state.prestigeUpgrades,
|
||||
@@ -243,39 +249,6 @@ export const useGameStore = create<GameStore>()(
|
||||
set(makeInitial());
|
||||
},
|
||||
|
||||
selectSkillUpgrade: (skillId: string, upgradeId: string) => {
|
||||
set((s) => {
|
||||
const currentUpgrades = s.skillUpgrades?.[skillId] || { selected: [], available: [] };
|
||||
return {
|
||||
skillUpgrades: { ...s.skillUpgrades, [skillId]: { ...currentUpgrades, selected: [...currentUpgrades.selected, upgradeId] } },
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
deselectSkillUpgrade: (skillId: string, upgradeId: string) => {
|
||||
set((s) => {
|
||||
const currentUpgrades = s.skillUpgrades?.[skillId] || { selected: [], available: [] };
|
||||
return {
|
||||
skillUpgrades: { ...s.skillUpgrades, [skillId]: { ...currentUpgrades, selected: currentUpgrades.selected.filter(id => id !== upgradeId) } },
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
commitSkillUpgrades: (skillId: string, upgradeIds: string[], milestone?: 5 | 10) => {
|
||||
set((s) => {
|
||||
const currentUpgrades = s.skillUpgrades?.[skillId] || { selected: [], available: [] };
|
||||
return {
|
||||
skillUpgrades: { ...s.skillUpgrades, [skillId]: { ...currentUpgrades, committed: upgradeIds, milestone } },
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
tierUpSkill: (skillId: string) => {
|
||||
set((s) => ({
|
||||
skillTiers: { ...s.skillTiers, [skillId]: (s.skillTiers?.[skillId] || 1) + 1 },
|
||||
}));
|
||||
},
|
||||
|
||||
addAttunementXP: (attunementId: string, amount: number) => {
|
||||
set((s) => {
|
||||
const attState = s.attunements?.[attunementId];
|
||||
@@ -302,7 +275,6 @@ export const useGameStore = create<GameStore>()(
|
||||
}));
|
||||
},
|
||||
|
||||
// Debug functions
|
||||
debugUnlockAttunement: (attunementId: string) => {
|
||||
set((s) => ({
|
||||
attunements: { ...s.attunements, [attunementId]: { id: attunementId, active: true, level: 1, experience: 0 } },
|
||||
@@ -331,7 +303,7 @@ export const useGameStore = create<GameStore>()(
|
||||
set((s) => ({
|
||||
currentFloor: floor,
|
||||
currentRoom: generateFloorState(floor),
|
||||
floorMaxHP: 100 + floor * 50, // Simplified getFloorMaxHP
|
||||
floorMaxHP: 100 + floor * 50,
|
||||
floorHP: 100 + floor * 50,
|
||||
}));
|
||||
},
|
||||
@@ -343,14 +315,6 @@ export const useGameStore = create<GameStore>()(
|
||||
}));
|
||||
},
|
||||
|
||||
getSkillUpgradeChoices: (skillId: string, milestone: 5 | 10) => {
|
||||
const state = get();
|
||||
const skillDef = state.spells?.[skillId];
|
||||
// Simplified - would return actual upgrade choices
|
||||
return { available: [], selected: [] };
|
||||
},
|
||||
|
||||
// Spire Mode actions
|
||||
enterSpireMode: () => {
|
||||
set({ spireMode: true });
|
||||
},
|
||||
@@ -362,7 +326,7 @@ export const useGameStore = create<GameStore>()(
|
||||
return {
|
||||
currentFloor: newFloor,
|
||||
currentRoom: generateFloorState(newFloor),
|
||||
floorMaxHP: 100 + newFloor * 50, // Simplified
|
||||
floorMaxHP: 100 + newFloor * 50,
|
||||
floorHP: 100 + newFloor * 50,
|
||||
};
|
||||
});
|
||||
@@ -384,7 +348,7 @@ export function useGameLoop() {
|
||||
const tick = useGameStore((s) => s.tick);
|
||||
return {
|
||||
start: () => {
|
||||
const interval = setInterval(tick, 1000); // TICK_MS
|
||||
const interval = setInterval(tick, 1000);
|
||||
return () => clearInterval(interval);
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user