refactor: resolve structural inconsistencies and dead code
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 55s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 55s
- Fix broken barrel exports in components/game/index.ts - Remove skill system from stores (gameStore, gameActions, gameLoopActions, gameHooks, craftingStore, combat) - Remove skill system from components (page.tsx, LeftPanel, StatsTab, SpellsTab, EnchantmentDesigner, EnchantmentPreparer, GameContext/Provider) - Delete dead code: stats/ directory, attunements/ directory, layout/ Header+TabBar, shared/ StudyProgress+UpgradeDialog duplicates, effects.ts.fix, study-slice.ts, navigation-slice.ts - Delete legacy store/ and store-modules/ directories, redirect remaining callers - Merge root formatting.ts into utils/formatting.ts - Move effects files (dynamic-compute, upgrade-effects, special-effects, upgrade-effects.types) into effects/ directory - Move debug-context.tsx into components/game/debug/ - Create tabs/index.ts barrel for tab components - Fix page.tsx lazy imports to use tabs barrel - Fix all broken import paths across codebase - Remove SKILLS_DEF and skill-evolution references - Trim store.ts to under 400 lines by removing dead skill actions
This commit is contained in:
@@ -6,8 +6,8 @@ import { usePrestigeStore } from '@/lib/game/stores/prestigeStore';
|
||||
import { useUIStore } from '@/lib/game/stores/uiStore';
|
||||
import { useCombatStore } from '@/lib/game/stores/combatStore';
|
||||
import { useGameStore } from '@/lib/game/stores/gameStore';
|
||||
import { computeEffects } from '@/lib/game/upgrade-effects';
|
||||
import { hasSpecial, SPECIAL_EFFECTS } from '@/lib/game/special-effects';
|
||||
import { computeEffects } from '@/lib/game/effects/upgrade-effects';
|
||||
import { hasSpecial, SPECIAL_EFFECTS } from '@/lib/game/effects/special-effects';
|
||||
import {
|
||||
computeMaxMana,
|
||||
computeRegen,
|
||||
|
||||
@@ -3,8 +3,8 @@ import { useManaStore } from '@/lib/game/stores/manaStore';
|
||||
import { usePrestigeStore } from '@/lib/game/stores/prestigeStore';
|
||||
import { useUIStore } from '@/lib/game/stores/uiStore';
|
||||
import { useCombatStore } from '@/lib/game/stores/combatStore';
|
||||
import { computeEffects } from '@/lib/game/upgrade-effects';
|
||||
import { hasSpecial, SPECIAL_EFFECTS } from '@/lib/game/special-effects';
|
||||
import { computeEffects } from '@/lib/game/effects/upgrade-effects';
|
||||
import { hasSpecial, SPECIAL_EFFECTS } from '@/lib/game/effects/special-effects';
|
||||
import { getBoonBonuses } from '@/lib/game/utils';
|
||||
|
||||
// Define a unified store type that combines all stores
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
import { BookOpen, X } from 'lucide-react';
|
||||
import { SKILLS_DEF, SPELLS_DEF } from '@/lib/game/constants';
|
||||
import { SPELLS_DEF } from '@/lib/game/constants';
|
||||
import { formatStudyTime } from '@/lib/game/utils/formatting';
|
||||
import type { StudyTarget } from '@/lib/game/types';
|
||||
|
||||
@@ -21,20 +21,20 @@ export function StudyProgress({
|
||||
cancelStudy,
|
||||
}: StudyProgressProps) {
|
||||
if (!currentStudyTarget) return null;
|
||||
|
||||
|
||||
const target = currentStudyTarget;
|
||||
const progressPct = Math.min(100, (target.progress / target.required) * 100);
|
||||
const isSkill = target.type === 'skill';
|
||||
const def = isSkill ? SKILLS_DEF[target.id] : SPELLS_DEF[target.id];
|
||||
const def = isSkill ? undefined : SPELLS_DEF[target.id];
|
||||
const currentLevel = isSkill ? (skills[target.id] || 0) : 0;
|
||||
|
||||
|
||||
return (
|
||||
<div className="p-3 rounded border border-purple-600/50 bg-purple-900/20">
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<BookOpen className="w-4 h-4 text-purple-400" />
|
||||
<span className="text-sm font-semibold text-purple-300">
|
||||
{def?.name}
|
||||
{def?.name ?? target.id}
|
||||
{isSkill && ` Lv.${currentLevel + 1}`}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use client';
|
||||
|
||||
import { SKILLS_DEF } from '@/lib/game/constants';
|
||||
import type { SkillUpgradeChoice } from '@/lib/game/types';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
@@ -32,35 +31,34 @@ export function UpgradeDialog({
|
||||
onOpenChange,
|
||||
}: UpgradeDialogProps) {
|
||||
if (!skillId) return null;
|
||||
|
||||
const skillDef = SKILLS_DEF[skillId];
|
||||
|
||||
const currentSelections = pendingSelections.length > 0 ? pendingSelections : alreadySelected;
|
||||
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="bg-gray-900 border-gray-700 max-w-lg">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-amber-400">
|
||||
Choose Upgrade - {skillDef?.name || skillId}
|
||||
Choose Upgrade - {skillId}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-gray-400">
|
||||
Level {milestone} Milestone - Select 2 upgrades ({currentSelections.length}/2 chosen)
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
|
||||
<div className="space-y-2 mt-4">
|
||||
{available.map((upgrade) => {
|
||||
const isSelected = currentSelections.includes(upgrade.id);
|
||||
const canToggle = currentSelections.length < 2 || isSelected;
|
||||
|
||||
|
||||
return (
|
||||
<div
|
||||
key={upgrade.id}
|
||||
className={`p-3 rounded border cursor-pointer transition-all ${
|
||||
isSelected
|
||||
? 'border-amber-500 bg-amber-900/30'
|
||||
: canToggle
|
||||
? 'border-gray-600 bg-gray-800/50 hover:border-amber-500/50 hover:bg-gray-800'
|
||||
isSelected
|
||||
? 'border-amber-500 bg-amber-900/30'
|
||||
: canToggle
|
||||
? 'border-gray-600 bg-gray-800/50 hover:border-amber-500/50 hover:bg-gray-800'
|
||||
: 'border-gray-700 bg-gray-800/30 opacity-50 cursor-not-allowed'
|
||||
}`}
|
||||
onClick={() => {
|
||||
@@ -93,15 +91,15 @@ export function UpgradeDialog({
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
|
||||
<div className="flex justify-end gap-2 mt-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onCancel}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={onConfirm}
|
||||
disabled={currentSelections.length !== 2}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Label } from '@/components/ui/label';
|
||||
import {
|
||||
RotateCcw, AlertTriangle, Zap, Clock, Settings, Eye,
|
||||
} from 'lucide-react';
|
||||
import { useDebug } from '@/lib/game/debug-context';
|
||||
import { useDebug } from '@/components/game/debug/debug-context';
|
||||
import { useGameStore, useManaStore, useUIStore, useCombatStore } from '@/lib/game/stores';
|
||||
import { computeMaxMana } from '@/lib/game/stores';
|
||||
|
||||
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, useContext, useState, useEffect, type ReactNode } from 'react';
|
||||
|
||||
interface DebugContextType {
|
||||
showComponentNames: boolean;
|
||||
toggleComponentNames: () => void;
|
||||
}
|
||||
|
||||
const DebugContext = createContext<DebugContextType | null>(null);
|
||||
|
||||
export function DebugProvider({ children }: { children: ReactNode }) {
|
||||
// Initialize from localStorage if available
|
||||
const [showComponentNames, setShowComponentNames] = useState(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const saved = localStorage.getItem('debug-show-component-names');
|
||||
return saved === 'true';
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const toggleComponentNames = () => {
|
||||
setShowComponentNames(prev => {
|
||||
const newValue = !prev;
|
||||
localStorage.setItem('debug-show-component-names', String(newValue));
|
||||
return newValue;
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<DebugContext.Provider value={{ showComponentNames, toggleComponentNames }}>
|
||||
{children}
|
||||
</DebugContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useDebug() {
|
||||
const context = useContext(DebugContext);
|
||||
if (!context) {
|
||||
// Return default values if used outside provider
|
||||
return { showComponentNames: false, toggleComponentNames: () => {} };
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
// Wrapper component to show component name in debug mode
|
||||
interface DebugNameProps {
|
||||
name: string;
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export function DebugName({ name, children }: DebugNameProps) {
|
||||
const { showComponentNames } = useDebug();
|
||||
|
||||
if (!showComponentNames) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<div className="absolute -top-5 left-0 text-[10px] font-mono text-yellow-400 bg-yellow-900/50 px-1 rounded z-50">
|
||||
{name}
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
DebugName.displayName = "DebugName";
|
||||
@@ -1,5 +1,4 @@
|
||||
export { GameStateDebug } from './GameStateDebug';
|
||||
export { SkillDebug } from './SkillDebug';
|
||||
export { ElementDebug } from './ElementDebug';
|
||||
export { AttunementDebug } from './AttunementDebug';
|
||||
export { GolemDebug } from './GolemDebug';
|
||||
|
||||
@@ -7,8 +7,6 @@ import { Badge } from '@/components/ui/badge';
|
||||
import { ScrollArea } from '@/components/ui/scroll-area';
|
||||
import { Save, Trash2, Star } from 'lucide-react';
|
||||
import { useGameContext } from '../GameContext';
|
||||
import { SKILLS_DEF } from '@/lib/game/constants';
|
||||
import { getTierMultiplier, getBaseSkillId } from '@/lib/game/skill-evolution';
|
||||
import type { Memory } from '@/lib/game/types';
|
||||
|
||||
interface MemorySlotPickerProps {
|
||||
@@ -22,15 +20,14 @@ export function MemorySlotPicker({ onConfirm }: MemorySlotPickerProps) {
|
||||
// Get all skills that have progress and can be saved
|
||||
const saveableSkills = useMemo(() => {
|
||||
const skills: { skillId: string; level: number; tier: number; upgrades: string[]; name: string }[] = [];
|
||||
|
||||
|
||||
for (const [skillId, level] of Object.entries(store.skills)) {
|
||||
if (level && level > 0) {
|
||||
const baseSkillId = getBaseSkillId(skillId);
|
||||
const baseSkillId = skillId;
|
||||
const tier = store.skillTiers?.[baseSkillId] || 1;
|
||||
const tieredSkillId = tier > 1 ? `${baseSkillId}_t${tier}` : baseSkillId;
|
||||
const upgrades = store.skillUpgrades?.[tieredSkillId] || [];
|
||||
const skillDef = SKILLS_DEF[baseSkillId];
|
||||
|
||||
|
||||
// Only include if it's a base skill (not a tiered variant in the skills object)
|
||||
if (skillId === baseSkillId || skillId.includes('_t')) {
|
||||
// Get the actual skill ID and level
|
||||
@@ -41,13 +38,13 @@ export function MemorySlotPicker({ onConfirm }: MemorySlotPickerProps) {
|
||||
level: actualLevel,
|
||||
tier,
|
||||
upgrades,
|
||||
name: skillDef?.name || baseSkillId,
|
||||
name: baseSkillId,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Remove duplicates and keep highest tier/level
|
||||
const uniqueSkills = new Map<string, typeof skills[0]>();
|
||||
for (const skill of skills) {
|
||||
@@ -56,7 +53,7 @@ export function MemorySlotPicker({ onConfirm }: MemorySlotPickerProps) {
|
||||
uniqueSkills.set(skill.skillId, skill);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Array.from(uniqueSkills.values()).sort((a, b) => {
|
||||
// Sort by tier then level then name
|
||||
if (a.tier !== b.tier) return b.tier - a.tier;
|
||||
@@ -66,12 +63,12 @@ export function MemorySlotPicker({ onConfirm }: MemorySlotPickerProps) {
|
||||
}, [store.skills, store.skillTiers, store.skillUpgrades]);
|
||||
|
||||
const isSkillSelected = (skillId: string) => selectedSkills.some(m => m.skillId === skillId);
|
||||
|
||||
|
||||
const canAddMore = selectedSkills.length < store.memorySlots;
|
||||
|
||||
const toggleSkill = (skillId: string) => {
|
||||
const existingIndex = selectedSkills.findIndex(m => m.skillId === skillId);
|
||||
|
||||
|
||||
if (existingIndex >= 0) {
|
||||
// Remove it
|
||||
setSelectedSkills(selectedSkills.filter((_, i) => i !== existingIndex));
|
||||
@@ -116,22 +113,19 @@ export function MemorySlotPicker({ onConfirm }: MemorySlotPickerProps) {
|
||||
<div className="space-y-1">
|
||||
<div className="text-xs text-green-400 game-panel-title">Saved to Memory:</div>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{selectedSkills.map((memory) => {
|
||||
const skillDef = SKILLS_DEF[memory.skillId];
|
||||
return (
|
||||
<Badge
|
||||
key={memory.skillId}
|
||||
className="bg-amber-900/50 text-amber-200 cursor-pointer hover:bg-red-900/50"
|
||||
onClick={() => toggleSkill(memory.skillId)}
|
||||
>
|
||||
{skillDef?.name || memory.skillId}
|
||||
{' '}Lv.{memory.level}
|
||||
{memory.tier > 1 && ` T${memory.tier}`}
|
||||
{memory.upgrades.length > 0 && ` (${memory.upgrades.length}⭐)`}
|
||||
<Trash2 className="w-3 h-3 ml-1" />
|
||||
</Badge>
|
||||
);
|
||||
})}
|
||||
{selectedSkills.map((memory) => (
|
||||
<Badge
|
||||
key={memory.skillId}
|
||||
className="bg-amber-900/50 text-amber-200 cursor-pointer hover:bg-red-900/50"
|
||||
onClick={() => toggleSkill(memory.skillId)}
|
||||
>
|
||||
{memory.skillId}
|
||||
{' '}Lv.{memory.level}
|
||||
{memory.tier > 1 && ` T${memory.tier}`}
|
||||
{memory.upgrades.length > 0 && ` (${memory.upgrades.length}⭐)`}
|
||||
<Trash2 className="w-3 h-3 ml-1" />
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -147,8 +141,8 @@ export function MemorySlotPicker({ onConfirm }: MemorySlotPickerProps) {
|
||||
) : (
|
||||
saveableSkills.map((skill) => {
|
||||
const isSelected = isSkillSelected(skill.skillId);
|
||||
const tierMult = getTierMultiplier(skill.tier > 1 ? `${skill.skillId}_t${skill.tier}` : skill.skillId);
|
||||
|
||||
const tierMult = 1;
|
||||
|
||||
return (
|
||||
<div
|
||||
key={skill.skillId}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
// ─── Tab Components Barrel ────────────────────────────────────────────────────
|
||||
// Re-exports all existing tab components for lazy loading from page.tsx
|
||||
|
||||
export { DisciplinesTab } from './DisciplinesTab';
|
||||
export { SpellsTab } from '../SpellsTab';
|
||||
export { StatsTab } from '../StatsTab';
|
||||
Reference in New Issue
Block a user