fix: add Critical Chance display to Stats tab Combat Stats section
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m2s

This commit is contained in:
2026-06-10 12:55:26 +02:00
parent 62979ea4c7
commit e30962f82f
5 changed files with 37 additions and 5 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
# Circular Dependencies # Circular Dependencies
Generated: 2026-06-10T09:41:41.471Z Generated: 2026-06-10T10:48:36.554Z
Found: 3 circular chain(s) — these MUST be fixed before modifying involved files. Found: 3 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
+4 -2
View File
@@ -1,6 +1,6 @@
{ {
"_meta": { "_meta": {
"generated": "2026-06-10T09:41:39.446Z", "generated": "2026-06-10T10:48:33.838Z",
"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."
}, },
@@ -556,8 +556,10 @@
"utils/index.ts" "utils/index.ts"
], ],
"stores/combat-damage.ts": [ "stores/combat-damage.ts": [
"data/enchantment-effects.ts",
"stores/combat-state.types.ts", "stores/combat-state.types.ts",
"types.ts" "types.ts",
"utils/index.ts"
], ],
"stores/combat-descent-actions.ts": [ "stores/combat-descent-actions.ts": [
"data/guardian-encounters.ts", "data/guardian-encounters.ts",
+2
View File
@@ -37,6 +37,8 @@ export function StatsTab() {
<CombatStatsSection <CombatStatsSection
activeSpellDef={combatStats.activeSpellDef} activeSpellDef={combatStats.activeSpellDef}
pactMultiplier={combatStats.pactMultiplier} pactMultiplier={combatStats.pactMultiplier}
critChance={combatStats.critChance}
critDamage={combatStats.critDamage}
/> />
<PactStatusSection <PactStatusSection
pactMultiplier={combatStats.pactMultiplier} pactMultiplier={combatStats.pactMultiplier}
@@ -9,9 +9,11 @@ import type { SpellDef } from '@/lib/game/types';
interface CombatStatsSectionProps { interface CombatStatsSectionProps {
activeSpellDef: SpellDef | null; activeSpellDef: SpellDef | null;
pactMultiplier: number; pactMultiplier: number;
critChance: number;
critDamage: number;
} }
export function CombatStatsSection({ activeSpellDef, pactMultiplier }: CombatStatsSectionProps) { export function CombatStatsSection({ activeSpellDef, pactMultiplier, critChance, critDamage }: CombatStatsSectionProps) {
return ( return (
<DebugName name="CombatStatsSection"> <DebugName name="CombatStatsSection">
<Card className="bg-[var(--bg-panel)] border-[var(--border-subtle)]"> <Card className="bg-[var(--bg-panel)] border-[var(--border-subtle)]">
@@ -38,9 +40,13 @@ export function CombatStatsSection({ activeSpellDef, pactMultiplier }: CombatSta
</div> </div>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<div className="flex justify-between text-sm">
<span style={{ color: 'var(--text-muted)' }}>Critical Chance:</span>
<span style={{ color: 'var(--mana-light)' }}>{fmtDec(critChance * 100, 1)}%</span>
</div>
<div className="flex justify-between text-sm"> <div className="flex justify-between text-sm">
<span style={{ color: 'var(--text-muted)' }}>Critical Multiplier:</span> <span style={{ color: 'var(--text-muted)' }}>Critical Multiplier:</span>
<span style={{ color: 'var(--mana-light)' }}>1.5x</span> <span style={{ color: 'var(--mana-light)' }}>{fmtDec(critDamage, 2)}x</span>
</div> </div>
</div> </div>
</div> </div>
+22
View File
@@ -17,7 +17,9 @@ import {
getFloorElement, getFloorElement,
calcDamage, calcDamage,
getElementalBonus, getElementalBonus,
getBoonBonuses,
} from '../utils'; } from '../utils';
import { computeEquipmentEffects } from '../effects';
import { computePactMultiplier, computePactInsightMultiplier } from '../utils/pact-utils'; import { computePactMultiplier, computePactInsightMultiplier } from '../utils/pact-utils';
import { ELEMENTS, SPELLS_DEF, getStudySpeedMultiplier, getStudyCostMultiplier, HOURS_PER_TICK, TICK_MS } from '../constants'; import { ELEMENTS, SPELLS_DEF, getStudySpeedMultiplier, getStudyCostMultiplier, HOURS_PER_TICK, TICK_MS } from '../constants';
@@ -120,6 +122,8 @@ export function useCombatStats() {
const currentFloor = useCombatStore((s) => s.currentFloor); const currentFloor = useCombatStore((s) => s.currentFloor);
const activeSpell = useCombatStore((s) => s.activeSpell); const activeSpell = useCombatStore((s) => s.activeSpell);
const { upgradeEffects } = useManaStats(); const { upgradeEffects } = useManaStats();
const equipmentInstances = useGameStore((s) => s.crafting.equipmentInstances);
const equippedInstances = useGameStore((s) => s.crafting.equippedInstances);
const floorElem = useMemo( const floorElem = useMemo(
() => getFloorElement(currentFloor), () => getFloorElement(currentFloor),
@@ -209,6 +213,22 @@ export function useCombatStats() {
}; };
}, [activeSpellDef, signedPacts, activeSpell, floorElem, isGuardianFloor, pactMultiplier]); }, [activeSpellDef, signedPacts, activeSpell, floorElem, isGuardianFloor, pactMultiplier]);
// Crit chance: sum equipment bonus (decimal) + pact boon bonus (percentage points) + upgrade bonus (decimal)
const critChance = useMemo(() => {
const equipEffects = computeEquipmentEffects(equipmentInstances, equippedInstances);
const equipCritBonus = equipEffects.bonuses.critChance || 0;
const boons = getBoonBonuses(signedPacts);
const boonCritChance = boons.critChance / 100; // Convert percentage points to decimal
const upgradeCritBonus = upgradeEffects.critChanceBonus || 0;
return equipCritBonus + boonCritChance + upgradeCritBonus;
}, [equipmentInstances, equippedInstances, signedPacts, upgradeEffects.critChanceBonus]);
// Crit damage: base multiplier (1.5) + pact boon bonus (percentage points)
const critDamage = useMemo(() => {
const boons = getBoonBonuses(signedPacts);
return (upgradeEffects.critDamageMultiplier || 1.5) + boons.critDamage / 100;
}, [signedPacts, upgradeEffects.critDamageMultiplier]);
return { return {
floorElem, floorElem,
floorElemDef, floorElemDef,
@@ -219,6 +239,8 @@ export function useCombatStats() {
pactInsightMultiplier, pactInsightMultiplier,
dps, dps,
damageBreakdown, damageBreakdown,
critChance,
critDamage,
}; };
} }