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
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m2s
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user