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
This commit is contained in:
257
src/lib/game/data/crafting-recipes.ts
Normal file
257
src/lib/game/data/crafting-recipes.ts
Normal file
@@ -0,0 +1,257 @@
|
||||
// ─── 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);
|
||||
}
|
||||
Reference in New Issue
Block a user