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
@@ -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 { fmt } from '@/lib/game/stores';
import { CheckCircle, Sparkles } from 'lucide-react';
import { useGameStore } from '@/lib/game/stores';
import { useGameStore, useCraftingStore, useManaStore } from '@/lib/game/stores';
export interface EnchantmentApplierProps {
selectedEquipmentInstance: string | null;
@@ -31,15 +31,15 @@ export function EnchantmentApplier({
onEnchantmentApplied,
onCapacityExceeded,
}: EnchantmentApplierProps) {
const equippedInstances = useGameStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances);
const enchantmentDesigns = useGameStore((s) => s.enchantmentDesigns);
const applicationProgress = useGameStore((s) => s.applicationProgress);
const rawMana = useGameStore((s) => s.rawMana);
const startApplying = useGameStore((s) => s.startApplying);
const pauseApplication = useGameStore((s) => s.pauseApplication);
const resumeApplication = useGameStore((s) => s.resumeApplication);
const cancelApplication = useGameStore((s) => s.cancelApplication);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const enchantmentDesigns = useCraftingStore((s) => s.enchantmentDesigns);
const applicationProgress = useCraftingStore((s) => s.applicationProgress);
const rawMana = useManaStore((s) => s.rawMana);
const startApplying = useCraftingStore((s) => s.startApplying);
const pauseApplication = useCraftingStore((s) => s.pauseApplication);
const resumeApplication = useCraftingStore((s) => s.resumeApplication);
const cancelApplication = useCraftingStore((s) => s.cancelApplication);
// Get equipped items as array - ONLY show items tagged 'Ready for Enchantment' (requirement cr5)
const equippedItems = Object.entries(equippedInstances)
@@ -22,7 +22,8 @@ import {
addEffectToDesign,
removeEffectFromDesign,
} from './EnchantmentDesigner/utils';
import { useGameStore } from '@/lib/game/stores';
import { useCraftingStore } from '@/lib/game/stores';
import { useSkillStore } from '@/lib/game/stores';
export function EnchantmentDesigner({
selectedEquipmentType,
@@ -34,16 +35,21 @@ export function EnchantmentDesigner({
selectedDesign,
setSelectedDesign,
}: EnchantmentDesignerProps) {
const enchantmentDesigns = useGameStore((s) => s.enchantmentDesigns);
const designProgress = useGameStore((s) => s.designProgress);
const startDesigningEnchantment = useGameStore((s) => s.startDesigningEnchantment);
const cancelDesign = useGameStore((s) => s.cancelDesign);
const deleteDesign = useGameStore((s) => s.deleteDesign);
const unlockedEffects = useGameStore((s) => s.unlockedEffects);
const skills = useGameStore((s) => s.skills);
// Crafting store selectors
const enchantmentDesigns = useCraftingStore((s) => s.enchantmentDesigns);
const designProgress = useCraftingStore((s) => s.designProgress);
const startDesigningEnchantment = useCraftingStore((s) => s.startDesigningEnchantment);
const cancelDesign = useCraftingStore((s) => s.cancelDesign);
const deleteDesign = useCraftingStore((s) => s.deleteDesign);
const unlockedEffects = useCraftingStore((s) => s.unlockedEffects);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const enchantingLevel = skills.enchanting || 0;
const efficiencyBonus = (skills.efficientEnchant || 0) * 0.05;
// Skill store selectors
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
const designCapacityCost = calculateDesignCapacityCost(selectedEffects, efficiencyBonus);
@@ -84,7 +90,7 @@ export function EnchantmentDesigner({
const incompatibleEffects = getIncompatibleEffects(selectedEquipmentType, unlockedEffects);
// 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
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 { GameStore } from '@/lib/game/stores';
export interface EnchantmentDesignerProps {
store: GameStore;
selectedEquipmentType: string | null;
setSelectedEquipmentType: (type: string | null) => void;
selectedEffects: DesignEffect[];
@@ -1,7 +1,6 @@
import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment';
import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from '@/lib/game/data/enchantment-effects';
import type { DesignEffect, EquipmentCategory } from '@/lib/game/types';
import type { GameStore } from '@/lib/game/stores';
import type { DesignEffect, EquipmentInstance, EquipmentCategory } from '@/lib/game/types';
/**
* 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)
* 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
const ownedEquipmentTypeIds = new Set<string>();
// 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);
}
@@ -13,7 +13,7 @@ import { Trash2, CheckCircle, AlertTriangle } from 'lucide-react';
import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment';
import type { EquipmentInstance, AppliedEnchantment, LootInventory, EquipmentCraftingProgress, EquipmentSlot } from '@/lib/game/types';
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';
export interface EnchantmentPreparerProps {
@@ -26,13 +26,13 @@ export function EnchantmentPreparer({
setSelectedEquipmentInstance,
}: EnchantmentPreparerProps) {
const showToast = useGameToast();
const equippedInstances = useGameStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances);
const preparationProgress = useGameStore((s) => s.preparationProgress);
const rawMana = useGameStore((s) => s.rawMana);
const skills = useGameStore((s) => s.skills);
const startPreparing = useGameStore((s) => s.startPreparing);
const cancelPreparation = useGameStore((s) => s.cancelPreparation);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const preparationProgress = useCraftingStore((s) => s.preparationProgress);
const rawMana = useManaStore((s) => s.rawMana);
const skills = useSkillStore((s) => s.skills);
const startPreparing = useCraftingStore((s) => s.startPreparing);
const cancelPreparation = useCraftingStore((s) => s.cancelPreparation);
// Get equipped items as array
const equippedItems = Object.entries(equippedInstances)
+2 -2
View File
@@ -1,12 +1,12 @@
'use client';
import { useGameStore } from '@/lib/game/stores';
import { useGameStore, useCraftingStore } from '@/lib/game/stores';
import { LootInventoryDisplay } from '@/components/game/LootInventory';
export function LootTab() {
const lootInventory = useGameStore((s) => s.lootInventory);
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 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 { formatSpellCost, getSpellCostColor } from '@/lib/game/formatting';
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';
// Extracted components
@@ -68,11 +68,11 @@ export function SpireTab({ simpleMode = false }: SpireTabProps) {
const skillTiers = useSkillStore((s) => s.skillTiers);
const rawMana = useManaStore((s) => s.rawMana);
const elements = useManaStore((s) => s.elements);
const equippedInstances = useGameStore((s) => s.equippedInstances);
const equipmentInstances = useGameStore((s) => s.equipmentInstances);
const designProgress = useGameStore((s) => s.designProgress);
const designProgress2 = useGameStore((s) => s.designProgress2);
const preparationProgress = useGameStore((s) => s.preparationProgress);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const designProgress = useCraftingStore((s) => s.designProgress);
const designProgress2 = useCraftingStore((s) => s.designProgress2);
const preparationProgress = useCraftingStore((s) => s.preparationProgress);
const applicationProgress = useGameStore((s) => s.applicationProgress);
const equipmentCraftingProgress = useGameStore((s) => s.equipmentCraftingProgress);