Files
Mana-Loop/src/components/game/tabs/DebugTab/GameStateDebugSection.tsx
T
n8n-gitea e0e7beb495
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m22s
fix: remove debug Skip to Floor 100 and Reset Floor HP buttons
- Remove debugSetFloor and resetFloorHP actions from combatStore.ts
- Remove their type definitions from combat-state.types.ts
- Remove Skip to Floor 100 and Reset Floor HP buttons from GameStateDebugSection.tsx
- Remove same buttons from legacy GameStateDebug.tsx
- Remove floor quick-jump and Reset Floor HP from SpireDebugSection.tsx
- Remove associated tests from DebugTab.test.ts, store-actions.test.ts, store-actions-combat-prestige.test.ts
- Add missing src/test/setup.ts required by vitest config

These debug buttons created inconsistent game states by teleporting players
to floors without proper initialization (no spireMode, no room state, no
clearedFloors, no guardian encounters). resetFloorHP could be spammed to
infinitely retry any floor for free.
2026-05-29 14:54:52 +02:00

264 lines
9.4 KiB
TypeScript

'use client';
import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Separator } from '@/components/ui/separator';
import { Switch } from '@/components/ui/switch';
import { Label } from '@/components/ui/label';
import {
RotateCcw, AlertTriangle, Zap, Clock, Eye,
} from 'lucide-react';
import { DebugName, useDebug } from '@/components/game/debug/debug-context';
import { useGameStore, useManaStore, useUIStore, useCombatStore } from '@/lib/game/stores';
import { computeMaxMana } from '@/lib/game/stores';
// ─── Display Options ─────────────────────────────────────────────────────────
function DisplayOptions() {
const { showComponentNames, toggleComponentNames } = useDebug();
return (
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader className="pb-2">
<CardTitle className="text-cyan-400 text-sm flex items-center gap-2">
<Eye className="w-4 h-4" />
Display Options
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center justify-between">
<div className="space-y-0.5">
<Label htmlFor="show-component-names" className="text-sm">Show Component Names</Label>
<p className="text-xs text-gray-400">
Display component names at the top of each component for debugging
</p>
</div>
<Switch
id="show-component-names"
checked={showComponentNames}
onCheckedChange={toggleComponentNames}
/>
</div>
</CardContent>
</Card>
);
}
// ─── Game Reset Section ──────────────────────────────────────────────────────
function GameResetSection({ confirmReset, onReset }: { confirmReset: boolean; onReset: () => void }) {
return (
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader className="pb-2">
<CardTitle className="text-red-400 text-sm flex items-center gap-2">
<RotateCcw className="w-4 h-4" />
Game Reset
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<p className="text-xs text-gray-400">
Reset all game progress and start fresh. This cannot be undone.
</p>
<Button
className={`w-full ${confirmReset ? 'bg-red-600 hover:bg-red-700' : 'bg-gray-700 hover:bg-gray-600'}`}
onClick={onReset}
>
{confirmReset ? (
<>
<AlertTriangle className="w-4 h-4 mr-2" />
Click Again to Confirm Reset
</>
) : (
<>
<RotateCcw className="w-4 h-4 mr-2" />
Reset Game
</>
)}
</Button>
</CardContent>
</Card>
);
}
// ─── Mana Debug Section ──────────────────────────────────────────────────────
function ManaDebugSection({ rawMana, onAddMana, onFillMana }: {
rawMana: number;
onAddMana: (amount: number) => void;
onFillMana: () => void;
}) {
const maxMana = computeMaxMana(
{ skills: {}, prestigeUpgrades: {}, skillUpgrades: {}, skillTiers: {} }
);
return (
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader className="pb-2">
<CardTitle className="text-blue-400 text-sm flex items-center gap-2">
<Zap className="w-4 h-4" />
Mana Debug
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="text-xs text-gray-400 mb-2">
Current: {rawMana} / {maxMana || '?'}
</div>
<div className="flex gap-2 flex-wrap">
<Button size="sm" variant="outline" onClick={() => onAddMana(10)}>
<Zap className="w-3 h-3 mr-1" /> +10
</Button>
<Button size="sm" variant="outline" onClick={() => onAddMana(100)}>
<Zap className="w-3 h-3 mr-1" /> +100
</Button>
<Button size="sm" variant="outline" onClick={() => onAddMana(1000)}>
<Zap className="w-3 h-3 mr-1" /> +1K
</Button>
<Button size="sm" variant="outline" onClick={() => onAddMana(10000)}>
<Zap className="w-3 h-3 mr-1" /> +10K
</Button>
</div>
<Separator className="bg-gray-700" />
<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={onFillMana}>
Fill Mana
</Button>
</CardContent>
</Card>
);
}
// ─── Time Control Section ────────────────────────────────────────────────────
function TimeControlSection({ day, hour, paused, onSetDay, onTogglePause }: {
day: number;
hour: number;
paused: boolean;
onSetDay: (day: number) => void;
onTogglePause: () => void;
}) {
return (
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader className="pb-2">
<CardTitle className="text-amber-400 text-sm flex items-center gap-2">
<Clock className="w-4 h-4" />
Time Control
</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div className="text-xs text-gray-400">
Current: Day {day}, Hour {hour}
</div>
<div className="flex gap-2 flex-wrap">
<Button size="sm" variant="outline" onClick={() => onSetDay(1)}>Day 1</Button>
<Button size="sm" variant="outline" onClick={() => onSetDay(10)}>Day 10</Button>
<Button size="sm" variant="outline" onClick={() => onSetDay(20)}>Day 20</Button>
<Button size="sm" variant="outline" onClick={() => onSetDay(30)}>Day 30</Button>
</div>
<Separator className="bg-gray-700" />
<div className="flex gap-2">
<Button size="sm" variant="outline" onClick={onTogglePause}>
{paused ? '▶ Resume' : '⏸ Pause'}
</Button>
</div>
</CardContent>
</Card>
);
}
// ─── Quick Actions Section ───────────────────────────────────────────────────
function QuickActionsSection({ onUnlockBase }: {
onUnlockBase: () => void;
}) {
return (
<Card className="bg-gray-900/80 border-gray-700">
<CardHeader className="pb-2">
<CardTitle className="text-cyan-400 text-sm flex items-center gap-2">
<Zap className="w-4 h-4" />
Quick Actions
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex gap-2 flex-wrap">
<Button size="sm" variant="outline" onClick={onUnlockBase}>
Unlock All Base Elements
</Button>
</div>
</CardContent>
</Card>
);
}
// ─── Main Component ───────────────────────────────────────────────────────────
export function GameStateDebugSection() {
const [confirmReset, setConfirmReset] = useState(false);
const { showComponentNames, toggleComponentNames } = useDebug();
const rawMana = useManaStore((s) => s.rawMana);
const day = useGameStore((s) => s.day);
const hour = useGameStore((s) => s.hour);
const paused = useUIStore((s) => s.paused);
const togglePause = useUIStore((s) => s.togglePause);
const resetGame = useGameStore((s) => s.resetGame);
const gatherMana = useGameStore((s) => s.gatherMana);
const elements = useManaStore((s) => s.elements);
const unlockElement = useManaStore((s) => s.unlockElement);
const handleReset = () => {
if (confirmReset) {
resetGame();
setConfirmReset(false);
} else {
setConfirmReset(true);
setTimeout(() => setConfirmReset(false), 3000);
}
};
const handleAddMana = (amount: number) => {
for (let i = 0; i < amount; i++) {
gatherMana();
}
};
const handleFillMana = () => {
const maxMana = computeMaxMana(
{ skills: {}, prestigeUpgrades: {}, skillUpgrades: {}, skillTiers: {} }
) || 100;
useManaStore.setState((s) => ({ rawMana: Math.max(s.rawMana, maxMana) }));
};
const handleSetDay = (d: number) => {
useGameStore.setState({ day: d, hour: 0 });
};
const handleUnlockBase = () => {
['fire', 'water', 'air', 'earth', 'light', 'dark', 'death'].forEach(e => {
if (!elements[e]?.unlocked) {
unlockElement(e, 0);
}
});
};
return (
<DebugName name="GameStateDebugSection">
<div className="space-y-4">
<DisplayOptions />
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<GameResetSection confirmReset={confirmReset} onReset={handleReset} />
<ManaDebugSection rawMana={rawMana} onAddMana={handleAddMana} onFillMana={handleFillMana} />
<TimeControlSection day={day} hour={hour} paused={paused} onSetDay={handleSetDay} onTogglePause={togglePause} />
<QuickActionsSection
onUnlockBase={handleUnlockBase}
/>
</div>
</div>
</DebugName>
);
}
GameStateDebugSection.displayName = 'GameStateDebugSection';