diff --git a/src/lib/game/stores/craftingStore.ts b/src/lib/game/stores/craftingStore.ts index 8a74264..aec0ae4 100644 --- a/src/lib/game/stores/craftingStore.ts +++ b/src/lib/game/stores/craftingStore.ts @@ -92,265 +92,267 @@ export type CraftingStore = CraftingState & CraftingActions; export const useCraftingStore = create()( persist( - (set, get) => ({ - // Initial state - designProgress: null, - designProgress2: null, - preparationProgress: null, - applicationProgress: null, - equipmentCraftingProgress: null, - enchantmentDesigns: [], - unlockedEffects: [], - equipmentInstances: {}, - equippedInstances: {}, - lootInventory: { - materials: {}, - blueprints: [], - }, + (set, get) => { + const startingEquipment = createStartingEquipment(); + return { + // Initial state + designProgress: null, + designProgress2: null, + preparationProgress: null, + applicationProgress: null, + equipmentCraftingProgress: null, + enchantmentDesigns: [], + unlockedEffects: [], + ...startingEquipment, + lootInventory: { + materials: {}, + blueprints: [], + }, - // Actions - setDesignProgress: (progress) => set({ designProgress: progress }), - setDesignProgress2: (progress) => set({ designProgress2: progress }), - setPreparationProgress: (progress) => set({ preparationProgress: progress }), - setApplicationProgress: (progress) => set({ applicationProgress: progress }), - setEquipmentCraftingProgress: (progress) => set({ equipmentCraftingProgress: progress }), + // Actions + setDesignProgress: (progress) => set({ designProgress: progress }), + setDesignProgress2: (progress) => set({ designProgress2: progress }), + setPreparationProgress: (progress) => set({ preparationProgress: progress }), + setApplicationProgress: (progress) => set({ applicationProgress: 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 + // 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 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 equipType = CraftingUtils.getEquipmentType(equipmentTypeId); + if (!equipType) return false; - const efficiencyBonus = (skillState.skillUpgrades?.['efficientEnchant'] || []).length * 0.05 || 0; - const totalCapacityCost = CraftingDesign.calculateDesignCapacityCost(effects, efficiencyBonus); + const efficiencyBonus = (skillState.skillUpgrades?.['efficientEnchant'] || []).length * 0.05 || 0; + const totalCapacityCost = CraftingDesign.calculateDesignCapacityCost(effects, efficiencyBonus); - if (totalCapacityCost > equipType.baseCapacity) return false; + if (totalCapacityCost > equipType.baseCapacity) return false; - const computedEffects = computeEffects(skillState.skillUpgrades || {}, skillState.skillTiers || {}); - const hasEnchantMastery = hasSpecial(computedEffects, SPECIAL_EFFECTS.ENCHANT_MASTERY); + const computedEffects = computeEffects(skillState.skillUpgrades || {}, skillState.skillTiers || {}); + const hasEnchantMastery = hasSpecial(computedEffects, SPECIAL_EFFECTS.ENCHANT_MASTERY); - let updates: Partial = {}; + let updates: Partial = {}; - if (!state.designProgress) { - updates = { - designProgress: { - designId: CraftingUtils.generateDesignId(), - progress: 0, - required: CraftingDesign.calculateDesignTime(effects), - name, - equipmentType: equipmentTypeId, - effects, - }, - }; - // Update currentAction in combatStore - useCombatStore.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 }); - useCombatStore.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, - })); - useCombatStore.setState({ currentAction: 'meditate' }); - } - }, - - // 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); - useCombatStore.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); - useCombatStore.setState({ currentAction: 'meditate' }); - }, - - // Equipment crafting actions - startCraftingEquipment: (blueprintId: string) => { - const state = get(); - const rawMana = useManaStore.getState().rawMana; - const currentAction = useCombatStore.getState().currentAction; - - // Check if we can start crafting - const check = CraftingEquipment.canStartEquipmentCrafting( - blueprintId, - state.lootInventory.blueprints.includes(blueprintId), - state.lootInventory.materials, - rawMana, - currentAction - ); - - if (!check.canCraft) return false; - - // Initialize crafting - const result = CraftingEquipment.initializeEquipmentCrafting( - blueprintId, - state.lootInventory.materials, - rawMana - ); - - // Update crafting store state - set((s) => ({ - lootInventory: { - ...s.lootInventory, - materials: result.newMaterials, - }, - equipmentCraftingProgress: result.progress, - })); - - // Update mana store (deduct mana) - useManaStore.setState((s) => ({ rawMana: s.rawMana - result.manaCost })); - - // Update combat store (set current action) - useCombatStore.setState({ currentAction: 'craft' }); - - return true; - }, - - cancelEquipmentCrafting: () => { - const state = get(); - const progress = state.equipmentCraftingProgress; - if (!progress) return; - - // Get cancel result (mana refund) - const cancelResult = CraftingEquipment.cancelEquipmentCrafting( - progress.blueprintId, - progress.manaSpent - ); - - // Update crafting store state - set({ equipmentCraftingProgress: null }); - - // Refund mana to mana store - useManaStore.setState((s) => ({ rawMana: s.rawMana + cancelResult.manaRefund })); - - // Update combat store (reset action) - useCombatStore.setState({ currentAction: 'meditate' }); - - // Add log message to UI store - useUIStore.getState().addLog(cancelResult.logMessage); - }, - - // Loot inventory actions - deleteMaterial: (materialId: string, amount: number) => { - set((state) => { - const newMaterials = { ...state.lootInventory.materials }; - const currentAmount = newMaterials[materialId] || 0; - const newAmount = Math.max(0, currentAmount - amount); - - if (newAmount <= 0) { - delete newMaterials[materialId]; + if (!state.designProgress) { + updates = { + designProgress: { + designId: CraftingUtils.generateDesignId(), + progress: 0, + required: CraftingDesign.calculateDesignTime(effects), + name, + equipmentType: equipmentTypeId, + effects, + }, + }; + // Update currentAction in combatStore + useCombatStore.setState({ currentAction: 'design' }); + } else if (hasEnchantMastery && !state.designProgress2) { + updates = { + designProgress2: { + designId: CraftingUtils.generateDesignId(), + progress: 0, + required: CraftingDesign.calculateDesignTime(effects), + name, + equipmentType: equipmentTypeId, + effects, + }, + }; } else { - newMaterials[materialId] = newAmount; + return false; } - return { + set(updates); + return true; + }, + + cancelDesign: () => { + const state = get(); + if (state.designProgress2 && !state.designProgress) { + set({ designProgress2: null }); + } else { + set({ designProgress: null }); + useCombatStore.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, + })); + useCombatStore.setState({ currentAction: 'meditate' }); + } + }, + + // 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); + useCombatStore.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); + useCombatStore.setState({ currentAction: 'meditate' }); + }, + + // Equipment crafting actions + startCraftingEquipment: (blueprintId: string) => { + const state = get(); + const rawMana = useManaStore.getState().rawMana; + const currentAction = useCombatStore.getState().currentAction; + + // Check if we can start crafting + const check = CraftingEquipment.canStartEquipmentCrafting( + bluePrintId, + state.lootInventory.blueprints.includes(blueprintId), + state.lootInventory.materials, + rawMana, + currentAction + ); + + if (!check.canCraft) return false; + + // Initialize crafting + const result = CraftingEquipment.initializeEquipmentCrafting( + bluePrintId, + state.lootInventory.materials, + rawMana + ); + + // Update crafting store state + set((s) => ({ lootInventory: { - ...state.lootInventory, - materials: newMaterials, + ...s.lootInventory, + materials: result.newMaterials, }, - }; - }); - }, + equipmentCraftingProgress: result.progress, + })); - deleteEquipmentInstance: (instanceId: string) => { - set((state) => { - let newEquipped = { ...state.equippedInstances }; - for (const [slot, id] of Object.entries(newEquipped)) { - if (id === instanceId) { - newEquipped[slot as any] = null; + // Update mana store (deduct mana) + useManaStore.setState((s) => ({ rawMana: s.rawMana - result.manaCost })); + + // Update combat store (set current action) + useCombatStore.setState({ currentAction: 'craft' }); + + return true; + }, + + cancelEquipmentCrafting: () => { + const state = get(); + const progress = state.equipmentCraftingProgress; + if (!progress) return; + + // Get cancel result (mana refund) + const cancelResult = CraftingEquipment.cancelEquipmentCrafting( + progress.blueprintId, + progress.manaSpent + ); + + // Update crafting store state + set({ equipmentCraftingProgress: null }); + + // Refund mana to mana store + useManaStore.setState((s) => ({ rawMana: s.rawMana + cancelResult.manaRefund })); + + // Update combat store (reset action) + useCombatStore.setState({ currentAction: 'meditate' }); + + // Add log message to UI store + useUIStore.getState().addLog(cancelResult.logMessage); + }, + + // Loot inventory actions + deleteMaterial: (materialId: string, amount: number) => { + set((state) => { + const newMaterials = { ...state.lootInventory.materials }; + const currentAmount = newMaterials[materialId] || 0; + const newAmount = Math.max(0, currentAmount - amount); + + if (newAmount <= 0) { + delete newMaterials[materialId]; + } else { + newMaterials[materialId] = newAmount; } - } - const newInstances = { ...state.equipmentInstances }; - delete newInstances[instanceId]; + return { + lootInventory: { + ...state.lootInventory, + materials: newMaterials, + }, + }; + }); + }, - return { - equippedInstances: newEquipped, - equipmentInstances: newInstances, - }; - }); - }, - }), + deleteEquipmentInstance: (instanceId: string) => { + set((state) => { + let newEquipped = { ...state.equippedInstances }; + for (const [slot, id] of Object.entries(newEquipped)) { + if (id === instanceId) { + newEquipped[slot as any] = null; + } + } + + const newInstances = { ...state.equipmentInstances }; + delete newInstances[instanceId]; + + return { + equippedInstances: newEquipped, + equipmentInstances: newInstances, + }; + }); + }, + }; + }, { name: 'mana-loop-crafting', partialize: (state) => ({