feat: Implement study special effects
Some checks failed
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m13s

- MENTAL_CLARITY: +10% study speed when mana > 75%
- STUDY_RUSH: First hour of study is 2x speed
- STUDY_MOMENTUM: +5% study speed per consecutive hour (max +50%)
- KNOWLEDGE_ECHO: 10% chance for instant study progress
- STUDY_REFUND: 25% mana back on study completion
- Add tracking for studyStartedAt and consecutiveStudyHours
- Reset tracking when study completes or stops
This commit is contained in:
2026-03-26 13:38:55 +00:00
parent fec3a2b88f
commit 3ce0bea13f

View File

@@ -455,17 +455,65 @@ export const useGameStore = create<GameStore>()(
let spells = state.spells; let spells = state.spells;
let log = state.log; let log = state.log;
let unlockedEffects = state.unlockedEffects; let unlockedEffects = state.unlockedEffects;
let consecutiveStudyHours = state.consecutiveStudyHours || 0;
let studyStartedAt = state.studyStartedAt;
if (state.currentAction === 'study' && currentStudyTarget) { if (state.currentAction === 'study' && currentStudyTarget) {
const studySpeedMult = getStudySpeedMultiplier(skills); // Track when study started (for STUDY_RUSH)
if (studyStartedAt === null) {
studyStartedAt = newTotalTicks;
}
// Calculate study speed with all bonuses
let studySpeedMult = getStudySpeedMultiplier(skills);
// MENTAL_CLARITY: +10% study speed when mana > 75%
if (hasSpecial(effects, SPECIAL_EFFECTS.MENTAL_CLARITY) && state.rawMana >= maxMana * 0.75) {
studySpeedMult *= 1.1;
}
// STUDY_RUSH: First hour of study is 2x speed
const hoursStudied = (newTotalTicks - studyStartedAt) * HOURS_PER_TICK;
if (hasSpecial(effects, SPECIAL_EFFECTS.STUDY_RUSH) && hoursStudied < 1) {
studySpeedMult *= 2;
}
// STUDY_MOMENTUM: +5% study speed per consecutive hour (max +50%)
if (hasSpecial(effects, SPECIAL_EFFECTS.STUDY_MOMENTUM)) {
const momentumBonus = Math.min(0.5, consecutiveStudyHours * 0.05);
studySpeedMult *= 1 + momentumBonus;
}
const progressGain = HOURS_PER_TICK * studySpeedMult; const progressGain = HOURS_PER_TICK * studySpeedMult;
// KNOWLEDGE_ECHO: 10% instant study chance
let instantProgress = 0;
if (hasSpecial(effects, SPECIAL_EFFECTS.KNOWLEDGE_ECHO) && Math.random() < 0.1) {
instantProgress = currentStudyTarget.required - currentStudyTarget.progress;
log = [`⚡ Knowledge Echo! Instant study progress!`, ...log.slice(0, 49)];
}
currentStudyTarget = { currentStudyTarget = {
...currentStudyTarget, ...currentStudyTarget,
progress: currentStudyTarget.progress + progressGain, progress: currentStudyTarget.progress + progressGain + instantProgress,
}; };
// Increment consecutive study hours
consecutiveStudyHours += HOURS_PER_TICK;
// Check if study is complete // Check if study is complete
if (currentStudyTarget.progress >= currentStudyTarget.required) { if (currentStudyTarget.progress >= currentStudyTarget.required) {
// STUDY_REFUND: 25% mana back on study complete
if (hasSpecial(effects, SPECIAL_EFFECTS.STUDY_REFUND) && state.lastStudyCost > 0) {
const refund = Math.floor(state.lastStudyCost * 0.25);
rawMana = Math.min(rawMana + refund, maxMana);
log = [`💰 Study Refund! Recovered ${refund} mana!`, ...log.slice(0, 49)];
}
// Reset study tracking
studyStartedAt = null;
consecutiveStudyHours = 0;
if (currentStudyTarget.type === 'skill') { if (currentStudyTarget.type === 'skill') {
const skillId = currentStudyTarget.id; const skillId = currentStudyTarget.id;
const currentLevel = skills[skillId] || 0; const currentLevel = skills[skillId] || 0;
@@ -501,6 +549,9 @@ export const useGameStore = create<GameStore>()(
} }
currentStudyTarget = null; currentStudyTarget = null;
} }
} else {
// Reset consecutive study hours when not studying
consecutiveStudyHours = 0;
} }
// Convert action - auto convert mana // Convert action - auto convert mana
@@ -922,6 +973,8 @@ export const useGameStore = create<GameStore>()(
totalSpellsCast, totalSpellsCast,
familiars, familiars,
consecutiveHits: state.currentAction === 'climb' ? state.consecutiveHits + hitsThisTick : state.consecutiveHits, consecutiveHits: state.currentAction === 'climb' ? state.consecutiveHits + hitsThisTick : state.consecutiveHits,
consecutiveStudyHours,
studyStartedAt,
...craftingUpdates, ...craftingUpdates,
}); });
}, },