Phase 4: Mana Well effects (remaining 7)
This commit is contained in:
+25
-4
@@ -563,6 +563,7 @@ function makeInitial(overrides: Partial<GameState> = {}): GameState {
|
|||||||
const pu = overrides.prestigeUpgrades || {};
|
const pu = overrides.prestigeUpgrades || {};
|
||||||
const startFloor = 1 + (pu.spireKey || 0) * 2;
|
const startFloor = 1 + (pu.spireKey || 0) * 2;
|
||||||
const elemMax = computeElementMax({ skills: overrides.skills || {}, prestigeUpgrades: pu });
|
const elemMax = computeElementMax({ skills: overrides.skills || {}, prestigeUpgrades: pu });
|
||||||
|
const manaHeartBonus = overrides.manaHeartBonus || 0;
|
||||||
|
|
||||||
const elements: Record<string, { current: number; max: number; unlocked: boolean }> = {};
|
const elements: Record<string, { current: number; max: number; unlocked: boolean }> = {};
|
||||||
Object.keys(ELEMENTS).forEach((k) => {
|
Object.keys(ELEMENTS).forEach((k) => {
|
||||||
@@ -732,6 +733,9 @@ 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.'],
|
log: ['✨ The loop begins. You start with a Basic Staff (Mana Bolt) and civilian clothes. Gather your strength, mage.'],
|
||||||
loopInsight: 0,
|
loopInsight: 0,
|
||||||
flowSurgeEndTime: 0, // Hour timestamp for FLOW_SURGE effect (0 = inactive)
|
flowSurgeEndTime: 0, // Hour timestamp for FLOW_SURGE effect (0 = inactive)
|
||||||
|
|
||||||
|
// Mana Well Effects (Phase 4)
|
||||||
|
manaHeartBonus: manaHeartBonus, // Cumulative +10% max mana per loop from MANA_HEART
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,10 +887,19 @@ export const useGameStore = create<GameStore>()(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mana regeneration with MANA_OVERFLOW support
|
// Mana regeneration with MANA_OVERFLOW and VOID_STORAGE support
|
||||||
const overflowMultiplier = hasSpecial(effects, SPECIAL_EFFECTS.MANA_OVERFLOW) ? 1.2 : 1.0;
|
const overflowMultiplier = hasSpecial(effects, SPECIAL_EFFECTS.MANA_OVERFLOW) ? 1.2 : 1.0;
|
||||||
const maxManaWithOverflow = maxMana * overflowMultiplier;
|
const hasVoidStorage = hasSpecial(effects, SPECIAL_EFFECTS.VOID_STORAGE);
|
||||||
let rawMana = Math.min(state.rawMana + effectiveRegen * HOURS_PER_TICK, maxManaWithOverflow);
|
const voidStorageMultiplier = hasVoidStorage ? 1.5 : 1.0; // VOID_STORAGE: Store 150% max
|
||||||
|
const maxManaStorage = maxMana * overflowMultiplier * voidStorageMultiplier;
|
||||||
|
|
||||||
|
// MANA_GENESIS: Generate 1% of max mana per hour passively
|
||||||
|
let manaGenesisBonus = 0;
|
||||||
|
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_GENESIS)) {
|
||||||
|
manaGenesisBonus = maxMana * 0.01 * HOURS_PER_TICK;
|
||||||
|
}
|
||||||
|
|
||||||
|
let rawMana = Math.min(state.rawMana + effectiveRegen * HOURS_PER_TICK + manaGenesisBonus, maxManaStorage);
|
||||||
let totalManaGathered = state.totalManaGathered;
|
let totalManaGathered = state.totalManaGathered;
|
||||||
|
|
||||||
// Attunement mana conversion - convert raw mana to attunement's primary mana type
|
// Attunement mana conversion - convert raw mana to attunement's primary mana type
|
||||||
@@ -1706,12 +1719,19 @@ 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
|
// Compute effects for special checks
|
||||||
const effects = computeEffects(state.skillUpgrades || {}, state.skillTiers || {});
|
const effects = computeEffects(state.skillUpgrades || {}, state.skillTiers || {});
|
||||||
|
|
||||||
|
// EMERGENCY_RESERVE: Keep 10% mana on new loop
|
||||||
const hasEmergencyReserve = hasSpecial(effects, SPECIAL_EFFECTS.EMERGENCY_RESERVE);
|
const hasEmergencyReserve = hasSpecial(effects, SPECIAL_EFFECTS.EMERGENCY_RESERVE);
|
||||||
const maxMana = computeMaxMana(state, effects);
|
const maxMana = computeMaxMana(state, effects);
|
||||||
const keepMana = hasEmergencyReserve ? Math.floor(maxMana * 0.10) : 0;
|
const keepMana = hasEmergencyReserve ? Math.floor(maxMana * 0.10) : 0;
|
||||||
|
|
||||||
|
// MANA_HEART: +10% max mana per loop (permanent bonus, compounds)
|
||||||
|
const hasManaHeart = hasSpecial(effects, SPECIAL_EFFECTS.MANA_HEART);
|
||||||
|
const currentHeartBonus = state.manaHeartBonus || 0;
|
||||||
|
const newHeartBonus = hasManaHeart ? currentHeartBonus + 0.10 : currentHeartBonus;
|
||||||
|
|
||||||
const newState = makeInitial({
|
const newState = makeInitial({
|
||||||
loopCount: state.loopCount + 1,
|
loopCount: state.loopCount + 1,
|
||||||
insight: total,
|
insight: total,
|
||||||
@@ -1719,6 +1739,7 @@ export const useGameStore = create<GameStore>()(
|
|||||||
prestigeUpgrades: state.prestigeUpgrades,
|
prestigeUpgrades: state.prestigeUpgrades,
|
||||||
memories: state.memories,
|
memories: state.memories,
|
||||||
skills: state.skills, // Keep skills through temporal memory for now
|
skills: state.skills, // Keep skills through temporal memory for now
|
||||||
|
manaHeartBonus: newHeartBonus,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the kept mana from EMERGENCY_RESERVE
|
// Set the kept mana from EMERGENCY_RESERVE
|
||||||
|
|||||||
@@ -19,12 +19,13 @@ export function getEffectiveSkillLevel(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function computeMaxMana(
|
export function computeMaxMana(
|
||||||
state: Pick<GameState, 'skills' | 'prestigeUpgrades' | 'skillUpgrades' | 'skillTiers'>,
|
state: Pick<GameState, 'skills' | 'prestigeUpgrades' | 'skillUpgrades' | 'skillTiers' | 'manaHeartBonus'>,
|
||||||
effects?: ReturnType<typeof computeEffects>
|
effects?: ReturnType<typeof computeEffects>
|
||||||
): number {
|
): number {
|
||||||
const pu = state.prestigeUpgrades;
|
const pu = state.prestigeUpgrades;
|
||||||
const skillTiers = state.skillTiers || {};
|
const skillTiers = state.skillTiers || {};
|
||||||
const skillUpgrades = state.skillUpgrades || {};
|
const skillUpgrades = state.skillUpgrades || {};
|
||||||
|
const manaHeartBonus = state.manaHeartBonus || 0;
|
||||||
|
|
||||||
const manaWellLevel = getEffectiveSkillLevel(state.skills, 'manaWell', skillTiers);
|
const manaWellLevel = getEffectiveSkillLevel(state.skills, 'manaWell', skillTiers);
|
||||||
|
|
||||||
@@ -34,7 +35,9 @@ export function computeMaxMana(
|
|||||||
(pu.manaWell || 0) * 500;
|
(pu.manaWell || 0) * 500;
|
||||||
|
|
||||||
const computedEffects = effects ?? computeEffects(skillUpgrades, skillTiers);
|
const computedEffects = effects ?? computeEffects(skillUpgrades, skillTiers);
|
||||||
return Math.floor((base + computedEffects.maxManaBonus) * computedEffects.maxManaMultiplier);
|
// Apply MANA_HEART bonus (+10% per loop, compounds)
|
||||||
|
const heartMultiplier = 1 + manaHeartBonus;
|
||||||
|
return Math.floor((base + computedEffects.maxManaBonus) * computedEffects.maxManaMultiplier * heartMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computeElementMax(
|
export function computeElementMax(
|
||||||
|
|||||||
@@ -192,6 +192,9 @@ export interface GameState {
|
|||||||
memorySlots: number;
|
memorySlots: number;
|
||||||
memories: string[];
|
memories: string[];
|
||||||
|
|
||||||
|
// Mana Well Effects (Phase 4)
|
||||||
|
manaHeartBonus: number; // Cumulative +10% max mana per loop from MANA_HEART
|
||||||
|
|
||||||
// Incursion
|
// Incursion
|
||||||
incursionStrength: number;
|
incursionStrength: number;
|
||||||
containmentWards: number;
|
containmentWards: number;
|
||||||
|
|||||||
@@ -363,6 +363,22 @@ export function computeDynamicRegen(
|
|||||||
regen *= 2.0;
|
regen *= 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deep Reserve: +0.5 regen per 100 max mana
|
||||||
|
if (hasSpecial(effects, SPECIAL_EFFECTS.DEEP_RESERVE)) {
|
||||||
|
regen += Math.floor(maxMana / 100) * 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mana Core: 0.5% of max mana added as regen
|
||||||
|
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_CORE)) {
|
||||||
|
regen += maxMana * 0.005;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mana Tide: Regen pulses ±50% (sinusoidal based on time)
|
||||||
|
if (hasSpecial(effects, SPECIAL_EFFECTS.MANA_TIDE)) {
|
||||||
|
const pulseFactor = 0.5 + 0.5 * Math.sin(Date.now() / 10000); // 10 second cycles
|
||||||
|
regen *= (0.5 + pulseFactor * 0.5); // Range: 0.5x to 1.0x
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
@@ -392,6 +408,12 @@ export function computeDynamicClickMana(
|
|||||||
// Note: The chance is handled in the click handler, this just returns the base
|
// Note: The chance is handled in the click handler, this just returns the base
|
||||||
// The click handler should check hasSpecial and apply the 10% chance
|
// The click handler should check hasSpecial and apply the 10% chance
|
||||||
|
|
||||||
|
// Mana Genesis: Generate 1% of max mana per hour passively
|
||||||
|
// This is handled in the game loop (store.ts), not here
|
||||||
|
|
||||||
|
// Mana Heart: +10% max mana per loop (permanent)
|
||||||
|
// This is applied during loop reset in store.ts
|
||||||
|
|
||||||
return Math.floor((clickMana + effects.clickManaBonus) * effects.clickManaMultiplier);
|
return Math.floor((clickMana + effects.clickManaBonus) * effects.clickManaMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user