From 9a2da670068fd51ec79fcee3e24d65c1f21d8348 Mon Sep 17 00:00:00 2001 From: n8n-gitea Date: Wed, 27 May 2026 14:39:44 +0200 Subject: [PATCH] feat: add material crafting recipes to Fabricator --- docs/circular-deps.txt | 11 +- docs/dependency-graph.json | 18 +- docs/project-structure.txt | 4 +- .../tabs/CraftingTab/FabricatorSubTab.tsx | 2 +- .../tabs/CraftingTab/MaterialRecipeCard.tsx | 3 +- src/lib/game/data/fabricator-recipe-types.ts | 45 ++++ src/lib/game/data/fabricator-recipes.ts | 230 ++++++++++++++---- src/lib/game/data/material-recipes.ts | 184 -------------- 8 files changed, 256 insertions(+), 241 deletions(-) create mode 100644 src/lib/game/data/fabricator-recipe-types.ts delete mode 100644 src/lib/game/data/material-recipes.ts diff --git a/docs/circular-deps.txt b/docs/circular-deps.txt index 450daea..1dbe844 100644 --- a/docs/circular-deps.txt +++ b/docs/circular-deps.txt @@ -1,4 +1,11 @@ # Circular Dependencies -Generated: 2026-05-27T10:56:11.451Z +Generated: 2026-05-27T12:13:52.087Z +Found: 1 circular chain(s) — these MUST be fixed before modifying involved files. -No circular dependencies found. ✅ +1. 1) data/fabricator-recipes.ts > data/material-recipes.ts + +## How to fix +1. Identify which import in the chain can be extracted to a shared types/utils file. +2. Move the shared type or function there. +3. Both files import from the new shared module instead of each other. +4. Run: bunx madge --circular src/lib/game (should return clean) \ No newline at end of file diff --git a/docs/dependency-graph.json b/docs/dependency-graph.json index e0039cb..9efc8e4 100644 --- a/docs/dependency-graph.json +++ b/docs/dependency-graph.json @@ -1,6 +1,6 @@ { "_meta": { - "generated": "2026-05-27T10:56:09.647Z", + "generated": "2026-05-27T12:13:50.329Z", "description": "Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.", "usage": "To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry." }, @@ -93,6 +93,12 @@ "stores/craftingStore.types.ts", "types.ts" ], + "crafting-actions/crafting-material-actions.ts": [ + "crafting-fabricator.ts", + "stores/combatStore.ts", + "stores/manaStore.ts", + "stores/uiStore.ts" + ], "crafting-actions/design-actions.ts": [ "crafting-design.ts", "crafting-utils.ts", @@ -153,6 +159,9 @@ ], "crafting-fabricator.ts": [ "data/fabricator-recipes.ts", + "stores/combatStore.ts", + "stores/manaStore.ts", + "stores/uiStore.ts", "types.ts" ], "crafting-loot.ts": [ @@ -357,7 +366,8 @@ "data/equipment/types.ts" ], "data/fabricator-recipes.ts": [ - "data/equipment/types.ts" + "data/equipment/types.ts", + "data/material-recipes.ts" ], "data/golems/base-golems.ts": [ "data/golems/types.ts" @@ -395,6 +405,9 @@ "data/loot-drops.ts": [ "types/game.ts" ], + "data/material-recipes.ts": [ + "data/fabricator-recipes.ts" + ], "effects.ts": [ "data/enchantment-effects.ts", "effects/discipline-effects.ts", @@ -464,6 +477,7 @@ ], "stores/craftingStore.ts": [ "crafting-actions/application-actions.ts", + "crafting-actions/crafting-material-actions.ts", "crafting-actions/equipment-actions.ts", "crafting-actions/preparation-actions.ts", "crafting-design.ts", diff --git a/docs/project-structure.txt b/docs/project-structure.txt index f0f4d77..18b5d8f 100644 --- a/docs/project-structure.txt +++ b/docs/project-structure.txt @@ -313,11 +313,11 @@ Mana-Loop/ │ │ │ ├── crafting-recipes.ts │ │ │ ├── enchantment-effects.ts │ │ │ ├── enchantment-types.ts +│ │ │ ├── fabricator-recipe-types.ts │ │ │ ├── fabricator-recipes.ts │ │ │ ├── guardian-data.ts │ │ │ ├── guardian-encounters.ts -│ │ │ ├── loot-drops.ts -│ │ │ └── material-recipes.ts +│ │ │ └── loot-drops.ts │ │ ├── effects/ │ │ │ ├── discipline-effects.ts │ │ │ ├── dynamic-compute.ts diff --git a/src/components/game/tabs/CraftingTab/FabricatorSubTab.tsx b/src/components/game/tabs/CraftingTab/FabricatorSubTab.tsx index 0df6a89..7292ab1 100644 --- a/src/components/game/tabs/CraftingTab/FabricatorSubTab.tsx +++ b/src/components/game/tabs/CraftingTab/FabricatorSubTab.tsx @@ -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'; diff --git a/src/components/game/tabs/CraftingTab/MaterialRecipeCard.tsx b/src/components/game/tabs/CraftingTab/MaterialRecipeCard.tsx index 441f34d..20ae042 100644 --- a/src/components/game/tabs/CraftingTab/MaterialRecipeCard.tsx +++ b/src/components/game/tabs/CraftingTab/MaterialRecipeCard.tsx @@ -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 { diff --git a/src/lib/game/data/fabricator-recipe-types.ts b/src/lib/game/data/fabricator-recipe-types.ts new file mode 100644 index 0000000..399b2ee --- /dev/null +++ b/src/lib/game/data/fabricator-recipe-types.ts @@ -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; + /** 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 = { + raw: '⚪ Raw', + fire: '🔥 Fire', + water: '💧 Water', + air: '🌬️ Air', + earth: '⛰️ Earth', + light: '☀️ Light', + dark: '🌑 Dark', + metal: '🔩 Metal', + crystal: '💎 Crystal', + sand: '🏜️ Sand', +}; diff --git a/src/lib/game/data/fabricator-recipes.ts b/src/lib/game/data/fabricator-recipes.ts index 83a7b75..7ec0e9d 100644 --- a/src/lib/game/data/fabricator-recipes.ts +++ b/src/lib/game/data/fabricator-recipes.ts @@ -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; - /** 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 = { - 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 { diff --git a/src/lib/game/data/material-recipes.ts b/src/lib/game/data/material-recipes.ts deleted file mode 100644 index 7258848..0000000 --- a/src/lib/game/data/material-recipes.ts +++ /dev/null @@ -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, - }, -];