Completely remove legacy skill system and tests

This commit is contained in:
2026-05-16 11:20:11 +02:00
parent 1a688394e4
commit fe0f2a079c
125 changed files with 7 additions and 14459 deletions
-244
View File
@@ -1,244 +0,0 @@
'use client';
import { useCombatStore, useCraftingStore, useManaStore, usePrestigeStore } from '@/lib/game/stores';
import { GameCard, ElementBadge } from '@/components/ui';
import { Badge } from '@/components/ui/badge';
import { ELEMENTS, SPELLS_DEF } from '@/lib/game/constants';
import { ENCHANTMENT_EFFECTS } from '@/lib/game/data/enchantment-effects';
import { canAffordSpellCost } from '@/lib/game/utils';
import { formatSpellCost, getSpellCostColor } from '@/lib/game/formatting';
export function SpellsTab() {
// Use modular stores directly
const spells = useCombatStore((s) => s.spells);
const activeSpell = useCombatStore((s) => s.activeSpell);
const setSpell = useCombatStore((s) => s.setSpell);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const rawMana = useManaStore((s) => s.rawMana);
const elements = useManaStore((s) => s.elements);
const signedPacts = usePrestigeStore((s) => s.signedPacts);
const unlockedEffects = useCraftingStore((s) => s.unlockedEffects);
// Get spells from equipment
const equipmentSpellIds: string[] = [];
const spellSources: Record<string, string[]> = {};
// Guard against undefined stores during initialization
if (!equippedInstances || !equipmentInstances) {
return (
<DebugName name="SpellsTab">
<div className="p-4 text-center text-[var(--text-muted)]">
Loading spell data...
</div>
</DebugName>);
}
for (const instanceId of Object.values(equippedInstances || {})) {
if (!instanceId) continue;
const instance = equipmentInstances[instanceId];
if (!instance) continue;
for (const ench of instance.enchantments) {
const effectDef = ENCHANTMENT_EFFECTS?.[ench.effectId];
if (effectDef?.effect.type === 'spell' && effectDef.effect.spellId) {
const spellId = effectDef.effect.spellId;
if (!equipmentSpellIds.includes(spellId)) {
equipmentSpellIds.push(spellId);
}
if (!spellSources[spellId]) {
spellSources[spellId] = [];
}
spellSources[spellId].push(instance.name);
}
}
}
const canCastSpell = (spellId: string): boolean => {
const spell = SPELLS_DEF[spellId];
if (!spell || !spell.cost) return false;
return canAffordSpellCost(spell.cost, rawMana, elements);
};
const hasPactSpells = signedPacts && signedPacts.length > 0;
return (
<div className="space-y-6">
{/* Equipment-Granted Spells */}
<div className="mb-6">
<h3 className="text-lg font-[var(--font-heading)] font-semibold mb-3 text-[var(--mana-crystal)]">
Known Spells
</h3>
<p className="text-sm text-[var(--text-secondary)] mb-4">
Spells are obtained by enchanting equipment with spell effects.
Visit the Crafting tab to design and apply enchantments.
</p>
{equipmentSpellIds.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{equipmentSpellIds.map(id => {
const def = SPELLS_DEF[id];
if (!def) return null;
const isActive = activeSpell === id;
const canCast = canCastSpell(id);
const elemDef = def.elem === 'raw' ? null : ELEMENTS[def.elem];
const sources = spellSources[id] || [];
return (
<GameCard
key={id}
className={canCast ? 'ring-1 ring-[var(--color-success)]/30' : ''}
>
<div className="pb-2">
<div className="flex items-center justify-between">
<h4
className="text-sm font-semibold"
style={{ color: def.elem === 'raw' ? 'var(--mana-transfer)' : `var(--mana-${def.elem})` }}
>
{def.name}
</h4>
<Badge className="bg-[var(--bg-elevated)] text-[var(--mana-crystal)] text-xs border border-[var(--mana-crystal)]/30">
Equipment
</Badge>
</div>
</div>
<div className="space-y-2">
<div className="text-xs text-[var(--text-secondary)]">
{def.elem !== 'raw' && (
<span className="mr-2">
<ElementBadge element={def.elem} size="sm" /> {elemDef?.name}
</span>
)}
<span> {def.dmg} dmg</span>
</div>
<div className="text-xs font-[var(--font-mono)]" style={{ color: getSpellCostColor(def.cost) }}>
Cost: {formatSpellCost(def.cost)}
</div>
<div className="text-xs text-[var(--mana-crystal)]/70">From: {sources.join(', ')}</div>
<div className="flex gap-2">
{isActive ? (
<Badge className="bg-[var(--bg-elevated)] text-[var(--color-warning)] border border-[var(--color-warning)]/30">
Active
</Badge>
) : (
<button
className="px-3 py-1 text-xs border border-[var(--border-default)] rounded hover:border-[var(--border-focus)] transition-colors"
onClick={() => setSpell(id)}
>
Set Active
</button>
)}
</div>
</div>
</GameCard>
);
})}
</div>
) : (
<div className="text-center p-8 bg-[var(--bg-sunken)] rounded border border-[var(--border-subtle)]">
<div className="text-[var(--text-muted)] mb-2">No spells known yet</div>
<div className="text-sm text-[var(--text-muted)]">Enchant a staff with a spell effect to gain spells</div>
</div>
)}
</div>
{/* Pact Spells (from guardian defeats) - Empty State */}
{!hasPactSpells && (
<div className="mb-6">
<h3 className="text-lg font-[var(--font-heading)] font-semibold mb-3 text-[var(--color-warning)]">
Pact Spells
</h3>
<div className="text-center p-6 bg-[var(--bg-sunken)] rounded border border-[var(--border-subtle)]">
<p className="text-sm text-[var(--text-muted)]">Defeat guardians and sign pacts to unlock powerful spells</p>
</div>
</div>
)}
{hasPactSpells && (
<div className="mb-6">
<h3 className="text-lg font-[var(--font-heading)] font-semibold mb-3 text-[var(--color-warning)]">
Pact Spells
</h3>
<p className="text-sm text-[var(--text-secondary)] mb-3">Spells earned through guardian pacts appear here.</p>
</div>
)}
{/* Spell Reference - show all available spells for enchanting */}
<div className="mb-6">
<h3 className="text-lg font-[var(--font-heading)] font-semibold mb-3 text-[var(--mana-death)]">
Spell Reference
</h3>
<p className="text-sm text-[var(--text-secondary)] mb-4">
These spells can be applied to equipment through the enchanting system.
Research enchantment effects in the Skills tab to unlock them for designing.
</p>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{Object.entries(SPELLS_DEF).map(([id, def]) => {
const elemDef = def.elem === 'raw' ? null : ELEMENTS[def.elem];
const isUnlocked = unlockedEffects?.includes(`spell_${id}`);
return (
<GameCard
key={id}
variant={isUnlocked ? "default" : "sunken"}
className={isUnlocked ? 'border-[var(--mana-death)]/50' : 'opacity-60'}
>
<div className="pb-2">
<div className="flex items-center justify-between">
<h4
className="text-sm font-semibold"
style={{ color: def.elem === 'raw' ? 'var(--mana-transfer)' : `var(--mana-${def.elem})` }}
>
{def.name}
</h4>
<div className="flex gap-1">
{def.tier > 0 && (
<span className="text-xs px-1.5 py-0.5 border border-[var(--border-default)] rounded">
T{def.tier}
</span>
)}
{isUnlocked && (
<Badge className="bg-[var(--bg-elevated)] text-[var(--mana-death)] text-xs border border-[var(--mana-death)]/30">
Unlocked
</Badge>
)}
</div>
</div>
</div>
<div className="space-y-2">
<div className="text-xs text-[var(--text-secondary)]">
{def.elem !== 'raw' && (
<span className="mr-2">
<ElementBadge element={def.elem} size="sm" /> {elemDef?.name}
</span>
)}
<span> {def.dmg} dmg</span>
</div>
<div className="text-xs font-[var(--font-mono)]" style={{ color: getSpellCostColor(def.cost) }}>
Cost: {formatSpellCost(def.cost)}
</div>
{def.desc && (
<div className="text-xs text-[var(--text-muted)] italic">{def.desc}</div>
)}
{!isUnlocked && (
<div className="text-xs text-[var(--color-warning)]/70">Research to unlock for enchanting</div>
)}
</div>
</GameCard>
);
})}
</div>
</div>
</div>
);
}
SpellsTab.displayName = "SpellsTab";
import { DebugName } from '@/lib/game/debug-context';