feat: add material crafting recipes to Fabricator
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m20s

This commit is contained in:
2026-05-27 14:39:44 +02:00
parent 3f20991d2d
commit 9a2da67006
8 changed files with 256 additions and 241 deletions
@@ -14,8 +14,8 @@ import {
MATERIAL_RECIPES,
getRecipesByManaType,
canCraftRecipe,
MANA_TYPE_LABELS,
} from '@/lib/game/data/fabricator-recipes';
import { MANA_TYPE_LABELS } from '@/lib/game/data/fabricator-recipe-types';
import { LOOT_DROPS, LOOT_RARITY_COLORS } from '@/lib/game/data/loot-drops';
import { useCraftingStore, useManaStore } from '@/lib/game/stores';
import type { FabricatorRecipe } from '@/lib/game/data/fabricator-recipes';
@@ -4,7 +4,8 @@ import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { LOOT_DROPS, LOOT_RARITY_COLORS } from '@/lib/game/data/loot-drops';
import { canCraftRecipe, MANA_TYPE_LABELS } from '@/lib/game/data/fabricator-recipes';
import { canCraftRecipe } from '@/lib/game/data/fabricator-recipes';
import { MANA_TYPE_LABELS } from '@/lib/game/data/fabricator-recipe-types';
import type { FabricatorRecipe } from '@/lib/game/data/fabricator-recipes';
interface MaterialRecipeCardProps {
@@ -0,0 +1,45 @@
// ─── Fabricator Recipe Types ───────────────────────────────────────────────────
// Shared types for fabricator and material recipes to avoid circular dependencies.
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;
/** Recipe type: 'equipment' (default) or 'material' */
recipeType?: 'equipment' | 'material';
/** For material recipes: the material ID produced */
resultMaterial?: string;
/** For material recipes: how many are produced */
resultAmount?: number;
}
export const MANA_TYPE_LABELS: Record<string, string> = {
raw: '⚪ Raw',
fire: '🔥 Fire',
water: '💧 Water',
air: '🌬️ Air',
earth: '⛰️ Earth',
light: '☀️ Light',
dark: '🌑 Dark',
metal: '🔩 Metal',
crystal: '💎 Crystal',
sand: '🏜️ Sand',
};
+181 -49
View File
@@ -2,39 +2,9 @@
// 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 type { FabricatorRecipe, MANA_TYPE_LABELS } from './fabricator-recipe-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;
/** Recipe type: 'equipment' (default) or 'material' */
recipeType?: 'equipment' | 'material';
/** For material recipes: the material ID produced */
resultMaterial?: string;
/** For material recipes: how many are produced */
resultAmount?: number;
}
import { MATERIAL_RECIPES } from './material-recipes';
export { MATERIAL_RECIPES };
export const FABRICATOR_RECIPES: FabricatorRecipe[] = [
// ─── Earth Gear (Compacted Earth — high defense) ──────────────────────
@@ -203,29 +173,191 @@ export const FABRICATOR_RECIPES: FabricatorRecipe[] = [
];
// ─── Mana Type Labels ────────────────────────────────────────────────────────
// ─── Material Crafting Recipes ───────────────────────────────────────────────
export const MANA_TYPE_LABELS: Record<string, string> = {
raw: '⚪ Raw',
fire: '🔥 Fire',
water: '💧 Water',
air: '🌬️ Air',
earth: '⛰️ Earth',
light: '☀️ Light',
dark: '🌑 Dark',
metal: '🔩 Metal',
crystal: '💎 Crystal',
sand: '🏜️ Sand',
};
export const MATERIAL_RECIPES: FabricatorRecipe[] = [
{
id: 'manaCrystal',
name: 'Mana Crystal',
description: 'Condense raw mana into a stable crystal. Used in all advanced crafting.',
manaType: 'raw',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: {},
manaCost: 500,
craftTime: 1,
rarity: 'uncommon',
gearTrait: 'Produces 1 Mana Crystal',
recipeType: 'material',
resultMaterial: 'manaCrystal',
resultAmount: 1,
},
{
id: 'manaCrystalDustCraft',
name: 'Mana Crystal Dust',
description: 'Grind a Mana Crystal into dust. Used as a base material.',
manaType: 'raw',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 10,
craftTime: 1,
rarity: 'common',
gearTrait: 'Produces 2 Mana Crystal Dust',
recipeType: 'material',
resultMaterial: 'manaCrystalDust',
resultAmount: 2,
},
{
id: 'fireCrystal',
name: 'Fire Attuned Crystal',
description: 'Infuse a Mana Crystal with fire mana to attune it to the flame element.',
manaType: 'fire',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Fire Attuned Crystal',
recipeType: 'material',
resultMaterial: 'fireCrystal',
resultAmount: 1,
},
{
id: 'waterCrystal',
name: 'Water Attuned Crystal',
description: 'Infuse a Mana Crystal with water mana to attune it to the flow element.',
manaType: 'water',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Water Attuned Crystal',
recipeType: 'material',
resultMaterial: 'waterCrystal',
resultAmount: 1,
},
{
id: 'airCrystal',
name: 'Air Attuned Crystal',
description: 'Infuse a Mana Crystal with air mana to attune it to the wind element.',
manaType: 'air',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Air Attuned Crystal',
recipeType: 'material',
resultMaterial: 'airCrystal',
resultAmount: 1,
},
{
id: 'earthCrystal',
name: 'Earth Attuned Crystal',
description: 'Infuse a Mana Crystal with earth mana to attune it to the stone element.',
manaType: 'earth',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Earth Attuned Crystal',
recipeType: 'material',
resultMaterial: 'earthCrystal',
resultAmount: 1,
},
{
id: 'lightCrystal',
name: 'Light Attuned Crystal',
description: 'Infuse a Mana Crystal with light mana to attune it to the radiant element.',
manaType: 'light',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Light Attuned Crystal',
recipeType: 'material',
resultMaterial: 'lightCrystal',
resultAmount: 1,
},
{
id: 'darkCrystal',
name: 'Dark Attuned Crystal',
description: 'Infuse a Mana Crystal with dark mana to attune it to the shadow element.',
manaType: 'dark',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Dark Attuned Crystal',
recipeType: 'material',
resultMaterial: 'darkCrystal',
resultAmount: 1,
},
{
id: 'metalCrystal',
name: 'Metal Attuned Crystal',
description: 'Infuse a Mana Crystal with metal mana to attune it to the alloy element.',
manaType: 'metal',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Metal Attuned Crystal',
recipeType: 'material',
resultMaterial: 'metalCrystal',
resultAmount: 1,
},
{
id: 'crystalCrystal',
name: 'Crystal Attuned Crystal',
description: 'Infuse a Mana Crystal with crystal mana to attune it to the prismatic element.',
manaType: 'crystal',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'epic',
gearTrait: 'Produces 1 Crystal Attuned Crystal',
recipeType: 'material',
resultMaterial: 'crystalCrystal',
resultAmount: 1,
},
{
id: 'elementalCore',
name: 'Elemental Core',
description: 'Combine mana crystals and all four base elements into a powerful core.',
manaType: 'raw',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 10 },
manaCost: 100,
craftTime: 10,
rarity: 'epic',
gearTrait: 'Produces 1 Elemental Core',
recipeType: 'material',
resultMaterial: 'elementalCore',
resultAmount: 1,
},
];
// ─── Helpers ──────────────────────────────────────────────────────────────────
export function getRecipesByManaType(manaType: string): FabricatorRecipe[] {
return FABRICATOR_RECIPES.filter(r => r.manaType === manaType && r.recipeType !== 'material');
}
export function getMaterialRecipes(): FabricatorRecipe[] {
return FABRICATOR_RECIPES.filter(r => r.recipeType === 'material');
return FABRICATOR_RECIPES.filter(r => r.manaType === manaType);
}
export function getRecipeById(id: string): FabricatorRecipe | undefined {
-184
View File
@@ -1,184 +0,0 @@
// ─── Material Crafting Recipes ────────────────────────────────────────────────
// Recipes that produce materials rather than equipment.
// All recipes use the FabricatorRecipe interface with recipeType: 'material'.
import type { FabricatorRecipe } from './fabricator-recipes';
export const MATERIAL_RECIPES: FabricatorRecipe[] = [
{
id: 'manaCrystal',
name: 'Mana Crystal',
description: 'Condense raw mana into a stable crystal. Used in all advanced crafting.',
manaType: 'raw',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: {},
manaCost: 500,
craftTime: 1,
rarity: 'uncommon',
gearTrait: 'Produces 1 Mana Crystal',
recipeType: 'material',
resultMaterial: 'manaCrystal',
resultAmount: 1,
},
{
id: 'manaCrystalDustCraft',
name: 'Mana Crystal Dust',
description: 'Grind a Mana Crystal into dust. Used as a base material.',
manaType: 'raw',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 10,
craftTime: 1,
rarity: 'common',
gearTrait: 'Produces 2 Mana Crystal Dust',
recipeType: 'material',
resultMaterial: 'manaCrystalDust',
resultAmount: 2,
},
{
id: 'fireCrystal',
name: 'Fire Attuned Crystal',
description: 'Infuse a Mana Crystal with fire mana to attune it to the flame element.',
manaType: 'fire',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Fire Attuned Crystal',
recipeType: 'material',
resultMaterial: 'fireCrystal',
resultAmount: 1,
},
{
id: 'waterCrystal',
name: 'Water Attuned Crystal',
description: 'Infuse a Mana Crystal with water mana to attune it to the flow element.',
manaType: 'water',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Water Attuned Crystal',
recipeType: 'material',
resultMaterial: 'waterCrystal',
resultAmount: 1,
},
{
id: 'airCrystal',
name: 'Air Attuned Crystal',
description: 'Infuse a Mana Crystal with air mana to attune it to the wind element.',
manaType: 'air',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Air Attuned Crystal',
recipeType: 'material',
resultMaterial: 'airCrystal',
resultAmount: 1,
},
{
id: 'earthCrystal',
name: 'Earth Attuned Crystal',
description: 'Infuse a Mana Crystal with earth mana to attune it to the stone element.',
manaType: 'earth',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Earth Attuned Crystal',
recipeType: 'material',
resultMaterial: 'earthCrystal',
resultAmount: 1,
},
{
id: 'lightCrystal',
name: 'Light Attuned Crystal',
description: 'Infuse a Mana Crystal with light mana to attune it to the radiant element.',
manaType: 'light',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Light Attuned Crystal',
recipeType: 'material',
resultMaterial: 'lightCrystal',
resultAmount: 1,
},
{
id: 'darkCrystal',
name: 'Dark Attuned Crystal',
description: 'Infuse a Mana Crystal with dark mana to attune it to the shadow element.',
manaType: 'dark',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Dark Attuned Crystal',
recipeType: 'material',
resultMaterial: 'darkCrystal',
resultAmount: 1,
},
{
id: 'metalCrystal',
name: 'Metal Attuned Crystal',
description: 'Infuse a Mana Crystal with metal mana to attune it to the alloy element.',
manaType: 'metal',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'rare',
gearTrait: 'Produces 1 Metal Attuned Crystal',
recipeType: 'material',
resultMaterial: 'metalCrystal',
resultAmount: 1,
},
{
id: 'crystalCrystal',
name: 'Crystal Attuned Crystal',
description: 'Infuse a Mana Crystal with crystal mana to attune it to the prismatic element.',
manaType: 'crystal',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 1 },
manaCost: 100,
craftTime: 1,
rarity: 'epic',
gearTrait: 'Produces 1 Crystal Attuned Crystal',
recipeType: 'material',
resultMaterial: 'crystalCrystal',
resultAmount: 1,
},
{
id: 'elementalCore',
name: 'Elemental Core',
description: 'Combine mana crystals and all four base elements into a powerful core.',
manaType: 'raw',
equipmentTypeId: 'basicStaff',
slot: 'mainHand',
materials: { manaCrystal: 10 },
manaCost: 100,
craftTime: 10,
rarity: 'epic',
gearTrait: 'Produces 1 Elemental Core',
recipeType: 'material',
resultMaterial: 'elementalCore',
resultAmount: 1,
},
];