Phase 4: Study effects (remaining 6)
This commit is contained in:
@@ -157,9 +157,10 @@ export function computeTotalMaxMana(
|
||||
effects?: UnifiedEffects
|
||||
): number {
|
||||
const pu = state.prestigeUpgrades;
|
||||
const skillMult = effects?.skillLevelMultiplier || 1;
|
||||
const base =
|
||||
100 +
|
||||
(state.skills.manaWell || 0) * 100 +
|
||||
(state.skills.manaWell || 0) * 100 * skillMult +
|
||||
(pu.manaWell || 0) * 500;
|
||||
|
||||
if (!effects) {
|
||||
@@ -178,10 +179,11 @@ export function computeTotalRegen(
|
||||
): number {
|
||||
const pu = state.prestigeUpgrades;
|
||||
const temporalBonus = 1 + (pu.temporalEcho || 0) * 0.1;
|
||||
const skillMult = effects?.skillLevelMultiplier || 1;
|
||||
const base =
|
||||
2 +
|
||||
(state.skills.manaFlow || 0) * 1 +
|
||||
(state.skills.manaSpring || 0) * 2 +
|
||||
(state.skills.manaFlow || 0) * 1 * skillMult +
|
||||
(state.skills.manaSpring || 0) * 2 * skillMult +
|
||||
(pu.manaFlow || 0) * 0.5;
|
||||
|
||||
let regen = base * temporalBonus;
|
||||
@@ -202,10 +204,11 @@ export function computeTotalClickMana(
|
||||
state: Pick<GameState, 'skills' | 'skillUpgrades' | 'skillTiers' | 'equipmentInstances' | 'equippedInstances'>,
|
||||
effects?: UnifiedEffects
|
||||
): number {
|
||||
const skillMult = effects?.skillLevelMultiplier || 1;
|
||||
const base =
|
||||
1 +
|
||||
(state.skills.manaTap || 0) * 1 +
|
||||
(state.skills.manaSurge || 0) * 3;
|
||||
(state.skills.manaTap || 0) * 1 * skillMult +
|
||||
(state.skills.manaSurge || 0) * 3 * skillMult;
|
||||
|
||||
if (!effects) {
|
||||
effects = getUnifiedEffects(state as any);
|
||||
|
||||
+32
-9
@@ -302,9 +302,10 @@ export function computeMaxMana(
|
||||
effects?: ComputedEffects | UnifiedEffects
|
||||
): number {
|
||||
const pu = state.prestigeUpgrades;
|
||||
const skillMult = (effects as any)?.skillLevelMultiplier || 1;
|
||||
const base =
|
||||
100 +
|
||||
(state.skills.manaWell || 0) * 100 +
|
||||
(state.skills.manaWell || 0) * 100 * skillMult +
|
||||
(pu.manaWell || 0) * 500;
|
||||
|
||||
// If effects not provided, compute unified effects (includes equipment)
|
||||
@@ -350,10 +351,11 @@ export function computeRegen(
|
||||
): number {
|
||||
const pu = state.prestigeUpgrades;
|
||||
const temporalBonus = 1 + (pu.temporalEcho || 0) * 0.1;
|
||||
const skillMult = (effects as any)?.skillLevelMultiplier || 1;
|
||||
const base =
|
||||
2 +
|
||||
(state.skills.manaFlow || 0) * 1 +
|
||||
(state.skills.manaSpring || 0) * 2 +
|
||||
(state.skills.manaFlow || 0) * 1 * skillMult +
|
||||
(state.skills.manaSpring || 0) * 2 * skillMult +
|
||||
(pu.manaFlow || 0) * 0.5;
|
||||
|
||||
let regen = base * temporalBonus;
|
||||
@@ -399,10 +401,11 @@ export function computeClickMana(
|
||||
state: Pick<GameState, 'skills' | 'skillUpgrades' | 'skillTiers' | 'equipmentInstances' | 'equippedInstances'>,
|
||||
effects?: ComputedEffects | UnifiedEffects
|
||||
): number {
|
||||
const skillMult = (effects as any)?.skillLevelMultiplier || 1;
|
||||
const base =
|
||||
1 +
|
||||
(state.skills.manaTap || 0) * 1 +
|
||||
(state.skills.manaSurge || 0) * 3;
|
||||
(state.skills.manaTap || 0) * 1 * skillMult +
|
||||
(state.skills.manaSurge || 0) * 3 * skillMult;
|
||||
|
||||
// If effects not provided, compute unified effects (includes equipment)
|
||||
if (!effects && state.equipmentInstances && state.equippedInstances) {
|
||||
@@ -437,16 +440,18 @@ function getElementalBonus(spellElem: string, floorElem: string): number {
|
||||
export function calcDamage(
|
||||
state: Pick<GameState, 'skills' | 'signedPacts'>,
|
||||
spellId: string,
|
||||
floorElem?: string
|
||||
floorElem?: string,
|
||||
effects?: ComputedEffects | UnifiedEffects
|
||||
): number {
|
||||
const sp = SPELLS_DEF[spellId];
|
||||
if (!sp) return 5;
|
||||
const skills = state.skills;
|
||||
const baseDmg = sp.dmg + (skills.combatTrain || 0) * 5;
|
||||
const pct = 1 + (skills.arcaneFury || 0) * 0.1;
|
||||
const skillMult = (effects as any)?.skillLevelMultiplier || 1;
|
||||
const baseDmg = sp.dmg + (skills.combatTrain || 0) * 5 * skillMult;
|
||||
const pct = 1 + (skills.arcaneFury || 0) * 0.1 * skillMult;
|
||||
|
||||
// Elemental mastery bonus
|
||||
const elemMasteryBonus = 1 + (skills.elementalMastery || 0) * 0.15;
|
||||
const elemMasteryBonus = 1 + (skills.elementalMastery || 0) * 0.15 * skillMult;
|
||||
|
||||
// Guardian bane bonus
|
||||
const guardianBonus = floorElem && GUARDIANS[Object.values(GUARDIANS).find(g => g.element === floorElem)?.hp ? 0 : 0]
|
||||
@@ -954,6 +959,17 @@ export const useGameStore = create<GameStore>()(
|
||||
// Calculate base study speed
|
||||
let studySpeedMult = getStudySpeedMultiplier(skills);
|
||||
|
||||
// STUDY_RUSH: First hour of study is 2x speed
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.STUDY_RUSH) && consecutiveStudyHours === 0) {
|
||||
studySpeedMult *= 2;
|
||||
log = [`⚡ Study Rush activated! Double speed for the first hour!`, ...log.slice(0, 49)];
|
||||
}
|
||||
|
||||
// MENTAL_CLARITY: +10% study speed when mana > 75%
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.MENTAL_CLARITY) && state.rawMana > maxMana * 0.75) {
|
||||
studySpeedMult *= 1.10;
|
||||
}
|
||||
|
||||
// DEEP_CONCENTRATION: +20% study speed when mana > 90%
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.DEEP_CONCENTRATION) && state.rawMana > maxMana * 0.9) {
|
||||
studySpeedMult *= 1.20;
|
||||
@@ -1009,6 +1025,13 @@ export const useGameStore = create<GameStore>()(
|
||||
skillProgress = { ...skillProgress, [skillId]: 0 };
|
||||
log = [`✅ ${SKILLS_DEF[skillId]?.name} Lv.${newLevel} mastered!`, ...log.slice(0, 49)];
|
||||
|
||||
// STUDY_REFUND: 25% mana back on study complete
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.STUDY_REFUND)) {
|
||||
const refundAmount = Math.floor(currentStudyTarget.totalCost * 0.25);
|
||||
rawMana += refundAmount;
|
||||
log = [`💰 Study Refund: ${refundAmount} mana returned!`, ...log.slice(0, 49)];
|
||||
}
|
||||
|
||||
// Check if this skill unlocks effects (research skills)
|
||||
const effectsToUnlock = EFFECT_RESEARCH_MAPPING[skillId];
|
||||
if (effectsToUnlock && newLevel >= (SKILLS_DEF[skillId]?.max || 1)) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
import type { GameState } from './types';
|
||||
import { SKILLS_DEF, SPELLS_DEF, getStudyCostMultiplier } from './constants';
|
||||
import { computeEffects, hasSpecial, SPECIAL_EFFECTS } from './upgrade-effects';
|
||||
|
||||
// ─── Study Actions Interface ──────────────────────────────────────────────────
|
||||
|
||||
@@ -39,19 +40,37 @@ export function createStudySlice(
|
||||
|
||||
// Calculate total mana cost and cost per hour
|
||||
const costMult = getStudyCostMultiplier(state.skills);
|
||||
const totalCost = Math.floor(sk.base * (currentLevel + 1) * costMult);
|
||||
let totalCost = Math.floor(sk.base * (currentLevel + 1) * costMult);
|
||||
|
||||
// CHAIN_STUDY: -5% cost per maxed skill
|
||||
const effects = computeEffects(state.skillUpgrades || {}, state.skillTiers || {});
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.CHAIN_STUDY)) {
|
||||
const maxedSkills = Object.entries(SKILLS_DEF).filter(([id, sk]) =>
|
||||
(state.skills[id] || 0) >= sk.max
|
||||
).length;
|
||||
const discount = Math.pow(0.95, maxedSkills); // -5% per maxed skill
|
||||
totalCost = Math.floor(totalCost * discount);
|
||||
}
|
||||
|
||||
const manaCostPerHour = Math.ceil(totalCost / sk.studyTime);
|
||||
|
||||
// Must have at least 1 hour worth of mana to start
|
||||
if (state.rawMana < manaCostPerHour) return;
|
||||
|
||||
// KNOWLEDGE_TRANSFER: New skills start at 10% progress
|
||||
let initialProgress = state.skillProgress[skillId] || 0;
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.KNOWLEDGE_TRANSFER) && initialProgress === 0) {
|
||||
initialProgress = sk.studyTime * 0.10; // 10% of required time
|
||||
log = [`📖 Knowledge Transfer: Starting with 10% progress!`, ...state.log.slice(0, 49)];
|
||||
}
|
||||
|
||||
// Start studying (no upfront cost - mana is deducted per hour during study)
|
||||
set({
|
||||
currentAction: 'study',
|
||||
currentStudyTarget: {
|
||||
type: 'skill',
|
||||
id: skillId,
|
||||
progress: state.skillProgress[skillId] || 0,
|
||||
progress: initialProgress,
|
||||
required: sk.studyTime,
|
||||
manaCostPerHour: manaCostPerHour,
|
||||
totalCost: totalCost,
|
||||
@@ -68,7 +87,18 @@ export function createStudySlice(
|
||||
|
||||
// Calculate total mana cost and cost per hour
|
||||
const costMult = getStudyCostMultiplier(state.skills);
|
||||
const totalCost = Math.floor(sp.unlock * costMult);
|
||||
let totalCost = Math.floor(sp.unlock * costMult);
|
||||
|
||||
// CHAIN_STUDY: -5% cost per maxed skill
|
||||
const effects = computeEffects(state.skillUpgrades || {}, state.skillTiers || {});
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.CHAIN_STUDY)) {
|
||||
const maxedSkills = Object.entries(SKILLS_DEF).filter(([id, sk]) =>
|
||||
(state.skills[id] || 0) >= sk.max
|
||||
).length;
|
||||
const discount = Math.pow(0.95, maxedSkills); // -5% per maxed skill
|
||||
totalCost = Math.floor(totalCost * discount);
|
||||
}
|
||||
|
||||
const studyTime = sp.studyTime || (sp.tier * 4);
|
||||
const manaCostPerHour = Math.ceil(totalCost / studyTime);
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ export interface ComputedEffects {
|
||||
|
||||
// All active upgrades for display
|
||||
activeUpgrades: ActiveUpgradeEffect[];
|
||||
|
||||
// DEEP_UNDERSTANDING: +10% bonus from all skill levels
|
||||
skillLevelMultiplier: number;
|
||||
}
|
||||
|
||||
// ─── Special Effect IDs ────────────────────────────────────────────────────────
|
||||
@@ -231,8 +234,14 @@ export function computeEffects(
|
||||
permanentRegenBonus: 0,
|
||||
specials: new Set<string>(),
|
||||
activeUpgrades,
|
||||
skillLevelMultiplier: 1,
|
||||
};
|
||||
|
||||
// Apply DEEP_UNDERSTANDING: +10% bonus from all skill levels
|
||||
if (hasSpecial(effects, SPECIAL_EFFECTS.DEEP_UNDERSTANDING)) {
|
||||
effects.skillLevelMultiplier = 1.10;
|
||||
}
|
||||
|
||||
// Apply each upgrade effect
|
||||
for (const upgrade of activeUpgrades) {
|
||||
const { effect } = upgrade;
|
||||
|
||||
Reference in New Issue
Block a user