fix: migrate equipment and enchantment state to modular stores, fix EnchantmentDesigner
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m24s

This commit is contained in:
Refactoring Agent
2026-05-05 13:25:19 +02:00
parent 221d3e4b41
commit 3db7e07302
14 changed files with 246 additions and 60 deletions
+1
View File
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const MAX_LINES = 400; const MAX_LINES = 400;
+1
View File
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const { execSync } = require('node:child_process'); const { execSync } = require('node:child_process');
+4 -3
View File
@@ -11,6 +11,7 @@ import {
useSkillStore, useSkillStore,
useCombatStore, useCombatStore,
usePrestigeStore, usePrestigeStore,
useCraftingStore,
fmt, fmt,
computeMaxMana, computeMaxMana,
computeRegen, computeRegen,
@@ -147,9 +148,9 @@ export default function ManaLoopGame() {
const gameOver = useUIStore((s) => s.gameOver); const gameOver = useUIStore((s) => s.gameOver);
// Get equipment state from store // Get equipment state from crafting store
const equippedInstances = useGameStore((s) => s.equippedInstances); const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
// Derived state // Derived state
const upgradeEffects = getUnifiedEffects({ const upgradeEffects = getUnifiedEffects({
@@ -12,7 +12,7 @@ import { ENCHANTMENT_EFFECTS } from '@/lib/game/data/enchantment-effects';
import type { EquipmentInstance, EnchantmentDesign, AppliedEnchantment, LootInventory, EquipmentCraftingProgress, EquipmentSlot } from '@/lib/game/types'; import type { EquipmentInstance, EnchantmentDesign, AppliedEnchantment, LootInventory, EquipmentCraftingProgress, EquipmentSlot } from '@/lib/game/types';
import { fmt } from '@/lib/game/stores'; import { fmt } from '@/lib/game/stores';
import { CheckCircle, Sparkles } from 'lucide-react'; import { CheckCircle, Sparkles } from 'lucide-react';
import { useGameStore } from '@/lib/game/stores'; import { useGameStore, useCraftingStore, useManaStore } from '@/lib/game/stores';
export interface EnchantmentApplierProps { export interface EnchantmentApplierProps {
selectedEquipmentInstance: string | null; selectedEquipmentInstance: string | null;
@@ -31,15 +31,15 @@ export function EnchantmentApplier({
onEnchantmentApplied, onEnchantmentApplied,
onCapacityExceeded, onCapacityExceeded,
}: EnchantmentApplierProps) { }: EnchantmentApplierProps) {
const equippedInstances = useGameStore((s) => s.equippedInstances); const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const enchantmentDesigns = useGameStore((s) => s.enchantmentDesigns); const enchantmentDesigns = useCraftingStore((s) => s.enchantmentDesigns);
const applicationProgress = useGameStore((s) => s.applicationProgress); const applicationProgress = useCraftingStore((s) => s.applicationProgress);
const rawMana = useGameStore((s) => s.rawMana); const rawMana = useManaStore((s) => s.rawMana);
const startApplying = useGameStore((s) => s.startApplying); const startApplying = useCraftingStore((s) => s.startApplying);
const pauseApplication = useGameStore((s) => s.pauseApplication); const pauseApplication = useCraftingStore((s) => s.pauseApplication);
const resumeApplication = useGameStore((s) => s.resumeApplication); const resumeApplication = useCraftingStore((s) => s.resumeApplication);
const cancelApplication = useGameStore((s) => s.cancelApplication); const cancelApplication = useCraftingStore((s) => s.cancelApplication);
// Get equipped items as array - ONLY show items tagged 'Ready for Enchantment' (requirement cr5) // Get equipped items as array - ONLY show items tagged 'Ready for Enchantment' (requirement cr5)
const equippedItems = Object.entries(equippedInstances) const equippedItems = Object.entries(equippedInstances)
@@ -22,7 +22,8 @@ import {
addEffectToDesign, addEffectToDesign,
removeEffectFromDesign, removeEffectFromDesign,
} from './EnchantmentDesigner/utils'; } from './EnchantmentDesigner/utils';
import { useGameStore } from '@/lib/game/stores'; import { useCraftingStore } from '@/lib/game/stores';
import { useSkillStore } from '@/lib/game/stores';
export function EnchantmentDesigner({ export function EnchantmentDesigner({
selectedEquipmentType, selectedEquipmentType,
@@ -34,16 +35,21 @@ export function EnchantmentDesigner({
selectedDesign, selectedDesign,
setSelectedDesign, setSelectedDesign,
}: EnchantmentDesignerProps) { }: EnchantmentDesignerProps) {
const enchantmentDesigns = useGameStore((s) => s.enchantmentDesigns); // Crafting store selectors
const designProgress = useGameStore((s) => s.designProgress); const enchantmentDesigns = useCraftingStore((s) => s.enchantmentDesigns);
const startDesigningEnchantment = useGameStore((s) => s.startDesigningEnchantment); const designProgress = useCraftingStore((s) => s.designProgress);
const cancelDesign = useGameStore((s) => s.cancelDesign); const startDesigningEnchantment = useCraftingStore((s) => s.startDesigningEnchantment);
const deleteDesign = useGameStore((s) => s.deleteDesign); const cancelDesign = useCraftingStore((s) => s.cancelDesign);
const unlockedEffects = useGameStore((s) => s.unlockedEffects); const deleteDesign = useCraftingStore((s) => s.deleteDesign);
const skills = useGameStore((s) => s.skills); const unlockedEffects = useCraftingStore((s) => s.unlockedEffects);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const enchantingLevel = skills.enchanting || 0; // Skill store selectors
const efficiencyBonus = (skills.efficientEnchant || 0) * 0.05; const skills = useSkillStore((s) => s.skills);
const skillUpgrades = useSkillStore((s) => s.skillUpgrades);
const enchantingLevel = skills?.enchanting || 0;
const efficiencyBonus = (skillUpgrades?.['efficientEnchant'] || []).length * 0.05 || 0;
// Calculate total capacity cost for current design // Calculate total capacity cost for current design
const designCapacityCost = calculateDesignCapacityCost(selectedEffects, efficiencyBonus); const designCapacityCost = calculateDesignCapacityCost(selectedEffects, efficiencyBonus);
@@ -84,7 +90,7 @@ export function EnchantmentDesigner({
const incompatibleEffects = getIncompatibleEffects(selectedEquipmentType, unlockedEffects); const incompatibleEffects = getIncompatibleEffects(selectedEquipmentType, unlockedEffects);
// Get equipment types that the player actually owns (has instances of) // Get equipment types that the player actually owns (has instances of)
const ownedEquipmentTypes = getOwnedEquipmentTypes(useGameStore.getState()); const ownedEquipmentTypes = getOwnedEquipmentTypes(equipmentInstances);
// Get the reason why an effect is incompatible // Get the reason why an effect is incompatible
const getIncompatibilityReasonWrapper = (effect: { id: string; name: string; description: string; allowedEquipmentCategories: any[] }) => { const getIncompatibilityReasonWrapper = (effect: { id: string; name: string; description: string; allowedEquipmentCategories: any[] }) => {
@@ -1,8 +1,6 @@
import type { EquipmentInstance, EnchantmentDesign, DesignEffect, EquipmentCraftingProgress, EquipmentCategory } from '@/lib/game/types'; import type { EquipmentInstance, EnchantmentDesign, DesignEffect, EquipmentCraftingProgress, EquipmentCategory } from '@/lib/game/types';
import type { GameStore } from '@/lib/game/stores';
export interface EnchantmentDesignerProps { export interface EnchantmentDesignerProps {
store: GameStore;
selectedEquipmentType: string | null; selectedEquipmentType: string | null;
setSelectedEquipmentType: (type: string | null) => void; setSelectedEquipmentType: (type: string | null) => void;
selectedEffects: DesignEffect[]; selectedEffects: DesignEffect[];
@@ -1,7 +1,6 @@
import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment'; import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment';
import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from '@/lib/game/data/enchantment-effects'; import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from '@/lib/game/data/enchantment-effects';
import type { DesignEffect, EquipmentCategory } from '@/lib/game/types'; import type { DesignEffect, EquipmentInstance, EquipmentCategory } from '@/lib/game/types';
import type { GameStore } from '@/lib/game/stores';
/** /**
* Get available effects for selected equipment type (only unlocked ones) * Get available effects for selected equipment type (only unlocked ones)
@@ -44,12 +43,12 @@ export function getIncompatibleEffects(
* Get equipment types that the player actually owns (has instances of) * Get equipment types that the player actually owns (has instances of)
* This ensures enchantment compatibility is based on owned items, not just blueprints * This ensures enchantment compatibility is based on owned items, not just blueprints
*/ */
export function getOwnedEquipmentTypes(store: GameStore) { export function getOwnedEquipmentTypes(equipmentInstances: Record<string, EquipmentInstance>) {
// Get all unique equipment type IDs from owned instances // Get all unique equipment type IDs from owned instances
const ownedEquipmentTypeIds = new Set<string>(); const ownedEquipmentTypeIds = new Set<string>();
// Check all equipment instances the player owns // Check all equipment instances the player owns
for (const instance of Object.values(store.equipmentInstances || {})) { for (const instance of Object.values(equipmentInstances || {})) {
ownedEquipmentTypeIds.add(instance.typeId); ownedEquipmentTypeIds.add(instance.typeId);
} }
@@ -13,7 +13,7 @@ import { Trash2, CheckCircle, AlertTriangle } from 'lucide-react';
import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment'; import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment';
import type { EquipmentInstance, AppliedEnchantment, LootInventory, EquipmentCraftingProgress, EquipmentSlot } from '@/lib/game/types'; import type { EquipmentInstance, AppliedEnchantment, LootInventory, EquipmentCraftingProgress, EquipmentSlot } from '@/lib/game/types';
import { fmt } from '@/lib/game/stores'; import { fmt } from '@/lib/game/stores';
import { useGameStore } from '@/lib/game/stores'; import { useGameStore, useCraftingStore, useManaStore, useSkillStore } from '@/lib/game/stores';
import { useGameToast } from '@/components/game/GameToast'; import { useGameToast } from '@/components/game/GameToast';
export interface EnchantmentPreparerProps { export interface EnchantmentPreparerProps {
@@ -26,13 +26,13 @@ export function EnchantmentPreparer({
setSelectedEquipmentInstance, setSelectedEquipmentInstance,
}: EnchantmentPreparerProps) { }: EnchantmentPreparerProps) {
const showToast = useGameToast(); const showToast = useGameToast();
const equippedInstances = useGameStore((s) => s.equippedInstances); const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const preparationProgress = useGameStore((s) => s.preparationProgress); const preparationProgress = useCraftingStore((s) => s.preparationProgress);
const rawMana = useGameStore((s) => s.rawMana); const rawMana = useManaStore((s) => s.rawMana);
const skills = useGameStore((s) => s.skills); const skills = useSkillStore((s) => s.skills);
const startPreparing = useGameStore((s) => s.startPreparing); const startPreparing = useCraftingStore((s) => s.startPreparing);
const cancelPreparation = useGameStore((s) => s.cancelPreparation); const cancelPreparation = useCraftingStore((s) => s.cancelPreparation);
// Get equipped items as array // Get equipped items as array
const equippedItems = Object.entries(equippedInstances) const equippedItems = Object.entries(equippedInstances)
+2 -2
View File
@@ -1,12 +1,12 @@
'use client'; 'use client';
import { useGameStore } from '@/lib/game/stores'; import { useGameStore, useCraftingStore } from '@/lib/game/stores';
import { LootInventoryDisplay } from '@/components/game/LootInventory'; import { LootInventoryDisplay } from '@/components/game/LootInventory';
export function LootTab() { export function LootTab() {
const lootInventory = useGameStore((s) => s.lootInventory); const lootInventory = useGameStore((s) => s.lootInventory);
const elements = useGameStore((s) => s.elements); const elements = useGameStore((s) => s.elements);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const deleteMaterial = useGameStore((s) => s.deleteMaterial); const deleteMaterial = useGameStore((s) => s.deleteMaterial);
const deleteEquipmentInstance = useGameStore((s) => s.deleteEquipmentInstance); const deleteEquipmentInstance = useGameStore((s) => s.deleteEquipmentInstance);
+6 -6
View File
@@ -12,7 +12,7 @@ import { getActiveEquipmentSpells, getTotalDPS } from '@/lib/game/computed-stats
import { getUnifiedEffects } from '@/lib/game/effects'; import { getUnifiedEffects } from '@/lib/game/effects';
import { formatSpellCost, getSpellCostColor } from '@/lib/game/formatting'; import { formatSpellCost, getSpellCostColor } from '@/lib/game/formatting';
import { canAffordSpellCost, getFloorElement } from '@/lib/game/stores'; import { canAffordSpellCost, getFloorElement } from '@/lib/game/stores';
import { useGameStore, useManaStore, useSkillStore, useCombatStore, usePrestigeStore } from '@/lib/game/stores'; import { useGameStore, useManaStore, useSkillStore, useCombatStore, usePrestigeStore, useCraftingStore } from '@/lib/game/stores';
import { GOLEMS_DEF, getGolemDamage, getGolemAttackSpeed } from '@/lib/game/data/golems'; import { GOLEMS_DEF, getGolemDamage, getGolemAttackSpeed } from '@/lib/game/data/golems';
// Extracted components // Extracted components
@@ -68,11 +68,11 @@ export function SpireTab({ simpleMode = false }: SpireTabProps) {
const skillTiers = useSkillStore((s) => s.skillTiers); const skillTiers = useSkillStore((s) => s.skillTiers);
const rawMana = useManaStore((s) => s.rawMana); const rawMana = useManaStore((s) => s.rawMana);
const elements = useManaStore((s) => s.elements); const elements = useManaStore((s) => s.elements);
const equippedInstances = useGameStore((s) => s.equippedInstances); const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const designProgress = useGameStore((s) => s.designProgress); const designProgress = useCraftingStore((s) => s.designProgress);
const designProgress2 = useGameStore((s) => s.designProgress2); const designProgress2 = useCraftingStore((s) => s.designProgress2);
const preparationProgress = useGameStore((s) => s.preparationProgress); const preparationProgress = useCraftingStore((s) => s.preparationProgress);
const applicationProgress = useGameStore((s) => s.applicationProgress); const applicationProgress = useGameStore((s) => s.applicationProgress);
const equipmentCraftingProgress = useGameStore((s) => s.equipmentCraftingProgress); const equipmentCraftingProgress = useGameStore((s) => s.equipmentCraftingProgress);
+1 -1
View File
@@ -184,7 +184,7 @@ export function updateEnchanterAttunement(
let newXP = enchanterState.experience + xpGained; let newXP = enchanterState.experience + xpGained;
let newLevel = enchanterState.level; let newLevel = enchanterState.level;
const { getAttunementXPForLevel, MAX_ATTUNEMENT_LEVEL } = require('./data/attunements'); import { getAttunementXPForLevel, MAX_ATTUNEMENT_LEVEL } from './data/attunements.js';
while (newLevel < MAX_ATTUNEMENT_LEVEL) { while (newLevel < MAX_ATTUNEMENT_LEVEL) {
const xpNeeded = getAttunementXPForLevel(newLevel + 1); const xpNeeded = getAttunementXPForLevel(newLevel + 1);
@@ -112,7 +112,7 @@ describe('Combat Calculations', () => {
describe('getFloorMaxHP', () => { describe('getFloorMaxHP', () => {
it('should return guardian HP for guardian floors', () => { it('should return guardian HP for guardian floors', () => {
// Import GUARDIANS from constants // Import GUARDIANS from constants
const { GUARDIANS } = require('../../constants'); import { GUARDIANS } from '../../constants';
expect(getFloorMaxHP(10)).toBe(GUARDIANS[10].hp); expect(getFloorMaxHP(10)).toBe(GUARDIANS[10].hp);
expect(getFloorMaxHP(100)).toBe(GUARDIANS[100].hp); expect(getFloorMaxHP(100)).toBe(GUARDIANS[100].hp);
}); });
+179 -2
View File
@@ -4,7 +4,22 @@
import { create } from 'zustand'; import { create } from 'zustand';
import { persist } from 'zustand/middleware'; import { persist } from 'zustand/middleware';
import type { DesignProgress, PreparationProgress, ApplicationProgress, EquipmentCraftingProgress } from '../types'; import type { DesignProgress, PreparationProgress, ApplicationProgress, EquipmentCraftingProgress, EnchantmentDesign, EquipmentInstance, DesignEffect } from '../types';
// Import crafting modules for action logic
import * as CraftingUtils from '../crafting-utils';
import * as CraftingDesign from '../crafting-design';
import { computeEffects } from '../upgrade-effects';
import { hasSpecial, SPECIAL_EFFECTS } from '../special-effects';
// Import other stores to access required state
import { useSkillStore } from './skillStore';
import { useGameStore } from './gameStore';
// Import action modules
import * as ApplicationActions from '../crafting-actions/application-actions';
import * as CraftingApply from '../crafting-apply';
import * as PreparationActions from '../crafting-actions/preparation-actions';
export interface CraftingState { export interface CraftingState {
// Crafting progress // Crafting progress
@@ -13,6 +28,15 @@ export interface CraftingState {
preparationProgress: PreparationProgress | null; preparationProgress: PreparationProgress | null;
applicationProgress: ApplicationProgress | null; applicationProgress: ApplicationProgress | null;
equipmentCraftingProgress: EquipmentCraftingProgress | null; equipmentCraftingProgress: EquipmentCraftingProgress | null;
// Enchantment designs
enchantmentDesigns: EnchantmentDesign[];
// Unlocked enchantment effects
unlockedEffects: string[];
// Equipment instances (instanceId -> instance)
equipmentInstances: Record<string, EquipmentInstance>;
// Equipped instances (slot -> instanceId or null)
equippedInstances: Record<string, string | null>;
} }
export interface CraftingActions { export interface CraftingActions {
@@ -28,19 +52,39 @@ export interface CraftingActions {
// Actions for equipment crafting progress // Actions for equipment crafting progress
setEquipmentCraftingProgress: (progress: EquipmentCraftingProgress | null) => void; setEquipmentCraftingProgress: (progress: EquipmentCraftingProgress | null) => void;
// Enchantment design actions
startDesigningEnchantment: (name: string, equipmentTypeId: string, effects: DesignEffect[]) => boolean;
cancelDesign: () => void;
saveDesign: (design: EnchantmentDesign) => void;
deleteDesign: (designId: string) => void;
// Enchantment application actions
startApplying: (equipmentInstanceId: string, designId: string) => boolean;
pauseApplication: () => void;
resumeApplication: () => void;
cancelApplication: () => void;
// Enchantment preparation actions
startPreparing: (equipmentInstanceId: string) => boolean;
cancelPreparation: () => void;
} }
export type CraftingStore = CraftingState & CraftingActions; export type CraftingStore = CraftingState & CraftingActions;
export const useCraftingStore = create<CraftingStore>()( export const useCraftingStore = create<CraftingStore>()(
persist( persist(
(set) => ({ (set, get) => ({
// Initial state // Initial state
designProgress: null, designProgress: null,
designProgress2: null, designProgress2: null,
preparationProgress: null, preparationProgress: null,
applicationProgress: null, applicationProgress: null,
equipmentCraftingProgress: null, equipmentCraftingProgress: null,
enchantmentDesigns: [],
unlockedEffects: [],
equipmentInstances: {},
equippedInstances: {},
// Actions // Actions
setDesignProgress: (progress) => set({ designProgress: progress }), setDesignProgress: (progress) => set({ designProgress: progress }),
@@ -48,6 +92,135 @@ export const useCraftingStore = create<CraftingStore>()(
setPreparationProgress: (progress) => set({ preparationProgress: progress }), setPreparationProgress: (progress) => set({ preparationProgress: progress }),
setApplicationProgress: (progress) => set({ applicationProgress: progress }), setApplicationProgress: (progress) => set({ applicationProgress: progress }),
setEquipmentCraftingProgress: (progress) => set({ equipmentCraftingProgress: progress }), setEquipmentCraftingProgress: (progress) => set({ equipmentCraftingProgress: progress }),
// Enchantment design actions
startDesigningEnchantment: (name, equipmentTypeId, effects) => {
// Get state from other stores
const skillState = useSkillStore.getState();
const state = get(); // crafting state
const enchantingLevel = skillState.skills?.enchanting || 0;
const validation = CraftingDesign.validateDesignEffects(effects, equipmentTypeId, enchantingLevel);
if (!validation.valid) return false;
const equipType = CraftingUtils.getEquipmentType(equipmentTypeId);
if (!equipType) return false;
const efficiencyBonus = (skillState.skillUpgrades?.['efficientEnchant'] || []).length * 0.05 || 0;
const totalCapacityCost = CraftingDesign.calculateDesignCapacityCost(effects, efficiencyBonus);
if (totalCapacityCost > equipType.baseCapacity) return false;
const computedEffects = computeEffects(skillState.skillUpgrades || {}, skillState.skillTiers || {});
const hasEnchantMastery = hasSpecial(computedEffects, SPECIAL_EFFECTS.ENCHANT_MASTERY);
let updates: Partial<CraftingState> = {};
if (!state.designProgress) {
updates = {
designProgress: {
designId: CraftingUtils.generateDesignId(),
progress: 0,
required: CraftingDesign.calculateDesignTime(effects),
name,
equipmentType: equipmentTypeId,
effects,
},
};
// Update currentAction in gameStore
useGameStore.setState({ currentAction: 'design' });
} else if (hasEnchantMastery && !state.designProgress2) {
updates = {
designProgress2: {
designId: CraftingUtils.generateDesignId(),
progress: 0,
required: CraftingDesign.calculateDesignTime(effects),
name,
equipmentType: equipmentTypeId,
effects,
},
};
} else {
return false;
}
set(updates);
return true;
},
cancelDesign: () => {
const state = get();
if (state.designProgress2 && !state.designProgress) {
set({ designProgress2: null });
} else {
set({ designProgress: null });
useGameStore.setState({ currentAction: 'meditate' });
}
},
deleteDesign: (designId) => {
set((state) => ({
enchantmentDesigns: state.enchantmentDesigns.filter(d => d.id !== designId),
}));
},
// Enchantment design save
saveDesign: (design) => {
const state = get();
if (state.designProgress2 && state.designProgress2.designId === design.id) {
set((s) => ({
enchantmentDesigns: [...s.enchantmentDesigns, design],
designProgress2: null,
}));
} else {
set((s) => ({
enchantmentDesigns: [...s.enchantmentDesigns, design],
designProgress: null,
currentAction: 'meditate' as const,
}));
}
},
// Enchantment application actions
startApplying: (equipmentInstanceId, designId) => {
return ApplicationActions.startApplying(
equipmentInstanceId,
designId,
get,
set
);
},
pauseApplication: () => {
ApplicationActions.pauseApplication(get, set);
},
resumeApplication: () => {
ApplicationActions.resumeApplication(get, set);
},
cancelApplication: () => {
ApplicationActions.cancelApplication(set);
useGameStore.setState({ currentAction: 'meditate' });
},
// Preparation actions
startPreparing: (equipmentInstanceId) => {
// Get rawMana from manaStore
const rawMana = useManaStore.getState().rawMana;
// Temporary state to pass to preparation action
const tempState = { ...get(), rawMana } as any;
return PreparationActions.startPreparing(
equipmentInstanceId,
() => tempState,
set
);
},
cancelPreparation: () => {
PreparationActions.cancelPreparation(set);
useGameStore.setState({ currentAction: 'meditate' });
},
}), }),
{ {
name: 'mana-loop-crafting', name: 'mana-loop-crafting',
@@ -57,6 +230,10 @@ export const useCraftingStore = create<CraftingStore>()(
preparationProgress: state.preparationProgress, preparationProgress: state.preparationProgress,
applicationProgress: state.applicationProgress, applicationProgress: state.applicationProgress,
equipmentCraftingProgress: state.equipmentCraftingProgress, equipmentCraftingProgress: state.equipmentCraftingProgress,
enchantmentDesigns: state.enchantmentDesigns,
unlockedEffects: state.unlockedEffects,
equipmentInstances: state.equipmentInstances,
equippedInstances: state.equippedInstances,
}), }),
} }
) )
+13 -10
View File
@@ -5,6 +5,7 @@ import { useSkillStore } from './skillStore';
import { usePrestigeStore } from './prestigeStore'; import { usePrestigeStore } from './prestigeStore';
import { useCombatStore } from './combatStore'; import { useCombatStore } from './combatStore';
import { useUIStore } from './uiStore'; import { useUIStore } from './uiStore';
import { useCraftingStore } from './craftingStore';
import { getUnifiedEffects } from '../effects'; import { getUnifiedEffects } from '../effects';
import { import {
computeMaxMana, computeMaxMana,
@@ -32,8 +33,8 @@ export function useGameLoop() {
export function useUnifiedEffects() { export function useUnifiedEffects() {
const skillUpgrades = useSkillStore((s) => s.skillUpgrades); const skillUpgrades = useSkillStore((s) => s.skillUpgrades);
const skillTiers = useSkillStore((s) => s.skillTiers); const skillTiers = useSkillStore((s) => s.skillTiers);
const equippedInstances = useGameStore((s) => s.equippedInstances); const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
return getUnifiedEffects({ return getUnifiedEffects({
skillUpgrades, skillUpgrades,
@@ -54,12 +55,14 @@ export function useManaStats() {
const meditateTicks = useManaStore((s) => s.meditateTicks); const meditateTicks = useManaStore((s) => s.meditateTicks);
const day = useGameStore((s) => s.day); const day = useGameStore((s) => s.day);
const hour = useGameStore((s) => s.hour); const hour = useGameStore((s) => s.hour);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const upgradeEffects = getUnifiedEffects({ const upgradeEffects = getUnifiedEffects({
skillUpgrades, skillUpgrades,
skillTiers, skillTiers,
equippedInstances: {}, equippedInstances,
equipmentInstances: {}, equipmentInstances,
}); });
const maxMana = computeMaxMana( const maxMana = computeMaxMana(
@@ -85,12 +88,12 @@ export function useManaStats() {
// Mana Cascade bonus // Mana Cascade bonus
const manaCascadeBonus = upgradeEffects.specials.has('mana_cascade') const manaCascadeBonus = upgradeEffects.specials.has('mana_cascade')
? Math.floor(maxMana / 100) * 0.1 ? Math.floor(maxMana /100) * 0.1
: 0; : 0;
// Mana Waterfall bonus // Mana Waterfall bonus
const manaWaterfallBonus = upgradeEffects.specials.has('mana_waterfall') const manaWaterfallBonus = upgradeEffects.specials.has('mana_waterfall')
? Math.floor(maxMana / 100) * 0.25 ? Math.floor(maxMana /100) * 0.25
: 0; : 0;
const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus + manaWaterfallBonus) * meditationMultiplier; const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus + manaWaterfallBonus) * meditationMultiplier;
@@ -114,8 +117,8 @@ export function useManaStats() {
export function useCombatStats() { export function useCombatStats() {
const skills = useSkillStore((s) => s.skills); const skills = useSkillStore((s) => s.skills);
const signedPacts = usePrestigeStore((s) => s.signedPacts); const signedPacts = usePrestigeStore((s) => s.signedPacts);
const equippedInstances = useGameStore((s) => s.equippedInstances); const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const skillUpgrades = useSkillStore((s) => s.skillUpgrades); const skillUpgrades = useSkillStore((s) => s.skillUpgrades);
const skillTiers = useSkillStore((s) => s.skillTiers); const skillTiers = useSkillStore((s) => s.skillTiers);
@@ -139,8 +142,8 @@ export function useCombatStats() {
* Get equipment-related derived state * Get equipment-related derived state
*/ */
export function useEquipmentState() { export function useEquipmentState() {
const equippedInstances = useGameStore((s) => s.equippedInstances); const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances); const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const elements = useManaStore((s) => s.elements); const elements = useManaStore((s) => s.elements);
return { return {