Phase 4: Mana Well effects (1st 7)
This commit is contained in:
+25
-3
@@ -298,7 +298,7 @@ function getEffectiveSkillLevel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function computeMaxMana(
|
export function computeMaxMana(
|
||||||
state: Pick<GameState, 'skills' | 'prestigeUpgrades' | 'skillUpgrades' | 'skillTiers' | 'equipmentInstances' | 'equippedInstances'>,
|
state: Pick<GameState, 'skills' | 'prestigeUpgrades' | 'skillUpgrades' | 'skillTiers' | 'equipmentInstances' | 'equippedInstances' | 'totalManaGathered'>,
|
||||||
effects?: ComputedEffects | UnifiedEffects
|
effects?: ComputedEffects | UnifiedEffects
|
||||||
): number {
|
): number {
|
||||||
const pu = state.prestigeUpgrades;
|
const pu = state.prestigeUpgrades;
|
||||||
@@ -313,10 +313,21 @@ export function computeMaxMana(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply effects if available (now includes equipment bonuses)
|
// Apply effects if available (now includes equipment bonuses)
|
||||||
|
let maxMana: number;
|
||||||
if (effects) {
|
if (effects) {
|
||||||
return Math.floor((base + effects.maxManaBonus) * effects.maxManaMultiplier);
|
maxMana = Math.floor((base + effects.maxManaBonus) * effects.maxManaMultiplier);
|
||||||
|
} else {
|
||||||
|
maxMana = base;
|
||||||
}
|
}
|
||||||
return base;
|
|
||||||
|
// MANA_CONDENSE: +1% max mana per 1000 total mana gathered
|
||||||
|
if (effects && hasSpecial(effects, SPECIAL_EFFECTS.MANA_CONDENSE)) {
|
||||||
|
const totalGathered = state.totalManaGathered || 0;
|
||||||
|
const condensesBonus = Math.floor(totalGathered / 1000);
|
||||||
|
maxMana = Math.floor(maxMana * (1 + condensesBonus * 0.01));
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxMana;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computeElementMax(
|
export function computeElementMax(
|
||||||
@@ -1695,6 +1706,12 @@ export const useGameStore = create<GameStore>()(
|
|||||||
spellsToKeep = learnedSpells.slice(0, state.skills.temporalMemory);
|
spellsToKeep = learnedSpells.slice(0, state.skills.temporalMemory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EMERGENCY_RESERVE: Keep 10% mana on new loop
|
||||||
|
const effects = computeEffects(state.skillUpgrades || {}, state.skillTiers || {});
|
||||||
|
const hasEmergencyReserve = hasSpecial(effects, SPECIAL_EFFECTS.EMERGENCY_RESERVE);
|
||||||
|
const maxMana = computeMaxMana(state, effects);
|
||||||
|
const keepMana = hasEmergencyReserve ? Math.floor(maxMana * 0.10) : 0;
|
||||||
|
|
||||||
const newState = makeInitial({
|
const newState = makeInitial({
|
||||||
loopCount: state.loopCount + 1,
|
loopCount: state.loopCount + 1,
|
||||||
insight: total,
|
insight: total,
|
||||||
@@ -1704,6 +1721,11 @@ export const useGameStore = create<GameStore>()(
|
|||||||
skills: state.skills, // Keep skills through temporal memory for now
|
skills: state.skills, // Keep skills through temporal memory for now
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set the kept mana from EMERGENCY_RESERVE
|
||||||
|
if (keepMana > 0) {
|
||||||
|
newState.rawMana = keepMana;
|
||||||
|
}
|
||||||
|
|
||||||
// Add kept spells
|
// Add kept spells
|
||||||
if (spellsToKeep.length > 0) {
|
if (spellsToKeep.length > 0) {
|
||||||
spellsToKeep.forEach(spellId => {
|
spellsToKeep.forEach(spellId => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { StateCreator } from 'zustand';
|
|||||||
import type { GameState, ElementState, SpellCost } from '../types';
|
import type { GameState, ElementState, SpellCost } from '../types';
|
||||||
import { ELEMENTS, MANA_PER_ELEMENT, BASE_UNLOCKED_ELEMENTS } from '../constants';
|
import { ELEMENTS, MANA_PER_ELEMENT, BASE_UNLOCKED_ELEMENTS } from '../constants';
|
||||||
import { computeMaxMana, computeElementMax, computeClickMana, canAffordSpellCost, getMeditationBonus } from './computed';
|
import { computeMaxMana, computeElementMax, computeClickMana, canAffordSpellCost, getMeditationBonus } from './computed';
|
||||||
import { computeEffects } from '../upgrade-effects';
|
import { computeEffects, hasSpecial, SPECIAL_EFFECTS } from '../upgrade-effects';
|
||||||
|
|
||||||
export interface ManaSlice {
|
export interface ManaSlice {
|
||||||
// State
|
// State
|
||||||
@@ -67,6 +67,11 @@ export const createManaSlice = (
|
|||||||
const effects = computeEffects(state.skillUpgrades || {}, state.skillTiers || {});
|
const effects = computeEffects(state.skillUpgrades || {}, state.skillTiers || {});
|
||||||
const max = computeMaxMana(state, effects);
|
const max = computeMaxMana(state, effects);
|
||||||
|
|
||||||
|
// Mana Conversion: Convert 5% of max mana to click bonus
|
||||||
|
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_CONVERSION)) {
|
||||||
|
cm += Math.floor(max * 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
// Mana Echo: 10% chance to gain double mana from clicks
|
// Mana Echo: 10% chance to gain double mana from clicks
|
||||||
const hasManaEcho = effects.specials?.has('MANA_ECHO') ?? false;
|
const hasManaEcho = effects.specials?.has('MANA_ECHO') ?? false;
|
||||||
if (hasManaEcho && Math.random() < 0.1) {
|
if (hasManaEcho && Math.random() < 0.1) {
|
||||||
|
|||||||
@@ -72,7 +72,8 @@ export const SPECIAL_EFFECTS = {
|
|||||||
ETERNAL_FLOW: 'eternalFlow', // Regen immune to all penalties
|
ETERNAL_FLOW: 'eternalFlow', // Regen immune to all penalties
|
||||||
|
|
||||||
// Mana Well special effects
|
// Mana Well special effects
|
||||||
DESPERATE_WELLS: 'desperateWells', // +50% regen when below 25% mana
|
DESPAIR_WELLS: 'despairWells', // +50% regen when below 25% mana (task name)
|
||||||
|
DESPERATE_WELLS: 'desperateWells', // +50% regen when below 25% mana (legacy name)
|
||||||
MANA_ECHO: 'manaEcho', // 10% chance double mana from clicks
|
MANA_ECHO: 'manaEcho', // 10% chance double mana from clicks
|
||||||
EMERGENCY_RESERVE: 'emergencyReserve', // Keep 10% mana on new loop
|
EMERGENCY_RESERVE: 'emergencyReserve', // Keep 10% mana on new loop
|
||||||
MANA_THRESHOLD: 'manaThreshold', // +30% max mana, -10% regen trade-off
|
MANA_THRESHOLD: 'manaThreshold', // +30% max mana, -10% regen trade-off
|
||||||
@@ -309,6 +310,12 @@ export function computeEffects(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MANA_THRESHOLD: +30% max mana, -10% regen trade-off
|
||||||
|
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_THRESHOLD)) {
|
||||||
|
effects.maxManaMultiplier *= 1.30;
|
||||||
|
effects.regenMultiplier *= 0.90;
|
||||||
|
}
|
||||||
|
|
||||||
return effects;
|
return effects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,11 +353,16 @@ export function computeDynamicRegen(
|
|||||||
regen *= 1.5;
|
regen *= 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desperate Wells: +50% regen when below 25% mana
|
// Desperate Wells / Despair Wells: +50% regen when below 25% mana
|
||||||
if (hasSpecial(effects, SPECIAL_EFFECTS.DESPERATE_WELLS) && currentMana < maxMana * 0.25) {
|
if ((hasSpecial(effects, SPECIAL_EFFECTS.DESPERATE_WELLS) || hasSpecial(effects, SPECIAL_EFFECTS.DESPAIR_WELLS)) && currentMana < maxMana * 0.25) {
|
||||||
regen *= 1.5;
|
regen *= 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Panic Reserve: +100% regen when below 10% mana
|
||||||
|
if (hasSpecial(effects, SPECIAL_EFFECTS.PANIC_RESERVE) && currentMana < maxMana * 0.1) {
|
||||||
|
regen *= 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
// Eternal Flow: Regen immune to ALL penalties (stronger than Steady Stream)
|
// Eternal Flow: Regen immune to ALL penalties (stronger than Steady Stream)
|
||||||
if (hasSpecial(effects, SPECIAL_EFFECTS.ETERNAL_FLOW)) {
|
if (hasSpecial(effects, SPECIAL_EFFECTS.ETERNAL_FLOW)) {
|
||||||
return regen * effects.regenMultiplier;
|
return regen * effects.regenMultiplier;
|
||||||
|
|||||||
Reference in New Issue
Block a user