Files
Mana-Loop/src/lib/game/data/fabricator-recipes.ts
T
n8n-gitea 64b472572b
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m37s
fix: fabricator recipes now use correct elemental mana type
- 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
2026-05-27 11:06:24 +02:00

232 lines
7.6 KiB
TypeScript

// ─── Fabricator Recipes ──────────────────────────────────────────────────────
// Crafting recipes for the Fabricator attunement.
// Each recipe is tied to a mana type the player has unlocked.
import type { EquipmentSlot } from './equipment/types';
export interface FabricatorRecipe {
id: string;
name: string;
description: string;
/** Mana type required to craft this recipe (must be unlocked) */
manaType: string;
/** Equipment type ID produced */
equipmentTypeId: string;
/** Which slot the resulting equipment occupies */
slot: EquipmentSlot;
/** Materials required: materialId -> count */
materials: Record<string, number>;
/** Mana cost in the recipe's mana type */
manaCost: number;
/** Craft time in hours */
craftTime: number;
/** Rarity tier */
rarity: 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary';
/** Flavor text describing the gear's properties */
gearTrait: string;
}
export const FABRICATOR_RECIPES: FabricatorRecipe[] = [
// ─── Earth Gear (Compacted Earth — high defense) ──────────────────────
{
id: 'earthHelm',
name: 'Earthen Helm',
description: 'A sturdy helm carved from compacted stone.',
manaType: 'earth',
equipmentTypeId: 'wizardHat',
slot: 'head',
materials: { manaCrystalDust: 4, arcaneShard: 2 },
manaCost: 200,
craftTime: 3,
rarity: 'uncommon',
gearTrait: '+15% physical resistance',
},
{
id: 'earthChest',
name: 'Stoneguard Armor',
description: 'Heavy stone plates layered over leather. Slow but nearly impenetrable.',
manaType: 'earth',
equipmentTypeId: 'scholarRobe',
slot: 'body',
materials: { manaCrystalDust: 8, arcaneShard: 4, elementalCore: 1 },
manaCost: 500,
craftTime: 6,
rarity: 'rare',
gearTrait: '+25% physical resistance, -10% cast speed',
},
{
id: 'earthBoots',
name: 'Stonegreaves',
description: 'Boots reinforced with compacted earth. Firm footing in any battle.',
manaType: 'earth',
equipmentTypeId: 'travelerBoots',
slot: 'feet',
materials: { manaCrystalDust: 3, arcaneShard: 1 },
manaCost: 150,
craftTime: 2,
rarity: 'uncommon',
gearTrait: '+10% physical resistance',
},
// ─── Metal Gear (Fire+Earth — balanced offense/defense) ──────────────
{
id: 'metalBlade',
name: 'Metal Blade',
description: 'A blade forged from condensed metal mana. Sharp and durable.',
manaType: 'metal',
equipmentTypeId: 'steelBlade',
slot: 'mainHand',
materials: { manaCrystalDust: 6, arcaneShard: 3, elementalCore: 2 },
manaCost: 400,
craftTime: 5,
rarity: 'rare',
gearTrait: '+20% damage, +10% durability',
},
{
id: 'metalShield',
name: 'Metal Kite Shield',
description: 'A polished metal shield. Reliable protection without excessive weight.',
manaType: 'metal',
equipmentTypeId: 'runicShield',
slot: 'offHand',
materials: { manaCrystalDust: 7, arcaneShard: 4, elementalCore: 1 },
manaCost: 450,
craftTime: 5,
rarity: 'rare',
gearTrait: '+20% block chance',
},
{
id: 'metalGloves',
name: 'Metalweave Gauntlets',
description: 'Gauntlets woven with metal mana threads. Protective yet dexterous.',
manaType: 'metal',
equipmentTypeId: 'spellweaveGloves',
slot: 'hands',
materials: { manaCrystalDust: 4, arcaneShard: 2 },
manaCost: 250,
craftTime: 3,
rarity: 'uncommon',
gearTrait: '+10% damage, +10% physical resistance',
},
// ─── Crystal Gear (Sand+Sand+Light — high enchantment capacity) ──────
{
id: 'crystalWand',
name: 'Crystal Focus Wand',
description: 'A wand with a pure crystal core. Exceptional mana conductivity.',
manaType: 'crystal',
equipmentTypeId: 'crystalWand',
slot: 'mainHand',
materials: { manaCrystalDust: 10, arcaneShard: 5, elementalCore: 3 },
manaCost: 600,
craftTime: 6,
rarity: 'epic',
gearTrait: '+40% enchantment capacity',
},
{
id: 'crystalRing',
name: 'Crystal Ring',
description: 'A ring set with a mana crystal. Amplifies enchantment effects.',
manaType: 'crystal',
equipmentTypeId: 'silverRing',
slot: 'accessory1',
materials: { manaCrystalDust: 5, arcaneShard: 3, elementalCore: 1 },
manaCost: 350,
craftTime: 3,
rarity: 'rare',
gearTrait: '+15% enchantment capacity',
},
{
id: 'crystalAmulet',
name: 'Crystal Pendant',
description: 'An amulet housing a crystal shard. Enhances all enchantments worn.',
manaType: 'crystal',
equipmentTypeId: 'silverAmulet',
slot: 'accessory2',
materials: { manaCrystalDust: 6, arcaneShard: 3, elementalCore: 2 },
manaCost: 400,
craftTime: 4,
rarity: 'rare',
gearTrait: '+10% all enchantment effects',
},
// ─── Sand Gear (Earth+Water — lightweight, agile) ────────────────────
{
id: 'sandBoots',
name: 'Sandstrider Boots',
description: 'Boots infused with sand mana. Light as air, silent as dust.',
manaType: 'sand',
equipmentTypeId: 'travelerBoots',
slot: 'feet',
materials: { manaCrystalDust: 3, arcaneShard: 1 },
manaCost: 120,
craftTime: 2,
rarity: 'uncommon',
gearTrait: '+15% cast speed, +10% evasion',
},
{
id: 'sandGloves',
name: 'Sandweave Gloves',
description: 'Gloves woven from sand mana. Nimble fingers for delicate enchanting.',
manaType: 'sand',
equipmentTypeId: 'spellweaveGloves',
slot: 'hands',
materials: { manaCrystalDust: 3, arcaneShard: 2 },
manaCost: 140,
craftTime: 2,
rarity: 'uncommon',
gearTrait: '+10% cast speed',
},
{
id: 'sandVest',
name: 'Sandcloth Vest',
description: 'A light vest woven from sand mana. Offers minimal protection but maximum mobility.',
manaType: 'sand',
equipmentTypeId: 'scholarRobe',
slot: 'body',
materials: { manaCrystalDust: 5, arcaneShard: 2, elementalCore: 1 },
manaCost: 300,
craftTime: 4,
rarity: 'rare',
gearTrait: '+20% cast speed, +5% evasion',
},
];
// ─── Helpers ──────────────────────────────────────────────────────────────────
export function getRecipesByManaType(manaType: string): FabricatorRecipe[] {
return FABRICATOR_RECIPES.filter(r => r.manaType === manaType);
}
export function getRecipeById(id: string): FabricatorRecipe | undefined {
return FABRICATOR_RECIPES.find(r => r.id === id);
}
export function canCraftRecipe(
recipe: FabricatorRecipe,
materials: Record<string, number>,
manaAmount: number,
manaType?: string,
): { canCraft: boolean; missingMaterials: Record<string, number>; missingMana: number } {
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;
}
}
// If manaType is provided, manaAmount is already the correct pool value.
// Otherwise fall back to treating manaAmount as raw mana (backward compat).
const effectiveManaType = manaType ?? recipe.manaType;
const missingMana = Math.max(0, recipe.manaCost - manaAmount);
if (missingMana > 0) {
canCraft = false;
}
return { canCraft, missingMaterials, missingMana };
}