+
+ Critical Chance:
+ {fmtDec(critChance * 100, 1)}%
+
Critical Multiplier:
- 1.5x
+ {fmtDec(critDamage, 2)}x
diff --git a/src/lib/game/hooks/useGameDerived.ts b/src/lib/game/hooks/useGameDerived.ts
index 7e8157a..5d53bc3 100644
--- a/src/lib/game/hooks/useGameDerived.ts
+++ b/src/lib/game/hooks/useGameDerived.ts
@@ -17,7 +17,9 @@ import {
getFloorElement,
calcDamage,
getElementalBonus,
+ getBoonBonuses,
} from '../utils';
+import { computeEquipmentEffects } from '../effects';
import { computePactMultiplier, computePactInsightMultiplier } from '../utils/pact-utils';
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 activeSpell = useCombatStore((s) => s.activeSpell);
const { upgradeEffects } = useManaStats();
+ const equipmentInstances = useGameStore((s) => s.crafting.equipmentInstances);
+ const equippedInstances = useGameStore((s) => s.crafting.equippedInstances);
const floorElem = useMemo(
() => getFloorElement(currentFloor),
@@ -209,6 +213,22 @@ export function useCombatStats() {
};
}, [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 {
floorElem,
floorElemDef,
@@ -219,6 +239,8 @@ export function useCombatStats() {
pactInsightMultiplier,
dps,
damageBreakdown,
+ critChance,
+ critDamage,
};
}