fix: remove discipline pool-drain model, add conversion stats UI per mana-conversion-spec
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m17s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m17s
DISC-2: Removed old pool-drain model from discipline-slice.ts processTick() - Disciplines no longer drain rawMana or element pools - canProceedDiscipline() no longer checks mana sufficiency - Removed auto-pause on insufficient mana from processTick() - Removed drain display and auto-paused message from DisciplineCard.tsx - Removed auto-paused log from gameStore.ts tick() DISC-4: Audited crafting pipeline — no composite crafting logic remains - craftComposite already removed from manaStore.ts (comment only) - No other composite crafting references found DISC-5: Added collapsible formula reference to Conversion Stats section - Shows unified formula, multipliers, cost formulas, and constraints DISC-6: Added per-element net regen summary line - Shows 'Net Fire Regen: +0.50/hr − 0.15/hr = +0.35/hr' per element DISC-7: Created dedicated 'Conversion Stats' section in Stats tab - Renamed from 'Conversion Breakdown' to dedicated section header DISC-8: Added detailed per-element regen breakdown to ManaDisplay - Each element card now expandable to show produced rate and downstream drains - New ElementRegenBreakdown type and elementRegenBreakdown prop Tests: Updated 4 test files to reflect new no-drain behavior - All 1090 tests pass
This commit is contained in:
@@ -5,7 +5,6 @@ import { createSafeStorage } from '../utils/safe-persist';
|
||||
import type { DisciplineState } from '../types/disciplines';
|
||||
import type { ElementState } from '../types';
|
||||
import {
|
||||
calculateManaDrain,
|
||||
calculateStatBonus,
|
||||
canProceedDiscipline,
|
||||
checkDisciplinePrerequisites,
|
||||
@@ -171,7 +170,7 @@ export const useDisciplineStore = create<DisciplineStore>()(
|
||||
|
||||
processTick(mana) {
|
||||
const s = get();
|
||||
let rawMana = mana.rawMana;
|
||||
const rawMana = mana.rawMana;
|
||||
const elements = { ...mana.elements };
|
||||
let newXP = s.totalXP;
|
||||
const newDisciplines = { ...s.disciplines };
|
||||
@@ -179,8 +178,6 @@ export const useDisciplineStore = create<DisciplineStore>()(
|
||||
const newUnlockedRecipes: string[] = [];
|
||||
const newProcessedPerks = [...(s.processedPerks ?? [])];
|
||||
|
||||
const drainedIds: string[] = [];
|
||||
const drainedNames: string[] = [];
|
||||
for (const id of s.activeIds ?? []) {
|
||||
const disc = newDisciplines[id];
|
||||
if (!disc) continue;
|
||||
@@ -190,26 +187,6 @@ export const useDisciplineStore = create<DisciplineStore>()(
|
||||
const def = DISCIPLINE_MAP[id];
|
||||
if (!def) continue;
|
||||
|
||||
const drain = calculateManaDrain(def.drainBase, disc.xp, def.difficultyFactor);
|
||||
const element = elements[def.manaType];
|
||||
const available = def.manaType === 'raw' ? rawMana : element?.current;
|
||||
|
||||
if (!available || available < drain) {
|
||||
newDisciplines[id] = { ...disc, paused: true, autoPaused: true };
|
||||
drainedIds.push(id);
|
||||
drainedNames.push(def.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (def.manaType === 'raw') {
|
||||
rawMana -= drain;
|
||||
} else if (elements[def.manaType]) {
|
||||
elements[def.manaType] = {
|
||||
...elements[def.manaType],
|
||||
current: elements[def.manaType].current - drain,
|
||||
};
|
||||
}
|
||||
|
||||
const oldXP = disc.xp;
|
||||
// Compute discipline XP bonus directly to avoid circular import
|
||||
let xpBonus = 0;
|
||||
@@ -264,21 +241,21 @@ export const useDisciplineStore = create<DisciplineStore>()(
|
||||
MAX_CONCURRENT_DISCIPLINES + 3
|
||||
);
|
||||
|
||||
// Remove mana-drained disciplines from activeIds so onStopPracticing fires
|
||||
const newActiveIds = (s.activeIds ?? []).filter((aid) => !drainedIds.includes(aid));
|
||||
if (newActiveIds.length === 0 && s.activeIds.length > 0) {
|
||||
// Check if no active disciplines remain to fire onStopPracticing
|
||||
const keepActiveIds = s.activeIds ?? [];
|
||||
if (keepActiveIds.length === 0 && s.activeIds.length > 0) {
|
||||
get().practicingCallbacks?.onStopPracticing?.();
|
||||
}
|
||||
|
||||
set({
|
||||
disciplines: newDisciplines,
|
||||
activeIds: newActiveIds,
|
||||
activeIds: keepActiveIds,
|
||||
totalXP: newXP,
|
||||
concurrentLimit: Math.max(s.concurrentLimit, newLimit),
|
||||
processedPerks: newProcessedPerks,
|
||||
});
|
||||
|
||||
return { rawMana, elements, unlockedEffects: newUnlockedEffects, unlockedRecipes: newUnlockedRecipes, autoPausedNames: drainedNames };
|
||||
return { rawMana, elements, unlockedEffects: newUnlockedEffects, unlockedRecipes: newUnlockedRecipes, autoPausedNames: [] };
|
||||
},
|
||||
}),
|
||||
{ storage: createSafeStorage(), name: 'mana-loop-discipline-store', version: 1, partialize: (state) => ({ disciplines: state.disciplines, activeIds: state.activeIds, concurrentLimit: state.concurrentLimit, totalXP: state.totalXP, processedPerks: state.processedPerks }) }
|
||||
|
||||
Reference in New Issue
Block a user