fix: pass rawMana to activate() in DisciplinesTab to allow discipline reactivation after stop
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m18s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m18s
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# Circular Dependencies
|
# Circular Dependencies
|
||||||
Generated: 2026-06-08T23:26:23.477Z
|
Generated: 2026-06-09T07:33:46.167Z
|
||||||
Found: 2 circular chain(s) — these MUST be fixed before modifying involved files.
|
Found: 2 circular chain(s) — these MUST be fixed before modifying involved files.
|
||||||
|
|
||||||
1. 1) stores/golem-combat-actions.ts > stores/golem-combat-helpers.ts
|
1. 1) stores/golem-combat-actions.ts > stores/golem-combat-helpers.ts
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"generated": "2026-06-08T23:26:19.136Z",
|
"generated": "2026-06-09T07:33:43.815Z",
|
||||||
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
|
"description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.",
|
||||||
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
|
"usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry."
|
||||||
},
|
},
|
||||||
@@ -144,13 +144,15 @@
|
|||||||
"crafting-actions/design-actions.ts": [
|
"crafting-actions/design-actions.ts": [
|
||||||
"crafting-design.ts",
|
"crafting-design.ts",
|
||||||
"crafting-utils.ts",
|
"crafting-utils.ts",
|
||||||
|
"effects/discipline-effects.ts",
|
||||||
"effects/special-effects.ts",
|
"effects/special-effects.ts",
|
||||||
"effects/upgrade-effects.ts",
|
"effects/upgrade-effects.ts",
|
||||||
"stores/craftingStore.types.ts",
|
"stores/craftingStore.types.ts",
|
||||||
"types.ts"
|
"types.ts"
|
||||||
],
|
],
|
||||||
"crafting-actions/disenchant-actions.ts": [
|
"crafting-actions/disenchant-actions.ts": [
|
||||||
"stores/craftingStore.types.ts"
|
"stores/craftingStore.types.ts",
|
||||||
|
"stores/manaStore.ts"
|
||||||
],
|
],
|
||||||
"crafting-actions/equipment-actions.ts": [
|
"crafting-actions/equipment-actions.ts": [
|
||||||
"crafting-utils.ts",
|
"crafting-utils.ts",
|
||||||
@@ -607,6 +609,7 @@
|
|||||||
"crafting-actions/preparation-actions.ts",
|
"crafting-actions/preparation-actions.ts",
|
||||||
"crafting-design.ts",
|
"crafting-design.ts",
|
||||||
"crafting-utils.ts",
|
"crafting-utils.ts",
|
||||||
|
"effects/discipline-effects.ts",
|
||||||
"stores/combatStore.ts",
|
"stores/combatStore.ts",
|
||||||
"stores/crafting-equipment-tick.ts",
|
"stores/crafting-equipment-tick.ts",
|
||||||
"stores/crafting-initial-state.ts",
|
"stores/crafting-initial-state.ts",
|
||||||
@@ -779,6 +782,7 @@
|
|||||||
"crafting-apply.ts",
|
"crafting-apply.ts",
|
||||||
"crafting-design.ts",
|
"crafting-design.ts",
|
||||||
"crafting-prep.ts",
|
"crafting-prep.ts",
|
||||||
|
"effects/discipline-effects.ts",
|
||||||
"effects/upgrade-effects.types.ts",
|
"effects/upgrade-effects.types.ts",
|
||||||
"stores/craftingStore.ts",
|
"stores/craftingStore.ts",
|
||||||
"stores/tick-pipeline.ts"
|
"stores/tick-pipeline.ts"
|
||||||
|
|||||||
@@ -85,15 +85,16 @@ export const DisciplinesTab: React.FC = () => {
|
|||||||
const [activeAttunement, setActiveAttunement] = useState<string>('base');
|
const [activeAttunement, setActiveAttunement] = useState<string>('base');
|
||||||
|
|
||||||
const elements = useManaStore((s) => s.elements);
|
const elements = useManaStore((s) => s.elements);
|
||||||
|
const rawMana = useManaStore((s) => s.rawMana);
|
||||||
const signedPacts = usePrestigeStore((s) => s.signedPacts);
|
const signedPacts = usePrestigeStore((s) => s.signedPacts);
|
||||||
|
|
||||||
const handleToggle = useCallback((id: string, paused: boolean) => {
|
const handleToggle = useCallback((id: string, paused: boolean) => {
|
||||||
if (paused) {
|
if (paused) {
|
||||||
activate(id, { elements, signedPacts });
|
activate(id, { elements, rawMana, signedPacts });
|
||||||
} else {
|
} else {
|
||||||
deactivate(id);
|
deactivate(id);
|
||||||
}
|
}
|
||||||
}, [activate, deactivate, elements, signedPacts]);
|
}, [activate, deactivate, elements, rawMana, signedPacts]);
|
||||||
|
|
||||||
const activeTab = ATTUNEMENT_TABS.find((t) => t.key === activeAttunement);
|
const activeTab = ATTUNEMENT_TABS.find((t) => t.key === activeAttunement);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function resetDisciplineStore() {
|
|||||||
describe('DisciplineStore — reactivate after deactivate (bug #163)', () => {
|
describe('DisciplineStore — reactivate after deactivate (bug #163)', () => {
|
||||||
beforeEach(resetDisciplineStore);
|
beforeEach(resetDisciplineStore);
|
||||||
|
|
||||||
it('BUG: should reactivate a raw discipline after deactivate (requires rawMana in gameState)', () => {
|
it('should reactivate a raw discipline after deactivate when rawMana is sufficient', () => {
|
||||||
// First activation succeeds because disciplineState is undefined (optimistic)
|
// First activation succeeds because disciplineState is undefined (optimistic)
|
||||||
useDisciplineStore.getState().activate('raw-mastery');
|
useDisciplineStore.getState().activate('raw-mastery');
|
||||||
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
||||||
@@ -25,16 +25,29 @@ describe('DisciplineStore — reactivate after deactivate (bug #163)', () => {
|
|||||||
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
||||||
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true);
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(true);
|
||||||
|
|
||||||
// Reactivate WITHOUT rawMana — reproduces the bug (silently fails)
|
// Reactivate WITH sufficient rawMana — should succeed
|
||||||
useDisciplineStore.getState().activate('raw-mastery', { elements: {}, signedPacts: [] });
|
|
||||||
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery'); // BUG: still inactive
|
|
||||||
|
|
||||||
// Reactivate WITH rawMana — the fix
|
|
||||||
useDisciplineStore.getState().activate('raw-mastery', { rawMana: 1000, elements: {}, signedPacts: [] });
|
useDisciplineStore.getState().activate('raw-mastery', { rawMana: 1000, elements: {}, signedPacts: [] });
|
||||||
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
expect(useDisciplineStore.getState().activeIds).toContain('raw-mastery');
|
||||||
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(false);
|
expect(useDisciplineStore.getState().disciplines['raw-mastery'].paused).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should NOT reactivate a raw discipline when rawMana is insufficient', () => {
|
||||||
|
// Activate and build up XP
|
||||||
|
useDisciplineStore.getState().activate('raw-mastery');
|
||||||
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
||||||
|
useDisciplineStore.getState().processTick({ rawMana: 1000, elements: {} });
|
||||||
|
const xp = useDisciplineStore.getState().disciplines['raw-mastery'].xp;
|
||||||
|
expect(xp).toBeGreaterThan(0);
|
||||||
|
|
||||||
|
// Deactivate
|
||||||
|
useDisciplineStore.getState().deactivate('raw-mastery');
|
||||||
|
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
||||||
|
|
||||||
|
// Reactivate with insufficient rawMana (0) — should fail
|
||||||
|
useDisciplineStore.getState().activate('raw-mastery', { rawMana: 0, elements: {}, signedPacts: [] });
|
||||||
|
expect(useDisciplineStore.getState().activeIds).not.toContain('raw-mastery');
|
||||||
|
});
|
||||||
|
|
||||||
it('should reactivate a discipline with elements after deactivating it', () => {
|
it('should reactivate a discipline with elements after deactivating it', () => {
|
||||||
useDisciplineStore.getState().activate('attune-fire', {
|
useDisciplineStore.getState().activate('attune-fire', {
|
||||||
elements: { fire: { unlocked: true, current: 100, max: 100, baseMax: 100 } },
|
elements: { fire: { unlocked: true, current: 100, max: 100, baseMax: 100 } },
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export interface DisciplineStoreState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DisciplineStoreActions {
|
export interface DisciplineStoreActions {
|
||||||
activate: (id: string, gameState?: { elements?: Record<string, ElementState>; signedPacts?: number[] }) => void;
|
activate: (id: string, gameState?: { elements?: Record<string, ElementState>; rawMana?: number; signedPacts?: number[] }) => void;
|
||||||
deactivate: (id: string) => void;
|
deactivate: (id: string) => void;
|
||||||
processTick: (mana: { rawMana: number; elements: Record<string, ElementState> }) => {
|
processTick: (mana: { rawMana: number; elements: Record<string, ElementState> }) => {
|
||||||
rawMana: number;
|
rawMana: number;
|
||||||
|
|||||||
Reference in New Issue
Block a user