fix: discipline reset on mana depletion and re-activation after stop
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m35s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m35s
- #143: processTick now removes drained disciplines from activeIds and calls onStopPracticing so currentAction resets to 'meditate' - #144: Removed paused guard from canProceedDiscipline so stopped disciplines can be re-activated - Updated test to match new expected behavior for paused disciplines
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Circular Dependencies
|
# Circular Dependencies
|
||||||
Generated: 2026-05-27T08:45:44.894Z
|
Generated: 2026-05-27T09:06:29.331Z
|
||||||
|
|
||||||
No circular dependencies found. ✅
|
No circular dependencies found. ✅
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"generated": "2026-05-27T08:45:43.143Z",
|
"generated": "2026-05-27T09:06:27.471Z",
|
||||||
"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."
|
||||||
},
|
},
|
||||||
@@ -151,6 +151,10 @@
|
|||||||
"types.ts",
|
"types.ts",
|
||||||
"utils/result.ts"
|
"utils/result.ts"
|
||||||
],
|
],
|
||||||
|
"crafting-fabricator.ts": [
|
||||||
|
"data/fabricator-recipes.ts",
|
||||||
|
"types.ts"
|
||||||
|
],
|
||||||
"crafting-loot.ts": [
|
"crafting-loot.ts": [
|
||||||
"data/crafting-recipes.ts",
|
"data/crafting-recipes.ts",
|
||||||
"types.ts"
|
"types.ts"
|
||||||
@@ -464,6 +468,7 @@
|
|||||||
"crafting-actions/preparation-actions.ts",
|
"crafting-actions/preparation-actions.ts",
|
||||||
"crafting-design.ts",
|
"crafting-design.ts",
|
||||||
"crafting-equipment.ts",
|
"crafting-equipment.ts",
|
||||||
|
"crafting-fabricator.ts",
|
||||||
"crafting-utils.ts",
|
"crafting-utils.ts",
|
||||||
"stores/combatStore.ts",
|
"stores/combatStore.ts",
|
||||||
"stores/crafting-initial-state.ts",
|
"stores/crafting-initial-state.ts",
|
||||||
|
|||||||
@@ -230,12 +230,12 @@ describe('canProceedDiscipline', () => {
|
|||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false when discipline is paused', () => {
|
it('should return true when discipline is paused (paused state is handled by activate, not canProceedDiscipline)', () => {
|
||||||
const state: DisciplineState = { id: 'raw-mastery', xp: 0, paused: true };
|
const state: DisciplineState = { id: 'raw-mastery', xp: 0, paused: true };
|
||||||
const result = canProceedDiscipline(rawMastery, state, {
|
const result = canProceedDiscipline(rawMastery, state, {
|
||||||
rawMana: 1000,
|
rawMana: 1000,
|
||||||
});
|
});
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true when raw mana is sufficient', () => {
|
it('should return true when raw mana is sufficient', () => {
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ export const useDisciplineStore = create<DisciplineStore>()(
|
|||||||
const newUnlockedEffects: string[] = [];
|
const newUnlockedEffects: string[] = [];
|
||||||
const newProcessedPerks = [...s.processedPerks];
|
const newProcessedPerks = [...s.processedPerks];
|
||||||
|
|
||||||
|
const drainedIds: string[] = [];
|
||||||
for (const id of s.activeIds) {
|
for (const id of s.activeIds) {
|
||||||
const disc = newDisciplines[id];
|
const disc = newDisciplines[id];
|
||||||
if (!disc) continue;
|
if (!disc) continue;
|
||||||
@@ -168,6 +169,7 @@ export const useDisciplineStore = create<DisciplineStore>()(
|
|||||||
|
|
||||||
if (!available || available < drain) {
|
if (!available || available < drain) {
|
||||||
newDisciplines[id] = { ...disc, paused: true };
|
newDisciplines[id] = { ...disc, paused: true };
|
||||||
|
drainedIds.push(id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,8 +208,15 @@ export const useDisciplineStore = create<DisciplineStore>()(
|
|||||||
MAX_CONCURRENT_DISCIPLINES + 3
|
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) {
|
||||||
|
get().practicingCallbacks?.onStopPracticing?.();
|
||||||
|
}
|
||||||
|
|
||||||
set({
|
set({
|
||||||
disciplines: newDisciplines,
|
disciplines: newDisciplines,
|
||||||
|
activeIds: newActiveIds,
|
||||||
totalXP: newXP,
|
totalXP: newXP,
|
||||||
concurrentLimit: Math.max(s.concurrentLimit, newLimit),
|
concurrentLimit: Math.max(s.concurrentLimit, newLimit),
|
||||||
processedPerks: newProcessedPerks,
|
processedPerks: newProcessedPerks,
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ export function canProceedDiscipline(
|
|||||||
gameState?: { elements?: Record<string, any>; rawMana?: number }
|
gameState?: { elements?: Record<string, any>; rawMana?: number }
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!disciplineState) return true;
|
if (!disciplineState) return true;
|
||||||
if (disciplineState.paused) return false;
|
|
||||||
|
|
||||||
// If no game state provided, allow activation (optimistic)
|
// If no game state provided, allow activation (optimistic)
|
||||||
if (!gameState) return true;
|
if (!gameState) return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user