fix: discipline tab NaN display — correct statBonus.baseValue destructuring, rate-aware /sec labels, NaN guards
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m20s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m20s
- Fix root cause: baseValue was undefined (destructured from definition instead of statBonus.baseValue), causing calculateStatBonus to produce NaN - Remove hardcoded /sec suffix from stat bonus display; now detects rate vs flat stats using isRateStat() helper - Fix computePerkCurrentEffect: perks only show /sec for actual rate stats - Add NaN guards in DisciplineCard display layer as safety net - Clean up DisciplinesTab UX (proper summary label, remove unused rawMana)
This commit is contained in:
@@ -16,7 +16,7 @@ import { useManaStore } from '@/lib/game/stores/manaStore';
|
||||
import { usePrestigeStore } from '@/lib/game/stores/prestigeStore';
|
||||
import clsx from 'clsx';
|
||||
import { DebugName } from '@/components/game/debug/debug-context';
|
||||
import { TICKS_PER_SECOND, computePerkCurrentEffect, computeTotalPerkBonusForStat } from './disciplines-utils';
|
||||
import { TICKS_PER_SECOND, computePerkCurrentEffect, computeTotalPerkBonusForStat, isRateStat } from './disciplines-utils';
|
||||
import type { ComputedPerkEffect } from './disciplines-utils';
|
||||
|
||||
// ─── Attunement Tabs ─────────────────────────────────────────────────────────
|
||||
@@ -56,13 +56,14 @@ const DisciplineCard: React.FC<DisciplineCardProps> = ({
|
||||
}) => {
|
||||
const {
|
||||
id, name, description, manaType, perks,
|
||||
statBonus, baseValue, drainBase, difficultyFactor, scalingFactor,
|
||||
statBonus, drainBase, difficultyFactor, scalingFactor,
|
||||
conversionRate, sourceManaTypes,
|
||||
} = definition;
|
||||
|
||||
const displayXp = xp;
|
||||
const progressPercent = Math.min(displayXp / Math.max(1, concurrentLimit * 100), 100);
|
||||
const activeStatBonus = calculateStatBonus(baseValue, displayXp, scalingFactor);
|
||||
// statBonus.baseValue is the correct field — not a top-level baseValue
|
||||
const activeStatBonus = calculateStatBonus(statBonus.baseValue, displayXp, scalingFactor);
|
||||
const drainPerSecond = calculateManaDrain(drainBase, displayXp, difficultyFactor) * TICKS_PER_SECOND;
|
||||
|
||||
const elementDef = ELEMENTS[manaType];
|
||||
@@ -134,14 +135,23 @@ const DisciplineCard: React.FC<DisciplineCardProps> = ({
|
||||
)}
|
||||
|
||||
{/* Stat Bonus with Perk Total */}
|
||||
<div className="mt-2 text-sm">
|
||||
<strong>Stat Bonus:</strong> {activeStatBonus.toFixed(2)}/sec on {statBonusLabel}
|
||||
{perkBonusTotal > 0 && (
|
||||
<span className="text-green-400 ml-1">
|
||||
({statBonusTotal.toFixed(2)}/sec with perks)
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
{(() => {
|
||||
// NaN guard — if the calculation produced NaN, show a safe fallback
|
||||
const safeActive = Number.isFinite(activeStatBonus) ? activeStatBonus : 0;
|
||||
const safePerk = Number.isFinite(perkBonusTotal) ? perkBonusTotal : 0;
|
||||
const safeTotal = Number.isFinite(statBonusTotal) ? statBonusTotal : 0;
|
||||
const rateSuffix = isRateStat(statBonus.stat) ? '/sec' : '';
|
||||
return (
|
||||
<div className="mt-2 text-sm">
|
||||
<strong>Stat Bonus:</strong> {safeActive.toFixed(2)}{rateSuffix} on {statBonusLabel}
|
||||
{safePerk > 0 && (
|
||||
<span className="text-green-400 ml-1">
|
||||
({safeTotal.toFixed(2)}{rateSuffix} with perks)
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
|
||||
{/* Perks */}
|
||||
<div className="mt-2">
|
||||
@@ -207,7 +217,7 @@ export const DisciplinesTab: React.FC = () => {
|
||||
|
||||
const handleToggle = useCallback((id: string, paused: boolean) => {
|
||||
if (paused) {
|
||||
activate(id, { rawMana, elements, signedPacts });
|
||||
activate(id, { elements, signedPacts });
|
||||
} else {
|
||||
deactivate(id);
|
||||
}
|
||||
@@ -261,7 +271,7 @@ export const DisciplinesTab: React.FC = () => {
|
||||
|
||||
{/* Summary */}
|
||||
<div className="mt-4 flex flex-col sm:flex-row gap-2 text-sm text-gray-500">
|
||||
<div>Active Disciple{activeIds.length}{activeIds.length === 1 ? '' : 's'} / {concurrentLimit}</div>
|
||||
<div>Active Disciplines: {activeIds.length} / {concurrentLimit}</div>
|
||||
<div>Concurrent Limit: {concurrentLimit}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user