fix: fabricator recipes now use correct elemental mana type
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m37s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m37s
- fabricator-recipes.ts: add optional manaType param to canCraftRecipe for clarity - FabricatorSubTab.tsx: read elemental mana from store based on recipe manaType instead of always using rawMana - craftingStore.ts: add startFabricatorCrafting action that deducts correct mana type - craftingStore.types.ts: add startFabricatorCrafting to CraftingActions interface - crafting-fabricator.ts: new helper file to keep craftingStore.ts under 400 lines Fixes #155
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
// ─── Fabricator Crafting Helpers ──────────────────────────────────────────────
|
||||
// Separate file to avoid exceeding the 400-line limit in craftingStore.ts.
|
||||
|
||||
import type { EquipmentCraftingProgress } from './types';
|
||||
import type { FabricatorRecipe } from './data/fabricator-recipes';
|
||||
import { FABRICATOR_RECIPES } from './data/fabricator-recipes';
|
||||
|
||||
// ─── Lookup ───────────────────────────────────────────────────────────────────
|
||||
|
||||
export function getFabricatorRecipe(recipeId: string): FabricatorRecipe | undefined {
|
||||
return FABRICATOR_RECIPES.find(r => r.id === recipeId);
|
||||
}
|
||||
|
||||
// ─── Cost Check ───────────────────────────────────────────────────────────────
|
||||
|
||||
export interface FabricatorCostCheck {
|
||||
canCraft: boolean;
|
||||
missingMana: number;
|
||||
missingMaterials: Record<string, number>;
|
||||
}
|
||||
|
||||
export function checkFabricatorCosts(
|
||||
recipe: FabricatorRecipe,
|
||||
materials: Record<string, number>,
|
||||
rawMana: number,
|
||||
elements: Record<string, { current: number; max: number; unlocked: boolean }>,
|
||||
): FabricatorCostCheck {
|
||||
const missingMaterials: Record<string, number> = {};
|
||||
let canCraft = true;
|
||||
|
||||
for (const [matId, required] of Object.entries(recipe.materials)) {
|
||||
const available = materials[matId] || 0;
|
||||
if (available < required) {
|
||||
missingMaterials[matId] = required - available;
|
||||
canCraft = false;
|
||||
}
|
||||
}
|
||||
|
||||
const manaAvailable = recipe.manaType === 'raw'
|
||||
? rawMana
|
||||
: (elements[recipe.manaType]?.current ?? 0);
|
||||
const missingMana = Math.max(0, recipe.manaCost - manaAvailable);
|
||||
if (missingMana > 0) canCraft = false;
|
||||
|
||||
return { canCraft, missingMana, missingMaterials };
|
||||
}
|
||||
|
||||
// ─── Mana Deduction ───────────────────────────────────────────────────────────
|
||||
|
||||
export interface ManaDeduction {
|
||||
rawMana: number;
|
||||
elements: Record<string, { current: number; max: number; unlocked: boolean }>;
|
||||
}
|
||||
|
||||
export function deductFabricatorMana(
|
||||
recipe: FabricatorRecipe,
|
||||
rawMana: number,
|
||||
elements: Record<string, { current: number; max: number; unlocked: boolean }>,
|
||||
): ManaDeduction | null {
|
||||
if (recipe.manaType === 'raw') {
|
||||
if (rawMana < recipe.manaCost) return null;
|
||||
return { rawMana: rawMana - recipe.manaCost, elements };
|
||||
}
|
||||
|
||||
const elemState = elements[recipe.manaType];
|
||||
if (!elemState || !elemState.unlocked || elemState.current < recipe.manaCost) return null;
|
||||
|
||||
return {
|
||||
rawMana,
|
||||
elements: {
|
||||
...elements,
|
||||
[recipe.manaType]: {
|
||||
...elements[recipe.manaType],
|
||||
current: elements[recipe.manaType].current - recipe.manaCost,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Mana Refund (on cancel) ──────────────────────────────────────────────────
|
||||
|
||||
export interface ManaRefund {
|
||||
rawMana: number;
|
||||
elements: Record<string, { current: number; max: number; unlocked: boolean }>;
|
||||
}
|
||||
|
||||
export function refundFabricatorMana(
|
||||
recipe: FabricatorRecipe,
|
||||
refundAmount: number,
|
||||
rawMana: number,
|
||||
elements: Record<string, { current: number; max: number; unlocked: boolean }>,
|
||||
): ManaRefund {
|
||||
if (recipe.manaType === 'raw') {
|
||||
return { rawMana: rawMana + refundAmount, elements };
|
||||
}
|
||||
|
||||
return {
|
||||
rawMana,
|
||||
elements: {
|
||||
...elements,
|
||||
[recipe.manaType]: {
|
||||
...elements[recipe.manaType],
|
||||
current: Math.min(
|
||||
elements[recipe.manaType].max,
|
||||
elements[recipe.manaType].current + refundAmount,
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Material Deduction ───────────────────────────────────────────────────────
|
||||
|
||||
export function deductMaterials(
|
||||
recipe: FabricatorRecipe,
|
||||
materials: Record<string, number>,
|
||||
): Record<string, number> {
|
||||
const newMaterials = { ...materials };
|
||||
for (const [matId, amount] of Object.entries(recipe.materials)) {
|
||||
newMaterials[matId] = (newMaterials[matId] || 0) - amount;
|
||||
if (newMaterials[matId] <= 0) delete newMaterials[matId];
|
||||
}
|
||||
return newMaterials;
|
||||
}
|
||||
|
||||
// ─── Progress Init ────────────────────────────────────────────────────────────
|
||||
|
||||
export function makeFabricatorProgress(
|
||||
recipeId: string,
|
||||
equipmentTypeId: string,
|
||||
craftTime: number,
|
||||
manaCost: number,
|
||||
): EquipmentCraftingProgress {
|
||||
return {
|
||||
blueprintId: `fabricator-${recipeId}`,
|
||||
equipmentTypeId,
|
||||
progress: 0,
|
||||
required: craftTime,
|
||||
manaSpent: manaCost,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user