Completely remove legacy skill system and tests
This commit is contained in:
@@ -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';
|
||||
Reference in New Issue
Block a user