refactor: resolve structural inconsistencies and dead code
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:
2026-05-18 14:21:59 +02:00
parent 2805f75f5e
commit ca86b6268c
57 changed files with 405 additions and 3726 deletions
+95 -81
View File
@@ -2,8 +2,11 @@
// Custom hooks for computing derived game stats from the store
import { useMemo } from 'react';
import { useGameStore } from '../store';
import { computeEffects } from '../upgrade-effects';
import { useGameStore } from '../stores/gameStore';
import { useManaStore } from '../stores/manaStore';
import { useCombatStore } from '../stores/combatStore';
import { usePrestigeStore } from '../stores/prestigeStore';
import { computeEffects } from '../effects/upgrade-effects';
import {
computeMaxMana,
computeRegen,
@@ -12,65 +15,71 @@ import {
getIncursionStrength,
getFloorElement,
calcDamage,
computePactMultiplier,
computePactInsightMultiplier,
getElementalBonus,
} from '../store/computed';
} from '../utils';
import { computePactMultiplier, computePactInsightMultiplier } from '../utils/pact-utils';
import { ELEMENTS, GUARDIANS, SPELLS_DEF, getStudySpeedMultiplier, getStudyCostMultiplier, HOURS_PER_TICK, TICK_MS } from '../constants';
import { hasSpecial, SPECIAL_EFFECTS } from '../special-effects';
import { hasSpecial, SPECIAL_EFFECTS } from '../effects/special-effects';
/**
* Hook for all mana-related derived stats
*/
export function useManaStats() {
const store = useGameStore();
const skills = useGameStore((s) => s.skills);
const skillUpgrades = useGameStore((s) => s.skillUpgrades);
const skillTiers = useGameStore((s) => s.skillTiers);
const prestigeUpgrades = usePrestigeStore((s) => s.prestigeUpgrades);
const rawMana = useManaStore((s) => s.rawMana);
const meditateTicks = useManaStore((s) => s.meditateTicks);
const day = useGameStore((s) => s.day);
const hour = useGameStore((s) => s.hour);
const upgradeEffects = useMemo(
() => computeEffects(store.skillUpgrades || {}, store.skillTiers || {}),
[store.skillUpgrades, store.skillTiers]
() => computeEffects(skillUpgrades || {}, skillTiers || {}),
[skillUpgrades, skillTiers]
);
const maxMana = useMemo(
() => computeMaxMana(store, upgradeEffects),
[store, upgradeEffects]
() => computeMaxMana({ skills, prestigeUpgrades, skillUpgrades, skillTiers }, upgradeEffects),
[skills, prestigeUpgrades, skillUpgrades, skillTiers, upgradeEffects]
);
const baseRegen = useMemo(
() => computeRegen(store, upgradeEffects),
[store, upgradeEffects]
() => computeRegen({ skills, prestigeUpgrades, skillUpgrades, skillTiers }, upgradeEffects),
[skills, prestigeUpgrades, skillUpgrades, skillTiers, upgradeEffects]
);
const clickMana = useMemo(
() => computeClickMana(store),
[store]
() => computeClickMana({ skills }),
[skills]
);
const meditationMultiplier = useMemo(
() => getMeditationBonus(store.meditateTicks, store.skills, upgradeEffects.meditationEfficiency),
[store.meditateTicks, store.skills, upgradeEffects.meditationEfficiency]
() => getMeditationBonus(meditateTicks, skills, upgradeEffects.meditationEfficiency),
[meditateTicks, skills, upgradeEffects.meditationEfficiency]
);
const incursionStrength = useMemo(
() => getIncursionStrength(store.day, store.hour),
[store.day, store.hour]
() => getIncursionStrength(day, hour),
[day, hour]
);
// Effective regen with incursion penalty
const effectiveRegenWithSpecials = baseRegen * (1 - incursionStrength);
// Mana Cascade bonus
const manaCascadeBonus = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_CASCADE)
? Math.floor(maxMana / 100) * 0.1
: 0;
// Mana Waterfall bonus
const manaWaterfallBonus = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_WATERFALL)
? Math.floor(maxMana / 100) * 0.25
: 0;
// Final effective regen
const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus + manaWaterfallBonus) * meditationMultiplier;
return {
upgradeEffects,
maxMana,
@@ -97,70 +106,73 @@ export function useManaStats() {
* Hook for combat-related derived stats
*/
export function useCombatStats() {
const store = useGameStore();
const skills = useGameStore((s) => s.skills);
const signedPacts = usePrestigeStore((s) => s.signedPacts);
const currentFloor = useCombatStore((s) => s.currentFloor);
const activeSpell = useCombatStore((s) => s.activeSpell);
const { upgradeEffects } = useManaStats();
const floorElem = useMemo(
() => getFloorElement(store.currentFloor),
[store.currentFloor]
() => getFloorElement(currentFloor),
[currentFloor]
);
const floorElemDef = useMemo(
() => ELEMENTS[floorElem],
[floorElem]
);
const isGuardianFloor = useMemo(
() => !!GUARDIANS[store.currentFloor],
[store.currentFloor]
() => !!GUARDIANS[currentFloor],
[currentFloor]
);
const currentGuardian = useMemo(
() => GUARDIANS[store.currentFloor],
[store.currentFloor]
() => GUARDIANS[currentFloor],
[currentFloor]
);
const activeSpellDef = useMemo(
() => SPELLS_DEF[store.activeSpell],
[store.activeSpell]
() => SPELLS_DEF[activeSpell],
[activeSpell]
);
const pactMultiplier = useMemo(
() => computePactMultiplier(store),
[store]
() => computePactMultiplier({ signedPacts }),
[signedPacts]
);
const pactInsightMultiplier = useMemo(
() => computePactInsightMultiplier(store),
[store]
() => computePactInsightMultiplier({ signedPacts }),
[signedPacts]
);
// DPS calculation
const dps = useMemo(() => {
if (!activeSpellDef) return 0;
const spellCastSpeed = activeSpellDef.castSpeed || 1;
const quickCastBonus = 1 + (store.skills.quickCast || 0) * 0.05;
const quickCastBonus = 1 + (skills.quickCast || 0) * 0.05;
const attackSpeedMult = upgradeEffects.attackSpeedMultiplier;
const totalCastSpeed = spellCastSpeed * quickCastBonus * attackSpeedMult;
const damagePerCast = calcDamage(store, store.activeSpell, floorElem);
const damagePerCast = calcDamage({ skills, signedPacts }, activeSpell, floorElem);
const castsPerSecond = totalCastSpeed * HOURS_PER_TICK / (TICK_MS / 1000);
return damagePerCast * castsPerSecond;
}, [activeSpellDef, store, floorElem, upgradeEffects.attackSpeedMultiplier]);
}, [activeSpellDef, skills, signedPacts, activeSpell, floorElem, upgradeEffects.attackSpeedMultiplier]);
// Damage breakdown for display
const damageBreakdown = useMemo(() => {
if (!activeSpellDef) return null;
const baseDmg = activeSpellDef.dmg;
const combatTrainBonus = (store.skills.combatTrain || 0) * 5;
const arcaneFuryMult = 1 + (store.skills.arcaneFury || 0) * 0.1;
const elemMasteryMult = 1 + (store.skills.elementalMastery || 0) * 0.15;
const guardianBaneMult = isGuardianFloor ? (1 + (store.skills.guardianBane || 0) * 0.2) : 1;
const precisionChance = (store.skills.precision || 0) * 0.05;
const combatTrainBonus = (skills.combatTrain || 0) * 5;
const arcaneFuryMult = 1 + (skills.arcaneFury || 0) * 0.1;
const elemMasteryMult = 1 + (skills.elementalMastery || 0) * 0.15;
const guardianBaneMult = isGuardianFloor ? (1 + (skills.guardianBane || 0) * 0.2) : 1;
const precisionChance = (skills.precision || 0) * 0.05;
// Calculate elemental bonus
const elemBonus = getElementalBonus(activeSpellDef.elem, floorElem);
let elemBonusText = '';
@@ -171,7 +183,7 @@ export function useCombatStats() {
elemBonusText = '+50% super effective';
}
}
return {
base: baseDmg,
combatTrainBonus,
@@ -182,10 +194,10 @@ export function useCombatStats() {
precisionChance,
elemBonus,
elemBonusText,
total: calcDamage(store, store.activeSpell, floorElem),
total: calcDamage({ skills, signedPacts }, activeSpell, floorElem),
};
}, [activeSpellDef, store, floorElem, isGuardianFloor, pactMultiplier]);
}, [activeSpellDef, skills, signedPacts, activeSpell, floorElem, isGuardianFloor, pactMultiplier]);
return {
floorElem,
floorElemDef,
@@ -203,25 +215,27 @@ export function useCombatStats() {
* Hook for study-related derived stats
*/
export function useStudyStats() {
const store = useGameStore();
const skills = useGameStore((s) => s.skills);
const skillUpgrades = useGameStore((s) => s.skillUpgrades);
const skillTiers = useGameStore((s) => s.skillTiers);
const studySpeedMult = useMemo(
() => getStudySpeedMultiplier(store.skills),
[store.skills]
() => getStudySpeedMultiplier(skills),
[skills]
);
const studyCostMult = useMemo(
() => getStudyCostMultiplier(store.skills),
[store.skills]
() => getStudyCostMultiplier(skills),
[skills]
);
const upgradeEffects = useMemo(
() => computeEffects(store.skillUpgrades || {}, store.skillTiers || {}),
[store.skillUpgrades, store.skillTiers]
() => computeEffects(skillUpgrades || {}, skillTiers || {}),
[skillUpgrades, skillTiers]
);
const effectiveStudySpeedMult = studySpeedMult * upgradeEffects.studySpeedMultiplier;
return {
studySpeedMult,
studyCostMult,