fix: complete store migration — fix all tab crashes and ghost field reads
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m22s

This commit is contained in:
Refactoring Agent
2026-05-05 12:45:07 +02:00
parent dc1aad3700
commit 221d3e4b41
20 changed files with 399 additions and 754 deletions
+47 -45
View File
@@ -10,40 +10,52 @@ import {
RotateCcw, AlertTriangle, Zap, Clock, Settings, Eye,
} from 'lucide-react';
import { useDebug } from '@/lib/game/debug-context';
import { useGameStore } from '@/lib/game/store';
import { useGameStore, useManaStore } from '@/lib/game/stores';
import { computeMaxMana } from '@/lib/game/stores';
export function GameStateDebug() {
const [confirmReset, setConfirmReset] = useState(false);
const { showComponentNames, toggleComponentNames } = useDebug();
// Get state from store
const store = useGameStore((s) => s);
// Get state from modular stores
const rawMana = useManaStore((s) => s.rawMana);
const elements = useManaStore((s) => s.elements);
const unlockElement = useManaStore((s) => s.unlockElement);
const gatherMana = useGameStore((s) => s.gatherMana);
const day = useGameStore((s) => s.day);
const hour = useGameStore((s) => s.hour);
const paused = useGameStore((s) => s.paused);
const togglePause = useGameStore((s) => s.togglePause);
// Get actions from stores
const resetGame = useGameStore((s) => s.resetGame);
const setTime = useGameStore((s) => s.debugSetTime);
const setFloor = useGameStore((s) => s.debugSetFloor);
const resetHP = useGameStore((s) => s.resetFloorHP);
const handleReset = () => {
if (confirmReset) {
useGameStore.getState().resetGame();
resetGame();
setConfirmReset(false);
} else {
setConfirmReset(true);
setTimeout(() => setConfirmReset(false), 3000);
}
};
const handleAddMana = (amount: number) => {
// Use gatherMana multiple times to add mana
const state = useGameStore.getState();
for (let i = 0; i < amount; i++) {
state.gatherMana();
gatherMana();
}
};
const handleSetTime = (day: number, hour: number) => {
const state = useGameStore.getState();
if (state.debugSetTime) {
state.debugSetTime(day, hour);
}
const getMaxMana = () => {
return computeMaxMana(
{ skills: {}, prestigeUpgrades: {}, skillUpgrades: {}, skillTiers: {} },
{ maxManaBonus: 0, maxManaMultiplier: 1 }
);
};
return (
<div className="space-y-4">
{/* Warning Banner */}
@@ -126,7 +138,7 @@ export function GameStateDebug() {
</CardHeader>
<CardContent className="space-y-3">
<div className="text-xs text-gray-400 mb-2">
Current: {store.rawMana} / {store.getMaxMana?.() || '?'}
Current: {rawMana} / {getMaxMana() || '?'}
</div>
<div className="flex gap-2 flex-wrap">
<Button size="sm" variant="outline" onClick={() => handleAddMana(10)}>
@@ -143,15 +155,15 @@ export function GameStateDebug() {
</Button>
</div>
<Separator className="bg-gray-700" />
<div className="text-xs text-gray-400">Fill to max:</div>
<div className="text-xs text-gray-400 mb-2">Fill to max:</div>
<Button
size="sm"
className="w-full bg-blue-600 hover:bg-blue-700"
onClick={() => {
const max = store.getMaxMana?.() || 100;
const current = store.rawMana;
const max = getMaxMana() || 100;
const current = rawMana;
for (let i = 0; i < Math.floor(max - current); i++) {
store.gatherMana();
gatherMana();
}
}}
>
@@ -170,30 +182,30 @@ export function GameStateDebug() {
</CardHeader>
<CardContent className="space-y-3">
<div className="text-xs text-gray-400">
Current: Day {store.day}, Hour {store.hour}
Current: Day {day}, Hour {hour}
</div>
<div className="flex gap-2 flex-wrap">
<Button size="sm" variant="outline" onClick={() => handleSetTime(1, 0)}>
<Button size="sm" variant="outline" onClick={() => setTime?.(1, 0)}>
Day 1
</Button>
<Button size="sm" variant="outline" onClick={() => handleSetTime(10, 0)}>
<Button size="sm" variant="outline" onClick={() => setTime?.(10, 0)}>
Day 10
</Button>
<Button size="sm" variant="outline" onClick={() => handleSetTime(20, 0)}>
<Button size="sm" variant="outline" onClick={() => setTime?.(20, 0)}>
Day 20
</Button>
<Button size="sm" variant="outline" onClick={() => handleSetTime(30, 0)}>
<Button size="sm" variant="outline" onClick={() => setTime?.(30, 0)}>
Day 30
</Button>
</div>
<Separator className="bg-gray-700" />
<div className="flex gap-2">
<Button
size="sm"
<Button
size="sm"
variant="outline"
onClick={() => useGameStore.getState().togglePause()}
onClick={togglePause}
>
{store.paused ? '▶ Resume' : '⏸ Pause'}
{paused ? '▶ Resume' : '⏸ Pause'}
</Button>
</div>
</CardContent>
@@ -215,8 +227,8 @@ export function GameStateDebug() {
onClick={() => {
// Unlock all base elements
['fire', 'water', 'air', 'earth', 'light', 'dark', 'death'].forEach(e => {
if (!store.elements[e]?.unlocked) {
useGameStore.getState().unlockElement(e);
if (!elements[e]?.unlocked) {
unlockElement(e, 500);
}
});
}}
@@ -229,8 +241,8 @@ export function GameStateDebug() {
onClick={() => {
// Unlock utility elements
['transference'].forEach(e => {
if (!store.elements[e]?.unlocked) {
useGameStore.getState().unlockElement(e);
if (!elements[e]?.unlocked) {
unlockElement(e, 500);
}
});
}}
@@ -240,24 +252,14 @@ export function GameStateDebug() {
<Button
size="sm"
variant="outline"
onClick={() => {
// Max floor
if (store.debugSetFloor) {
useGameStore.getState().debugSetFloor(100);
}
}}
onClick={() => setFloor?.(100)}
>
Skip to Floor 100
</Button>
<Button
size="sm"
variant="outline"
onClick={() => {
// Reset floor HP
if (store.resetFloorHP) {
useGameStore.getState().resetFloorHP();
}
}}
onClick={() => resetHP?.()}
>
Reset Floor HP
</Button>