701 lines
28 KiB
TypeScript
Executable File
701 lines
28 KiB
TypeScript
Executable File
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Separator } from '@/components/ui/separator';
|
|
import { Switch } from '@/components/ui/switch';
|
|
import { Label } from '@/components/ui/label';
|
|
import {
|
|
RotateCcw, Bug, Plus, Minus, Lock, Unlock, Zap,
|
|
Clock, Star, AlertTriangle, Sparkles, Settings, Eye, BookOpen
|
|
} from 'lucide-react';
|
|
import type { GameStore } from '@/lib/game/types';
|
|
import { ATTUNEMENTS_DEF } from '@/lib/game/data/attunements';
|
|
import { ELEMENTS } from '@/lib/game/constants';
|
|
import { fmt } from '@/lib/game/store';
|
|
import { useDebug } from '@/lib/game/debug-context';
|
|
|
|
interface DebugTabProps {
|
|
store: GameStore;
|
|
}
|
|
|
|
export function DebugTab({ store }: DebugTabProps) {
|
|
const [confirmReset, setConfirmReset] = useState(false);
|
|
const { showComponentNames, toggleComponentNames } = useDebug();
|
|
|
|
const handleReset = () => {
|
|
if (confirmReset) {
|
|
store.resetGame();
|
|
setConfirmReset(false);
|
|
} else {
|
|
setConfirmReset(true);
|
|
setTimeout(() => setConfirmReset(false), 3000);
|
|
}
|
|
};
|
|
|
|
const handleAddMana = (amount: number) => {
|
|
// Use gatherMana multiple times to add mana
|
|
for (let i = 0; i < amount; i++) {
|
|
store.gatherMana();
|
|
}
|
|
};
|
|
|
|
const handleUnlockAttunement = (id: string) => {
|
|
// Debug action to unlock attunements
|
|
if (store.debugUnlockAttunement) {
|
|
store.debugUnlockAttunement(id);
|
|
}
|
|
};
|
|
|
|
const handleUnlockElement = (element: string) => {
|
|
store.unlockElement(element);
|
|
};
|
|
|
|
const handleAddElementalMana = (element: string, amount: number) => {
|
|
const elem = store.elements[element];
|
|
if (elem?.unlocked) {
|
|
// Add directly to element pool - need to implement in store
|
|
if (store.debugAddElementalMana) {
|
|
store.debugAddElementalMana(element, amount);
|
|
}
|
|
}
|
|
};
|
|
|
|
const handleSetTime = (day: number, hour: number) => {
|
|
if (store.debugSetTime) {
|
|
store.debugSetTime(day, hour);
|
|
}
|
|
};
|
|
|
|
const handleAddAttunementXP = (id: string, amount: number) => {
|
|
if (store.debugAddAttunementXP) {
|
|
store.debugAddAttunementXP(id, amount);
|
|
}
|
|
};
|
|
|
|
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: {fmt(store.rawMana)} / {fmt(store.getMaxMana())}
|
|
</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(10)}>
|
|
<Plus className="w-3 h-3 mr-1" /> +10
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(100)}>
|
|
<Plus className="w-3 h-3 mr-1" /> +100
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(1000)}>
|
|
<Plus className="w-3 h-3 mr-1" /> +1K
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleAddMana(10000)}>
|
|
<Plus className="w-3 h-3 mr-1" /> +10K
|
|
</Button>
|
|
</div>
|
|
<Separator className="bg-gray-700" />
|
|
<div className="text-xs text-gray-400">Fill to max:</div>
|
|
<Button
|
|
size="sm"
|
|
className="w-full bg-blue-600 hover:bg-blue-700"
|
|
onClick={() => {
|
|
const max = store.getMaxMana();
|
|
const current = store.rawMana;
|
|
for (let i = 0; i < Math.floor(max - current); i++) {
|
|
store.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 {store.day}, Hour {store.hour}
|
|
</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button size="sm" variant="outline" onClick={() => handleSetTime(1, 0)}>
|
|
Day 1
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleSetTime(10, 0)}>
|
|
Day 10
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleSetTime(20, 0)}>
|
|
Day 20
|
|
</Button>
|
|
<Button size="sm" variant="outline" onClick={() => handleSetTime(30, 0)}>
|
|
Day 30
|
|
</Button>
|
|
</div>
|
|
<Separator className="bg-gray-700" />
|
|
<div className="flex gap-2">
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => store.togglePause()}
|
|
>
|
|
{store.paused ? '▶ Resume' : '⏸ Pause'}
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Attunement Unlock */}
|
|
<Card className="bg-gray-900/80 border-gray-700">
|
|
<CardHeader className="pb-2">
|
|
<CardTitle className="text-purple-400 text-sm flex items-center gap-2">
|
|
<Sparkles className="w-4 h-4" />
|
|
Attunements
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
{Object.entries(ATTUNEMENTS_DEF).map(([id, def]) => {
|
|
const isActive = store.attunements?.[id]?.active;
|
|
const level = store.attunements?.[id]?.level || 1;
|
|
const xp = store.attunements?.[id]?.experience || 0;
|
|
|
|
return (
|
|
<div key={id} className="flex items-center justify-between p-2 bg-gray-800/50 rounded">
|
|
<div className="flex items-center gap-2">
|
|
<span>{def.icon}</span>
|
|
<div>
|
|
<div className="text-sm font-medium">{def.name}</div>
|
|
{isActive && (
|
|
<div className="text-xs text-gray-400">Lv.{level} • {xp} XP</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="flex gap-1">
|
|
{!isActive && (
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => handleUnlockAttunement(id)}
|
|
>
|
|
<Unlock className="w-3 h-3" />
|
|
</Button>
|
|
)}
|
|
{isActive && (
|
|
<>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => handleAddAttunementXP(id, 50)}
|
|
>
|
|
+50 XP
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => handleAddAttunementXP(id, 500)}
|
|
>
|
|
+500 XP
|
|
</Button>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Element Unlock */}
|
|
<Card className="bg-gray-900/80 border-gray-700 md:col-span-2">
|
|
<CardHeader className="pb-2">
|
|
<CardTitle className="text-green-400 text-sm flex items-center gap-2">
|
|
<Star className="w-4 h-4" />
|
|
Elemental Mana
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-6 gap-2">
|
|
{Object.entries(ELEMENTS).map(([id, def]) => {
|
|
const elem = store.elements[id];
|
|
const isUnlocked = elem?.unlocked;
|
|
|
|
return (
|
|
<div
|
|
key={id}
|
|
className={`p-2 rounded border ${
|
|
isUnlocked ? 'border-gray-600' : 'border-gray-800 opacity-60'
|
|
}`}
|
|
style={{
|
|
borderColor: isUnlocked ? def.color : undefined
|
|
}}
|
|
>
|
|
<div className="flex items-center justify-between mb-1">
|
|
<span style={{ color: def.color }}>{def.sym}</span>
|
|
{!isUnlocked && (
|
|
<Button
|
|
size="sm"
|
|
variant="ghost"
|
|
className="h-5 w-5 p-0"
|
|
onClick={() => handleUnlockElement(id)}
|
|
>
|
|
<Lock className="w-3 h-3" />
|
|
</Button>
|
|
)}
|
|
</div>
|
|
<div className="text-xs" style={{ color: def.color }}>{def.name}</div>
|
|
{isUnlocked && (
|
|
<div className="text-xs text-gray-400 mt-1">
|
|
{elem.current.toFixed(0)}/{elem.max}
|
|
</div>
|
|
)}
|
|
{isUnlocked && (
|
|
<Button
|
|
size="sm"
|
|
variant="ghost"
|
|
className="h-5 w-full mt-1 text-xs"
|
|
onClick={() => handleAddElementalMana(id, 100)}
|
|
>
|
|
+100
|
|
</Button>
|
|
)}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Skills Debug */}
|
|
<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 (!store.elements[e]?.unlocked) {
|
|
store.unlockElement(e);
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
Unlock All Base Elements
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Unlock utility elements (only transference remains)
|
|
['transference'].forEach(e => {
|
|
if (!store.elements[e]?.unlocked) {
|
|
store.unlockElement(e);
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
Unlock Utility Elements
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Max floor
|
|
if (store.debugSetFloor) {
|
|
store.debugSetFloor(100);
|
|
}
|
|
}}
|
|
>
|
|
Skip to Floor 100
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Reset floor HP
|
|
if (store.resetFloorHP) {
|
|
store.resetFloorHP();
|
|
}
|
|
}}
|
|
>
|
|
Reset Floor HP
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Skill Research Debug */}
|
|
<Card className="bg-gray-900/80 border-gray-700 md:col-span-2">
|
|
<CardHeader className="pb-2">
|
|
<CardTitle className="text-purple-400 text-sm flex items-center gap-2">
|
|
<BookOpen className="w-4 h-4" />
|
|
Skill Research Debug
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-3">
|
|
{/* Enchanting Skills */}
|
|
<div>
|
|
<div className="text-xs text-gray-400 mb-2">Enchanting Skills:</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Level up all enchanting skills by 1
|
|
const enchantSkills = ['enchanting', 'efficientEnchant', 'disenchanting', 'enchantSpeed', 'scrollCrafting', 'essenceRefining'];
|
|
enchantSkills.forEach(skillId => {
|
|
if (store.skills[skillId] !== undefined) {
|
|
store.skills[skillId] = Math.min((store.skills[skillId] || 0) + 1, 10);
|
|
} else {
|
|
store.skills[skillId] = 1;
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
+1 All Enchanting
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Max all enchanting skills
|
|
const enchantSkills = ['enchanting', 'efficientEnchant', 'disenchanting', 'enchantSpeed', 'scrollCrafting', 'essenceRefining'];
|
|
enchantSkills.forEach(skillId => {
|
|
store.skills[skillId] = 10;
|
|
});
|
|
}}
|
|
>
|
|
Max All Enchanting
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mana Skills */}
|
|
<div>
|
|
<div className="text-xs text-gray-400 mb-2">Mana Skills:</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
const manaSkills = ['manaWell', 'manaFlow', 'elemAttune', 'manaOverflow'];
|
|
manaSkills.forEach(skillId => {
|
|
if (store.skills[skillId] !== undefined) {
|
|
store.skills[skillId] = Math.min((store.skills[skillId] || 0) + 1, 10);
|
|
} else {
|
|
store.skills[skillId] = 1;
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
+1 All Mana
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
const manaSkills = ['manaWell', 'manaFlow', 'elemAttune', 'manaOverflow'];
|
|
manaSkills.forEach(skillId => {
|
|
store.skills[skillId] = 10;
|
|
});
|
|
}}
|
|
>
|
|
Max All Mana
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Study Skills */}
|
|
<div>
|
|
<div className="text-xs text-gray-400 mb-2">Study Skills:</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
const studySkills = ['quickLearner', 'focusedMind', 'meditation', 'knowledgeRetention'];
|
|
studySkills.forEach(skillId => {
|
|
if (store.skills[skillId] !== undefined) {
|
|
store.skills[skillId] = Math.min((store.skills[skillId] || 0) + 1, 10);
|
|
} else {
|
|
store.skills[skillId] = 1;
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
+1 All Study
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
const studySkills = ['quickLearner', 'focusedMind', 'meditation', 'knowledgeRetention'];
|
|
studySkills.forEach(skillId => {
|
|
store.skills[skillId] = 10;
|
|
});
|
|
}}
|
|
>
|
|
Max All Study
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Crafting Skills */}
|
|
<div>
|
|
<div className="text-xs text-gray-400 mb-2">Crafting Skills:</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
const craftSkills = ['effCrafting', 'fieldRepair', 'elemCrafting'];
|
|
craftSkills.forEach(skillId => {
|
|
if (store.skills[skillId] !== undefined) {
|
|
store.skills[skillId] = Math.min((store.skills[skillId] || 0) + 1, 10);
|
|
} else {
|
|
store.skills[skillId] = 1;
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
+1 All Crafting
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
const craftSkills = ['effCrafting', 'fieldRepair', 'elemCrafting'];
|
|
craftSkills.forEach(skillId => {
|
|
store.skills[skillId] = 10;
|
|
});
|
|
}}
|
|
>
|
|
Max All Crafting
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Research Effects */}
|
|
<div>
|
|
<div className="text-xs text-gray-400 mb-2">Research Effects:</div>
|
|
<div className="flex gap-2 flex-wrap">
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Unlock all spell research
|
|
const researchSkills = [
|
|
'researchManaSpells', 'researchFireSpells', 'researchWaterSpells',
|
|
'researchAirSpells', 'researchEarthSpells', 'researchLightSpells',
|
|
'researchDarkSpells', 'researchLifeDeathSpells',
|
|
'researchAdvancedFire', 'researchAdvancedWater', 'researchAdvancedAir',
|
|
'researchAdvancedEarth', 'researchAdvancedLight', 'researchAdvancedDark',
|
|
'researchMasterFire', 'researchMasterWater', 'researchMasterEarth',
|
|
'researchDamageEffects', 'researchCombatEffects',
|
|
'researchManaEffects', 'researchAdvancedManaEffects', 'researchUtilityEffects'
|
|
];
|
|
researchSkills.forEach(skillId => {
|
|
store.skills[skillId] = 1;
|
|
});
|
|
}}
|
|
>
|
|
Unlock All Research
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
variant="outline"
|
|
onClick={() => {
|
|
// Add all unlocked effects to unlockedEffects
|
|
const effectIds = Object.keys(store.unlockedEffects || {});
|
|
// Add spell effects, mana effects, combat effects, utility effects
|
|
const allEffectIds = [
|
|
// Spell effects
|
|
'spell_manaBolt', 'spell_manaStrike', 'spell_fireball', 'spell_emberShot',
|
|
'spell_waterJet', 'spell_iceShard', 'spell_gust', 'spell_windSlash',
|
|
'spell_stoneBullet', 'spell_rockSpike', 'spell_lightLance', 'spell_radiance',
|
|
'spell_shadowBolt', 'spell_darkPulse', 'spell_drain',
|
|
// Tier 2 spells
|
|
'spell_inferno', 'spell_flameWave', 'spell_tidalWave', 'spell_iceStorm',
|
|
'spell_hurricane', 'spell_windBlade', 'spell_earthquake', 'spell_stoneBarrage',
|
|
'spell_solarFlare', 'spell_divineSmite', 'spell_voidRift', 'spell_shadowStorm',
|
|
// Tier 3 spells
|
|
'spell_pyroclasm', 'spell_tsunami', 'spell_meteorStrike',
|
|
// Lightning
|
|
'spell_spark', 'spell_lightningBolt', 'spell_chainLightning',
|
|
'spell_stormCall', 'spell_thunderStrike',
|
|
// Metal and Sand
|
|
'spell_metalShard', 'spell_ironFist', 'spell_steelTempest', 'spell_furnaceBlast',
|
|
'spell_sandBlast', 'spell_sandstorm', 'spell_desertWind', 'spell_duneCollapse',
|
|
// Mana effects
|
|
'mana_cap_50', 'mana_cap_100', 'mana_regen_1', 'mana_regen_2', 'mana_regen_5',
|
|
'click_mana_1', 'click_mana_3',
|
|
// Combat effects
|
|
'damage_5', 'damage_10', 'damage_pct_10', 'crit_5', 'attack_speed_10',
|
|
// Utility effects
|
|
'meditate_10', 'study_10', 'insight_5',
|
|
// Special
|
|
'spell_echo_10', 'guardian_dmg_10', 'overpower_80',
|
|
// Weapon mana
|
|
'weapon_mana_cap_20', 'weapon_mana_cap_50', 'weapon_mana_cap_100',
|
|
'weapon_mana_regen_1', 'weapon_mana_regen_2', 'weapon_mana_regen_5',
|
|
// Sword enchants
|
|
'sword_fire', 'sword_frost', 'sword_lightning', 'sword_void'
|
|
];
|
|
allEffectIds.forEach(id => {
|
|
if (!store.unlockedEffects.includes(id)) {
|
|
store.unlockedEffects.push(id);
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
Unlock All Effects
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Max All */}
|
|
<Separator className="bg-gray-700" />
|
|
<div className="flex gap-2">
|
|
<Button
|
|
size="sm"
|
|
className="bg-purple-600 hover:bg-purple-700"
|
|
onClick={() => {
|
|
// Max all skills
|
|
Object.keys(store.skills).forEach(skillId => {
|
|
const current = store.skills[skillId] || 0;
|
|
if (current < 10) {
|
|
store.skills[skillId] = 10;
|
|
}
|
|
});
|
|
// Unlock all effects
|
|
const allEffectIds = [
|
|
'spell_manaBolt', 'spell_manaStrike', 'spell_fireball', 'spell_emberShot',
|
|
'spell_waterJet', 'spell_iceShard', 'spell_gust', 'spell_windSlash',
|
|
'spell_stoneBullet', 'spell_rockSpike', 'spell_lightLance', 'spell_radiance',
|
|
'spell_shadowBolt', 'spell_darkPulse', 'spell_drain', 'spell_inferno',
|
|
'spell_flameWave', 'spell_tidalWave', 'spell_iceStorm', 'spell_hurricane',
|
|
'spell_windBlade', 'spell_earthquake', 'spell_stoneBarrage', 'spell_solarFlare',
|
|
'spell_divineSmite', 'spell_voidRift', 'spell_shadowStorm', 'spell_pyroclasm',
|
|
'spell_tsunami', 'spell_meteorStrike', 'spell_spark', 'spell_lightningBolt',
|
|
'spell_chainLightning', 'spell_stormCall', 'spell_thunderStrike', 'spell_metalShard',
|
|
'spell_ironFist', 'spell_steelTempest', 'spell_furnaceBlast', 'spell_sandBlast',
|
|
'spell_sandstorm', 'spell_desertWind', 'spell_duneCollapse',
|
|
'mana_cap_50', 'mana_cap_100', 'mana_regen_1', 'mana_regen_2', 'mana_regen_5',
|
|
'click_mana_1', 'click_mana_3', 'damage_5', 'damage_10', 'damage_pct_10',
|
|
'crit_5', 'attack_speed_10', 'meditate_10', 'study_10', 'insight_5',
|
|
'spell_echo_10', 'guardian_dmg_10', 'overpower_80',
|
|
'weapon_mana_cap_20', 'weapon_mana_cap_50', 'weapon_mana_cap_100',
|
|
'weapon_mana_regen_1', 'weapon_mana_regen_2', 'weapon_mana_regen_5',
|
|
'sword_fire', 'sword_frost', 'sword_lightning', 'sword_void'
|
|
];
|
|
allEffectIds.forEach(id => {
|
|
if (!store.unlockedEffects.includes(id)) {
|
|
store.unlockedEffects.push(id);
|
|
}
|
|
});
|
|
}}
|
|
>
|
|
🚀 Max Everything
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|