'use client'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Tooltip, TooltipProvider, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'; import { Zap, Shield, ShieldCheck, Wind, Heart, Mountain, BookOpen } from 'lucide-react'; import { ELEMENTS } from '@/lib/game/constants'; import { GOLEMS_DEF, getGolemDamage, getGolemAttackSpeed } from '@/lib/game/data/golems'; import type { CombatStatsPanelProps } from '@/lib/game/types'; export function CombatStatsPanel({ activeEquipmentSpells, store, totalDPS, calcDamage, formatSpellCost, getSpellCostColor, SPELLS_DEF, upgradeEffects, canCastSpell, studySpeedMult, storeCurrentAction, }: CombatStatsPanelProps) { const activeGolems = store.golemancy.summonedGolems; return ( Combat Stats
Total DPS: {storeCurrentAction === 'climb' && activeEquipmentSpells.length > 0 ? fmtDec(totalDPS) : '—'}
{activeEquipmentSpells.length > 0 && (
Active Spells
{activeEquipmentSpells.map(({ spellId, equipmentId }) => { const spellDef = SPELLS_DEF[spellId]; if (!spellDef) return null; const spellState = store.equipmentSpellStates?.find( s => s.spellId === spellId && s.sourceEquipment === equipmentId ); const progress = spellState?.castProgress || 0; const canCast = canCastSpell(spellId); return (
{spellDef.name} {spellDef.tier === 0 && Basic} {spellDef.tier >= 4 && Legendary} {canCast ? '✓' : '✗'}
⚔️ {fmt(calcDamage(store, spellId))} dmg • {' '} {formatSpellCost(spellDef.cost)} {' '}• ⚡ {fmt(Math.floor(calcDamage(store, spellId) * (spellDef.castSpeed || 1)))} dmg/hr
{storeCurrentAction === 'climb' && (
Cast {(progress * 100).toFixed(0)}%
)}
); })}
)} {activeGolems.length > 0 && (
Active Golems
{activeGolems.map((summoned) => { const golemDef = GOLEMS_DEF[summoned.golemId]; if (!golemDef) return null; const elemColor = ELEMENTS[golemDef.baseManaType]?.color || '#888'; const damage = getGolemDamage(summoned.golemId, store.skills); const attackSpeed = getGolemAttackSpeed(summoned.golemId, store.skills); return (
{golemDef.name}
{golemDef.isAoe && ( AOE {golemDef.aoeTargets} )}
⚔️ {damage} DMG • ⚡ {attackSpeed.toFixed(1)}/hr
{storeCurrentAction === 'climb' && summoned.attackProgress > 0 && (
Attack {Math.min(100, (summoned.attackProgress * 100)).toFixed(0)}%
)}
); })}
)}
Study Speed: {Math.round(studySpeedMult * 100)}%
); } function fmt(value: number): string { if (value >= 1e12) return (value / 1e12).toFixed(2) + 't'; if (value >= 1e9) return (value / 1e9).toFixed(2) + 'b'; if (value >= 1e6) return (value / 1e6).toFixed(2) + 'm'; if (value >= 1e3) return (value / 1e3).toFixed(2) + 'k'; return value.toFixed(0); } function fmtDec(value: number): string { if (value >= 1e12) return (value / 1e12).toFixed(2) + 't'; if (value >= 1e9) return (value / 1e9).toFixed(2) + 'b'; if (value >= 1e6) return (value / 1e6).toFixed(2) + 'm'; if (value >= 1e3) return (value / 1e3).toFixed(2) + 'k'; return value.toFixed(0); }