49 lines
2.3 KiB
TypeScript
49 lines
2.3 KiB
TypeScript
// ─── Discipline Effects ───────────────────────────────────────────────────────
|
|
// Computes bonuses from active disciplines and integrates with the unified effect system
|
|
|
|
import type { GameState } from '../types';
|
|
import { useDisciplineStore } from '../stores/discipline-slice';
|
|
import { ALL_DISCIPLINES } from '../data/disciplines';
|
|
import { calculateStatBonus, getUnlockedPerks } from '../utils/discipline-math';
|
|
|
|
export function computeDisciplineEffects(state: GameState): {
|
|
bonuses: Record<string, number>;
|
|
multipliers: Record<string, number>;
|
|
specials: Set<string>;
|
|
} {
|
|
const { disciplines } = useDisciplineStore.getState();
|
|
const activeDiscs = Object.entries(disciplines)
|
|
.filter(([, disc]) => disc && !disc.paused)
|
|
.map(([id, disc]) => ({ id, disc, def: ALL_DISCIPLINES.find(d => d.id === id) }))
|
|
.filter((entry): entry is { id: string; disc: any; def: NonNullable<typeof ALL_DISCIPLINES[0]> } => !!entry.def);
|
|
|
|
const bonuses: Record<string, number> = {};
|
|
const multipliers: Record<string, number> = {};
|
|
const specials = new Set<string>();
|
|
|
|
for (const { disc, def } of activeDiscs) {
|
|
// Continuous stat bonus
|
|
const statBonus = calculateStatBonus(def.statBonus.baseValue, disc.xp, def.scalingFactor);
|
|
if (def.statBonus.stat) {
|
|
bonuses[def.statBonus.stat] = (bonuses[def.statBonus.stat] || 0) + statBonus;
|
|
}
|
|
|
|
// Perk unlocks
|
|
const perks = getUnlockedPerks(def, disc.xp);
|
|
for (const perk of perks) {
|
|
if (perk.type === 'once' || perk.type === 'infinite') {
|
|
// Once/infinite perks can be treated as additive bonuses or special flags
|
|
// For simplicity, we add them as a special flag; actual effect depends on perk.id
|
|
specials.add(perk.id);
|
|
} else if (perk.type === 'capped') {
|
|
// Capped perks act as multipliers after certain thresholds
|
|
// For now, we treat them as additive to a multiplier stat (example)
|
|
// In a real implementation, each perk would have a specific effect.
|
|
// Here we just add a generic perk multiplier placeholder.
|
|
multipliers[`perk_${perk.id}`] = (multipliers[`perk_${perk.id}`] || 1) + perk.value / 100;
|
|
}
|
|
}
|
|
}
|
|
|
|
return { bonuses, multipliers, specials };
|
|
} |