fix: make discipline perk numerical bonuses functional via structured BonusSpec
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m23s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m23s
- Add PerkBonus type and optional bonus field to DisciplinePerk - Populate bonus data on 39 perks across base, elemental, elemental-regen, elemental-regen-advanced, and invoker discipline files - Rewrite computeDisciplineEffects() to apply once/infinite/capped perk bonuses through known stat keys (maxManaBonus, baseDamageBonus, regen_*, elementCap_*) - Add per-element cap bonus routing in effects.ts computeAllEffects() - Remove dead enchantPower bonus (no consumer in effects pipeline)
This commit is contained in:
@@ -5,7 +5,23 @@ import type { DisciplineStoreState } from '../stores/discipline-slice';
|
||||
import type { DisciplineState } from '../types/disciplines';
|
||||
import { useDisciplineStore } from '../stores/discipline-slice';
|
||||
import { ALL_DISCIPLINES } from '../data/disciplines';
|
||||
import { calculateStatBonus, getUnlockedPerks } from '../utils/discipline-math';
|
||||
import {
|
||||
calculateStatBonus,
|
||||
calculatePerkTier,
|
||||
getUnlockedPerks,
|
||||
} from '../utils/discipline-math';
|
||||
|
||||
/**
|
||||
* Known stat keys consumed by computeAllEffects() in effects.ts.
|
||||
* Perk bonuses are routed to these keys so they flow into the unified system.
|
||||
*/
|
||||
const KNOWN_BONUS_STATS = new Set([
|
||||
'maxManaBonus',
|
||||
'regenBonus',
|
||||
'clickManaBonus',
|
||||
'baseDamageBonus',
|
||||
'elementCapBonus',
|
||||
]);
|
||||
|
||||
export function computeDisciplineEffects(_state?: DisciplineStoreState): {
|
||||
bonuses: Record<string, number>;
|
||||
@@ -22,29 +38,50 @@ export function computeDisciplineEffects(_state?: DisciplineStoreState): {
|
||||
const multipliers: Record<string, number> = {};
|
||||
const specials = new Set<string>();
|
||||
|
||||
function addBonus(stat: string, amount: number) {
|
||||
bonuses[stat] = (bonuses[stat] || 0) + amount;
|
||||
}
|
||||
|
||||
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;
|
||||
addBonus(def.statBonus.stat, 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);
|
||||
if (perk.type === 'once') {
|
||||
if (perk.bonus) {
|
||||
addBonus(perk.bonus.stat, perk.bonus.amount);
|
||||
} else if (!perk.unlocksEffects) {
|
||||
// Fallback: qualitative perk with no structured bonus — add as special flag
|
||||
specials.add(perk.id);
|
||||
}
|
||||
// Perks with unlocksEffects are handled by discipline-slice.ts processTick()
|
||||
} else if (perk.type === 'infinite') {
|
||||
if (perk.bonus) {
|
||||
const interval = perk.value;
|
||||
const tier = calculatePerkTier(disc.xp, perk.threshold, interval);
|
||||
if (tier > 0) {
|
||||
addBonus(perk.bonus.stat, tier * perk.bonus.amount);
|
||||
}
|
||||
} else if (!perk.unlocksEffects) {
|
||||
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;
|
||||
if (perk.bonus) {
|
||||
const tier = calculatePerkTier(disc.xp, perk.threshold, perk.value);
|
||||
if (tier > 0) {
|
||||
addBonus(perk.bonus.stat, tier * perk.bonus.amount);
|
||||
}
|
||||
} else if (!perk.unlocksEffects) {
|
||||
specials.add(perk.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { bonuses, multipliers, specials };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user