Files
Mana-Loop/src/lib/game/data/crafting-recipes.ts
zhipu 1d2dce75cc Add equipment crafting system
- Add crafting-recipes.ts with blueprint definitions and material requirements
- Update crafting-slice.ts with equipment crafting functions
- Add EquipmentCraftingProgress type and state
- Update CraftingTab.tsx with new Craft tab for equipment crafting
- Add material deletion functionality
- Update store.ts with equipment crafting methods
- Update page.tsx to pass new props to CraftingTab

Features:
- Players can craft equipment from discovered blueprints
- Crafting requires materials and mana
- Materials are obtained from loot drops
- New Craft tab in the crafting interface
- Shows blueprint details and material requirements
2026-03-26 11:04:50 +00:00

258 lines
6.6 KiB
TypeScript

// ─── Crafting Recipes ─────────────────────────────────────────────────────────
// Defines what materials are needed to craft equipment from blueprints
import type { EquipmentSlot } from '../types';
export interface CraftingRecipe {
id: string; // Blueprint ID (matches loot drop)
equipmentTypeId: string; // Resulting equipment type ID
name: string; // Display name
description: string;
rarity: 'common' | 'uncommon' | 'rare' | 'epic' | 'legendary';
materials: Record<string, number>; // materialId -> count required
manaCost: number; // Raw mana cost to craft
craftTime: number; // Hours to craft
minFloor: number; // Minimum floor where blueprint drops
unlocked: boolean; // Whether the player has discovered this
}
export const CRAFTING_RECIPES: Record<string, CraftingRecipe> = {
// ─── Staff Blueprints ───
staffBlueprint: {
id: 'staffBlueprint',
equipmentTypeId: 'oakStaff',
name: 'Oak Staff',
description: 'A sturdy oak staff with decent mana capacity.',
rarity: 'uncommon',
materials: {
manaCrystalDust: 5,
arcaneShard: 2,
},
manaCost: 200,
craftTime: 4,
minFloor: 10,
unlocked: false,
},
wandBlueprint: {
id: 'wandBlueprint',
equipmentTypeId: 'crystalWand',
name: 'Crystal Wand',
description: 'A wand tipped with a small crystal. Excellent for elemental enchantments.',
rarity: 'rare',
materials: {
manaCrystalDust: 8,
arcaneShard: 4,
elementalCore: 1,
},
manaCost: 500,
craftTime: 6,
minFloor: 20,
unlocked: false,
},
robeBlueprint: {
id: 'robeBlueprint',
equipmentTypeId: 'scholarRobe',
name: 'Scholar Robe',
description: 'A robe worn by scholars and researchers.',
rarity: 'rare',
materials: {
manaCrystalDust: 6,
arcaneShard: 3,
elementalCore: 1,
},
manaCost: 400,
craftTime: 5,
minFloor: 25,
unlocked: false,
},
artifactBlueprint: {
id: 'artifactBlueprint',
equipmentTypeId: 'arcanistStaff',
name: 'Arcanist Staff',
description: 'A staff designed for advanced spellcasters. High capacity for complex enchantments.',
rarity: 'legendary',
materials: {
manaCrystalDust: 20,
arcaneShard: 10,
elementalCore: 5,
voidEssence: 2,
celestialFragment: 1,
},
manaCost: 2000,
craftTime: 12,
minFloor: 60,
unlocked: false,
},
// ─── Additional Blueprints ───
battlestaffBlueprint: {
id: 'battlestaffBlueprint',
equipmentTypeId: 'battlestaff',
name: 'Battlestaff',
description: 'A reinforced staff suitable for both casting and combat.',
rarity: 'rare',
materials: {
manaCrystalDust: 10,
arcaneShard: 5,
elementalCore: 2,
},
manaCost: 600,
craftTime: 6,
minFloor: 30,
unlocked: false,
},
catalystBlueprint: {
id: 'catalystBlueprint',
equipmentTypeId: 'fireCatalyst',
name: 'Fire Catalyst',
description: 'A catalyst attuned to fire magic. Enhances fire enchantments.',
rarity: 'rare',
materials: {
manaCrystalDust: 8,
arcaneShard: 4,
elementalCore: 3,
},
manaCost: 500,
craftTime: 5,
minFloor: 25,
unlocked: false,
},
shieldBlueprint: {
id: 'shieldBlueprint',
equipmentTypeId: 'runicShield',
name: 'Runic Shield',
description: 'A shield engraved with protective runes.',
rarity: 'rare',
materials: {
manaCrystalDust: 10,
arcaneShard: 6,
elementalCore: 2,
},
manaCost: 450,
craftTime: 5,
minFloor: 28,
unlocked: false,
},
hatBlueprint: {
id: 'hatBlueprint',
equipmentTypeId: 'wizardHat',
name: 'Wizard Hat',
description: 'A classic pointed wizard hat. Decent capacity for headwear.',
rarity: 'uncommon',
materials: {
manaCrystalDust: 4,
arcaneShard: 2,
},
manaCost: 150,
craftTime: 3,
minFloor: 12,
unlocked: false,
},
glovesBlueprint: {
id: 'glovesBlueprint',
equipmentTypeId: 'spellweaveGloves',
name: 'Spellweave Gloves',
description: 'Gloves woven with mana-conductive threads.',
rarity: 'uncommon',
materials: {
manaCrystalDust: 3,
arcaneShard: 2,
},
manaCost: 120,
craftTime: 3,
minFloor: 15,
unlocked: false,
},
bootsBlueprint: {
id: 'bootsBlueprint',
equipmentTypeId: 'travelerBoots',
name: 'Traveler Boots',
description: 'Comfortable boots for long journeys.',
rarity: 'uncommon',
materials: {
manaCrystalDust: 3,
arcaneShard: 1,
},
manaCost: 100,
craftTime: 2,
minFloor: 8,
unlocked: false,
},
ringBlueprint: {
id: 'ringBlueprint',
equipmentTypeId: 'silverRing',
name: 'Silver Ring',
description: 'A silver ring with decent magical conductivity.',
rarity: 'uncommon',
materials: {
manaCrystalDust: 2,
arcaneShard: 1,
},
manaCost: 80,
craftTime: 2,
minFloor: 10,
unlocked: false,
},
amuletBlueprint: {
id: 'amuletBlueprint',
equipmentTypeId: 'silverAmulet',
name: 'Silver Amulet',
description: 'A silver amulet with a small gem.',
rarity: 'uncommon',
materials: {
manaCrystalDust: 3,
arcaneShard: 2,
},
manaCost: 100,
craftTime: 3,
minFloor: 12,
unlocked: false,
},
};
// Helper functions
export function getRecipeByBlueprint(blueprintId: string): CraftingRecipe | undefined {
return CRAFTING_RECIPES[blueprintId];
}
export function canCraftRecipe(
recipe: CraftingRecipe,
materials: Record<string, number>,
rawMana: number
): { 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;
}
}
const missingMana = Math.max(0, recipe.manaCost - rawMana);
if (missingMana > 0) {
canCraft = false;
}
return { canCraft, missingMaterials, missingMana };
}
// Get all recipes available based on unlocked blueprints
export function getAvailableRecipes(unlockedBlueprints: string[]): CraftingRecipe[] {
return unlockedBlueprints
.map(bpId => CRAFTING_RECIPES[bpId])
.filter(Boolean);
}