fix: mana conversion attunement rate now uses flat base + linear multiplier per 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
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# Circular Dependencies
|
# Circular Dependencies
|
||||||
Generated: 2026-06-07T14:14:38.464Z
|
Generated: 2026-06-07T16:09:18.340Z
|
||||||
|
|
||||||
No circular dependencies found. ✅
|
No circular dependencies found. ✅
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
"generated": "2026-06-07T14:14:36.561Z",
|
"generated": "2026-06-07T16:09:16.437Z",
|
||||||
"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."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { usePrestigeStore, useManaStore, useAttunementStore, useDisciplineStore,
|
|||||||
import { computeDisciplineEffects } from '@/lib/game/effects/discipline-effects';
|
import { computeDisciplineEffects } from '@/lib/game/effects/discipline-effects';
|
||||||
import { computeConversionRates } from '@/lib/game/utils/conversion-rates';
|
import { computeConversionRates } from '@/lib/game/utils/conversion-rates';
|
||||||
import { getGuardianForFloor } from '@/lib/game/data/guardian-encounters';
|
import { getGuardianForFloor } from '@/lib/game/data/guardian-encounters';
|
||||||
import { ATTUNEMENTS_DEF, getAttunementConversionRate } from '@/lib/game/data/attunements';
|
import { ATTUNEMENTS_DEF } from '@/lib/game/data/attunements';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { ElementState } from '@/lib/game/types';
|
import type { ElementState } from '@/lib/game/types';
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ export function ElementStatsSection({ elemMax }: ElementStatsSectionProps) {
|
|||||||
const def = ATTUNEMENTS_DEF[id];
|
const def = ATTUNEMENTS_DEF[id];
|
||||||
if (def?.primaryManaType) {
|
if (def?.primaryManaType) {
|
||||||
grossRegen[def.primaryManaType] = (grossRegen[def.primaryManaType] || 0)
|
grossRegen[def.primaryManaType] = (grossRegen[def.primaryManaType] || 0)
|
||||||
+ getAttunementConversionRate(id, state.level || 1);
|
+ (def.conversionRate || 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const invokerLevel = attunements.invoker?.active ? (attunements.invoker.level || 1) : 0;
|
const invokerLevel = attunements.invoker?.active ? (attunements.invoker.level || 1) : 0;
|
||||||
|
|||||||
@@ -66,13 +66,14 @@ describe('Attunement Mana Type Unlocking', () => {
|
|||||||
const enchanter = ATTUNEMENTS_DEF['enchanter'];
|
const enchanter = ATTUNEMENTS_DEF['enchanter'];
|
||||||
expect(enchanter.conversionRate).toBeGreaterThan(0);
|
expect(enchanter.conversionRate).toBeGreaterThan(0);
|
||||||
|
|
||||||
// Get scaled conversion rate at level 1
|
// Base conversion rate is flat (not scaled by level)
|
||||||
|
// Level scaling is applied as a multiplier in computeConversionRates(), not here
|
||||||
const level1Rate = getAttunementConversionRate('enchanter', 1);
|
const level1Rate = getAttunementConversionRate('enchanter', 1);
|
||||||
expect(level1Rate).toBe(enchanter.conversionRate);
|
expect(level1Rate).toBe(enchanter.conversionRate);
|
||||||
|
|
||||||
// Higher level should have higher rate
|
// Flat rate: same at all levels (level multiplier applied separately)
|
||||||
const level5Rate = getAttunementConversionRate('enchanter', 5);
|
const level5Rate = getAttunementConversionRate('enchanter', 5);
|
||||||
expect(level5Rate).toBeGreaterThan(level1Rate);
|
expect(level5Rate).toBe(level1Rate);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have raw mana regen for all attunements', () => {
|
it('should have raw mana regen for all attunements', () => {
|
||||||
|
|||||||
@@ -99,12 +99,13 @@ export function getTotalAttunementRegen(attunements: Record<string, { active: bo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the attunement base conversion rate for a specific attunement.
|
* Get the attunement base conversion rate for a specific attunement.
|
||||||
* This is the base rate contribution to the unified conversion system.
|
* This is the flat base rate contribution to the unified conversion system.
|
||||||
|
* Level scaling is applied as a multiplier in computeConversionRates(), not here.
|
||||||
*/
|
*/
|
||||||
export function getAttunementConversionRate(attunementId: string, level: number): number {
|
export function getAttunementConversionRate(attunementId: string, level: number): number {
|
||||||
const def = ATTUNEMENTS_DEF[attunementId];
|
const def = ATTUNEMENTS_DEF[attunementId];
|
||||||
if (!def || def.conversionRate <= 0) return 0;
|
if (!def || def.conversionRate <= 0) return 0;
|
||||||
return def.conversionRate * Math.pow(1.5, (level || 1) - 1);
|
return def.conversionRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { useCombatStore } from './combatStore';
|
|||||||
import { useAttunementStore } from './attunementStore';
|
import { useAttunementStore } from './attunementStore';
|
||||||
import { useCraftingStore } from './craftingStore';
|
import { useCraftingStore } from './craftingStore';
|
||||||
import { useDisciplineStore } from './discipline-slice';
|
import { useDisciplineStore } from './discipline-slice';
|
||||||
import { ATTUNEMENTS_DEF, getAttunementConversionRate } from '../data/attunements';
|
import { ATTUNEMENTS_DEF } from '../data/attunements';
|
||||||
import { createResetGame, createGatherMana } from './gameActions';
|
import { createResetGame, createGatherMana } from './gameActions';
|
||||||
import { createSafeStorage } from '../utils/safe-persist';
|
import { createSafeStorage } from '../utils/safe-persist';
|
||||||
import { createStartNewLoop } from './gameLoopActions';
|
import { createStartNewLoop } from './gameLoopActions';
|
||||||
@@ -369,7 +369,7 @@ function buildConversionParams(
|
|||||||
const def = ATTUNEMENTS_DEF[id];
|
const def = ATTUNEMENTS_DEF[id];
|
||||||
if (def?.primaryManaType) {
|
if (def?.primaryManaType) {
|
||||||
grossRegen[def.primaryManaType] = (grossRegen[def.primaryManaType] || 0)
|
grossRegen[def.primaryManaType] = (grossRegen[def.primaryManaType] || 0)
|
||||||
+ getAttunementConversionRate(id, state.level || 1);
|
+ (def.conversionRate || 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { pactElementMap, grossRegen };
|
return { pactElementMap, grossRegen };
|
||||||
|
|||||||
Reference in New Issue
Block a user