Files
Mana-Loop/src/lib/game/effects/dynamic-compute.ts
T
n8n-gitea ef850e98e2
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m23s
refactor: simplify ManaStatsSection props from 17 fields to single stats object
2026-05-26 18:28:24 +02:00

88 lines
2.8 KiB
TypeScript

// ─── Dynamic Computations ──────────────────────────────────────────────────
// Dynamic computation functions that depend on special effects
import type { ComputedEffects } from './upgrade-effects.types';
import { SPECIAL_EFFECTS, hasSpecial } from './special-effects';
// Threshold ratios for mana-dependent effects (currentMana / maxMana)
const MANA_HIGH_THRESHOLD = 0.75;
const MANA_LOW_THRESHOLD = 0.25;
const MANA_CRITICAL_THRESHOLD = 0.1;
// Regen multipliers for mana-dependent thresholds
const MANA_TORRENT_MULTIPLIER = 1.5;
const MANA_CRISIS_MULTIPLIER = 1.5; // Desperate / Despair Wells
const PANIC_RESERVE_MULTIPLIER = 2.0;
const REGEN_BOOST_PER_100_MANA = 0.1;
/**
* Compute regen with special effects that depend on dynamic values
*/
export function computeDynamicRegen(
effects: ComputedEffects,
baseRegen: number,
maxMana: number,
currentMana: number,
incursionStrength: number
): number {
let regen = baseRegen;
// Per-100-max-mana regen bonuses
const manaHundreds = Math.floor(maxMana / 100);
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_CASCADE)) {
regen += manaHundreds * REGEN_BOOST_PER_100_MANA;
}
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_WATERFALL)) {
regen += manaHundreds * 0.25;
}
if (hasSpecial(effects, SPECIAL_EFFECTS.DEEP_RESERVE)) {
regen += manaHundreds * 0.5;
}
// Fractional max-mana regen
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_CORE)) {
regen += maxMana * 0.005;
}
// Mana Tide: sinusoidal pulse
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_TIDE)) {
regen *= (1.0 + 0.5 * Math.sin(Date.now() / 10000));
}
// Mana-ratio-dependent multipliers
const manaRatio = currentMana / maxMana;
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_TORRENT) && manaRatio > MANA_HIGH_THRESHOLD) {
regen *= MANA_TORRENT_MULTIPLIER;
}
if ((hasSpecial(effects, SPECIAL_EFFECTS.DESPERATE_WELLS) || hasSpecial(effects, SPECIAL_EFFECTS.DESPAIR_WELLS)) && manaRatio < MANA_LOW_THRESHOLD) {
regen *= MANA_CRISIS_MULTIPLIER;
}
if (hasSpecial(effects, SPECIAL_EFFECTS.PANIC_RESERVE) && manaRatio < MANA_CRITICAL_THRESHOLD) {
regen *= PANIC_RESERVE_MULTIPLIER;
}
// Eternal Flow: skip incursion + multiplier below
if (hasSpecial(effects, SPECIAL_EFFECTS.ETERNAL_FLOW)) {
return regen * effects.regenMultiplier;
}
// Steady Stream: skip incursion only
if (!hasSpecial(effects, SPECIAL_EFFECTS.STEADY_STREAM)) {
regen *= (1 - incursionStrength);
}
return regen * effects.regenMultiplier;
}
/**
* Compute click mana with special effects
*/
export function computeDynamicClickMana(
effects: ComputedEffects,
baseClickMana: number
): number {
return Math.floor((baseClickMana + effects.clickManaBonus) * effects.clickManaMultiplier);
}