Phase 4: Mana Flow effects

This commit is contained in:
Refactoring Agent
2026-04-24 15:52:14 +02:00
parent 7d1bfbe4dc
commit 6e3b867e7d
9 changed files with 201 additions and 31 deletions
+11 -1
View File
@@ -63,8 +63,13 @@ export function useManaStats() {
? Math.floor(maxMana / 100) * 0.1
: 0;
// Mana Waterfall bonus
const manaWaterfallBonus = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_WATERFALL)
? Math.floor(maxMana / 100) * 0.25
: 0;
// Final effective regen
const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus) * meditationMultiplier;
const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus + manaWaterfallBonus) * meditationMultiplier;
return {
upgradeEffects,
@@ -75,11 +80,16 @@ export function useManaStats() {
incursionStrength,
effectiveRegenWithSpecials,
manaCascadeBonus,
manaWaterfallBonus,
effectiveRegen,
hasSteadyStream: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.STEADY_STREAM),
hasManaTorrent: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_TORRENT),
hasDesperateWells: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.DESPERATE_WELLS),
hasManaEcho: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_ECHO),
hasManaWaterfall: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_WATERFALL),
hasFlowSurge: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.FLOW_SURGE),
hasManaOverflow: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_OVERFLOW),
hasEternalFlow: hasSpecial(upgradeEffects, SPECIAL_EFFECTS.ETERNAL_FLOW),
};
}
+28 -3
View File
@@ -720,6 +720,7 @@ function makeInitial(overrides: Partial<GameState> = {}): GameState {
log: ['✨ The loop begins. You start with a Basic Staff (Mana Bolt) and civilian clothes. Gather your strength, mage.'],
loopInsight: 0,
flowSurgeEndTime: 0, // Hour timestamp for FLOW_SURGE effect (0 = inactive)
};
}
@@ -857,10 +858,24 @@ export const useGameStore = create<GameStore>()(
}
// Calculate effective regen with incursion and meditation
const effectiveRegen = baseRegen * (1 - incursionStrength) * meditationMultiplier;
let effectiveRegen = baseRegen * (1 - incursionStrength) * meditationMultiplier;
// Mana regeneration
let rawMana = Math.min(state.rawMana + effectiveRegen * HOURS_PER_TICK, maxMana);
// FLOW_SURGE: +100% regen for 1 hour after clicking
let flowSurgeEndTime = state.flowSurgeEndTime;
if (flowSurgeEndTime > 0) {
if (state.hour <= flowSurgeEndTime) {
// FLOW_SURGE is active - double the regen
effectiveRegen *= 2;
} else {
// FLOW_SURGE has expired
flowSurgeEndTime = 0;
}
}
// Mana regeneration with MANA_OVERFLOW support
const overflowMultiplier = hasSpecial(effects, SPECIAL_EFFECTS.MANA_OVERFLOW) ? 1.2 : 1.0;
const maxManaWithOverflow = maxMana * overflowMultiplier;
let rawMana = Math.min(state.rawMana + effectiveRegen * HOURS_PER_TICK, maxManaWithOverflow);
let totalManaGathered = state.totalManaGathered;
// Attunement mana conversion - convert raw mana to attunement's primary mana type
@@ -1405,6 +1420,7 @@ export const useGameStore = create<GameStore>()(
log,
castProgress,
golemancy,
flowSurgeEndTime,
...craftingUpdates,
});
},
@@ -1421,9 +1437,18 @@ export const useGameStore = create<GameStore>()(
cm = Math.floor(cm * overflowBonus);
const max = computeMaxMana(state, effects);
// FLOW_SURGE: Clicks restore 2x regen for 1 hour
let flowSurgeEndTime = state.flowSurgeEndTime;
if (hasSpecial(effects, SPECIAL_EFFECTS.FLOW_SURGE) && flowSurgeEndTime === 0) {
// Activate FLOW_SURGE for 1 hour
flowSurgeEndTime = state.hour + 1;
}
set({
rawMana: Math.min(state.rawMana + cm, max),
totalManaGathered: state.totalManaGathered + cm,
flowSurgeEndTime,
});
},
+1
View File
@@ -105,6 +105,7 @@ export interface GameState {
rawMana: number;
meditateTicks: number;
totalManaGathered: number;
flowSurgeEndTime: number; // Hour timestamp for FLOW_SURGE effect (0 = inactive)
// Attunements (class-like system)
attunements: Record<string, AttunementState>; // attunement id -> state
+10
View File
@@ -336,6 +336,11 @@ export function computeDynamicRegen(
regen += Math.floor(maxMana / 100) * 0.1;
}
// Mana Waterfall: +0.25 regen per 100 max mana (upgraded cascade)
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_WATERFALL)) {
regen += Math.floor(maxMana / 100) * 0.25;
}
// Mana Torrent: +50% regen when above 75% mana
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_TORRENT) && currentMana > maxMana * 0.75) {
regen *= 1.5;
@@ -346,6 +351,11 @@ export function computeDynamicRegen(
regen *= 1.5;
}
// Eternal Flow: Regen immune to ALL penalties (stronger than Steady Stream)
if (hasSpecial(effects, SPECIAL_EFFECTS.ETERNAL_FLOW)) {
return regen * effects.regenMultiplier;
}
// Steady Stream: Regen immune to incursion
if (hasSpecial(effects, SPECIAL_EFFECTS.STEADY_STREAM)) {
return regen * effects.regenMultiplier;