92 lines
3.6 KiB
TypeScript
92 lines
3.6 KiB
TypeScript
// ─── Equipment Crafting Tick ─────────────────────────────────────────────────
|
|
// Handles advancing equipment crafting progress and completing crafted items.
|
|
// Extracted from craftingStore.ts to stay under the 400-line file limit.
|
|
|
|
import type { CraftingState } from './craftingStore.types';
|
|
import * as CraftingEquipment from '../crafting-equipment';
|
|
import { CRAFTING_RECIPES } from '../data/crafting-recipes';
|
|
import { FABRICATOR_RECIPES } from '../data/fabricator-recipes';
|
|
import { HOURS_PER_TICK } from '../constants';
|
|
import type { AppliedEnchantment } from '../types/equipment';
|
|
import { useCombatStore } from './combatStore';
|
|
|
|
export interface CraftingTickResult {
|
|
completed: boolean;
|
|
logMessage?: string;
|
|
}
|
|
|
|
export function processEquipmentCraftingTick(
|
|
state: CraftingState,
|
|
set: (partial: Partial<CraftingState>) => void,
|
|
): CraftingTickResult {
|
|
const progress = state.equipmentCraftingProgress;
|
|
if (!progress) return { completed: false };
|
|
|
|
const newProgress = progress.progress + HOURS_PER_TICK;
|
|
|
|
// Still in progress — just advance
|
|
if (newProgress < progress.required) {
|
|
set({ equipmentCraftingProgress: { ...progress, progress: newProgress } });
|
|
return { completed: false };
|
|
}
|
|
|
|
// Crafting complete — resolve the recipe and create instance
|
|
const isFabricator = progress.blueprintId.startsWith('fabricator-');
|
|
|
|
if (isFabricator) {
|
|
const recipeId = progress.blueprintId.replace('fabricator-', '');
|
|
const recipe = FABRICATOR_RECIPES.find(r => r.id === recipeId);
|
|
if (!recipe) {
|
|
set({ equipmentCraftingProgress: null });
|
|
useCombatStore.setState({ currentAction: 'meditate' });
|
|
return { completed: false, logMessage: '🔨 Crafting failed: recipe not found.' };
|
|
}
|
|
const bonusEnchantments: AppliedEnchantment[] = recipe.bonusEnchantments
|
|
? recipe.bonusEnchantments.map(e => ({ ...e }))
|
|
: [];
|
|
const result = CraftingEquipment.completeEquipmentCrafting(
|
|
progress.blueprintId,
|
|
recipe as any,
|
|
bonusEnchantments,
|
|
);
|
|
if (result.success) {
|
|
const { instanceId, instance, logMessage } = result.data;
|
|
set({
|
|
equipmentInstances: { ...state.equipmentInstances, [instanceId]: instance },
|
|
equipmentCraftingProgress: null,
|
|
});
|
|
useCombatStore.setState({ currentAction: 'meditate' });
|
|
return { completed: true, logMessage };
|
|
} else {
|
|
set({ equipmentCraftingProgress: null });
|
|
useCombatStore.setState({ currentAction: 'meditate' });
|
|
return { completed: false, logMessage: `🔨 Crafting failed: ${result.error}` };
|
|
}
|
|
} else {
|
|
// Blueprint crafting
|
|
const blueprint = CRAFTING_RECIPES[progress.blueprintId];
|
|
if (!blueprint) {
|
|
set({ equipmentCraftingProgress: null });
|
|
useCombatStore.setState({ currentAction: 'meditate' });
|
|
return { completed: false, logMessage: '🔨 Crafting failed: blueprint not found.' };
|
|
}
|
|
const result = CraftingEquipment.completeEquipmentCrafting(
|
|
progress.blueprintId,
|
|
blueprint,
|
|
);
|
|
if (result.success) {
|
|
const { instanceId, instance, logMessage } = result.data;
|
|
set({
|
|
equipmentInstances: { ...state.equipmentInstances, [instanceId]: instance },
|
|
equipmentCraftingProgress: null,
|
|
});
|
|
useCombatStore.setState({ currentAction: 'meditate' });
|
|
return { completed: true, logMessage };
|
|
} else {
|
|
set({ equipmentCraftingProgress: null });
|
|
useCombatStore.setState({ currentAction: 'meditate' });
|
|
return { completed: false, logMessage: `🔨 Crafting failed: ${result.error}` };
|
|
}
|
|
}
|
|
}
|