275 lines
9.7 KiB
TypeScript
275 lines
9.7 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, Settings, Eye,
|
|
} from 'lucide-react';
|
|
import { useDebug } from '@/lib/game/debug-context';
|
|
import { useGameStore, useManaStore, useUIStore, useCombatStore } 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 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 = useUIStore((s) => s.paused);
|
|
const togglePause = useUIStore((s) => s.togglePause);
|
|
|
|
// Get actions from stores
|
|
const resetGame = useGameStore((s) => s.resetGame);
|
|
const setTime = useCombatStore((s) => s.debugSetTime);
|
|
const setFloor = useCombatStore((s) => s.debugSetFloor);
|
|
const resetHP = useCombatStore((s) => s.resetFloorHP);
|
|
|
|
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 getMaxMana = () => {
|
|
return computeMaxMana(
|
|
{ skills: {}, prestigeUpgrades: {}, skillUpgrades: {}, skillTiers: {} },
|
|
{ maxManaBonus: 0, maxManaMultiplier: 1 }
|
|
);
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* Warning Banner */}
|
|
<Card className="bg-amber-900/20 border-amber-600/50">
|
|
<CardContent className="pt-4">
|
|
<div className="flex items-center gap-2 text-amber-400">
|
|
<AlertTriangle className="w-5 h-5" />
|
|
<span className="font-semibold">Debug Mode</span>
|
|
</div>
|
|
<p className="text-sm text-amber-300/70 mt-1">
|
|
These tools are for development and testing. Using them may break game balance or save data.
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Display Options */}
|
|
<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>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
{/* Game Reset */}
|
|
<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={handleReset}
|
|
>
|
|
{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 */}
|
|
<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} / {getMaxMana() || '?'}
|
|
</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(10)}>
|
|
<Zap className="w-3 h-3 mr-1" /> +10
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(100)}>
|
|
<Zap className="w-3 h-3 mr-1" /> +100
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(1000)}>
|
|
<Zap className="w-3 h-3 mr-1" /> +1K
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(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={() => {
|
|
const max = getMaxMana() || 100;
|
|
const current = rawMana;
|
|
for (let i = 0; i < Math.floor(max - current); i++) {
|
|
gatherMana();
|
|
}
|
|
}}
|
|
>
|
|
Fill Mana
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Time Control */}
|
|
<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={() => setTime?.(1, 0)}>
|
|
Day 1
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => setTime?.(10, 0)}>
|
|
Day 10
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => setTime?.(20, 0)}>
|
|
Day 20
|
|
</Button>
|
|
<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"
|
|
variant="outline"
|
|
onClick={togglePause}
|
|
>
|
|
{paused ? '▶ Resume' : '⏸ Pause'}
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Skills Debug - Quick Actions */}
|
|
<Card className="bg-gray-900/80 border-gray-700 md:col-span-2">
|
|
<CardHeader className="pb-2">
|
|
<CardTitle className="text-cyan-400 text-sm flex items-center gap-2">
|
|
<Settings className="w-4 h-4" />
|
|
Quick Actions
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Unlock all base elements
|
|
['fire', 'water', 'air', 'earth', 'light', 'dark', 'death'].forEach(e => {
|
|
if (!elements[e]?.unlocked) {
|
|
unlockElement(e, 500);
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
Unlock All Base Elements
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Unlock utility elements
|
|
['transference'].forEach(e => {
|
|
if (!elements[e]?.unlocked) {
|
|
unlockElement(e, 500);
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
Unlock Utility Elements
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => setFloor?.(100)}
|
|
>
|
|
Skip to Floor 100
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => resetHP?.()}
|
|
>
|
|
Reset Floor HP
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
GameStateDebug.displayName = "GameStateDebug";
|