using Godot; using System.Collections.Generic; using System.Text.Json; public partial class CraftingRecipeManager : Node { public static CraftingRecipeManager Instance { get; private set; } public class Ingredient { public string ItemId { get; set; } public int Quantity { get; set; } } public class CraftingRecipe { public string Id { get; set; } public string OutputItem { get; set; } public int OutputQuantity { get; set; } public string CraftingMethod { get; set; } public float CraftingTime { get; set; } public List Ingredients { get; set; } = new List(); } public class CraftingRecipeData { public List Recipes { get; set; } = new List(); } private CraftingRecipeData recipeData; private Dictionary recipeMap = new Dictionary(); private Dictionary> outputItemMap = new Dictionary>(); public override void _Ready() { if (Instance == null) { Instance = this; LoadCraftingRecipes(); } else { QueueFree(); } } private void LoadCraftingRecipes() { string configPath = "res://data/config/crafting_recipes.json"; if (!FileAccess.FileExists(configPath)) { GD.PrintErr($"合成配方配置文件不存在: {configPath}"); return; } using var file = FileAccess.Open(configPath, FileAccess.ModeFlags.Read); if (file == null) { GD.PrintErr($"无法打开合成配方配置文件: {configPath}"); return; } string jsonContent = file.GetAsText(); try { var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; recipeData = JsonSerializer.Deserialize(jsonContent, options); if (recipeData?.Recipes != null) { // 构建配方映射 foreach (var recipe in recipeData.Recipes) { recipeMap[recipe.Id] = recipe; // 按输出物品分组 if (!outputItemMap.ContainsKey(recipe.OutputItem)) { outputItemMap[recipe.OutputItem] = new List(); } outputItemMap[recipe.OutputItem].Add(recipe); GD.Print($"加载合成配方: {recipe.Id} - {recipe.OutputItem} ({recipe.CraftingMethod})"); } GD.Print($"成功加载 {recipeData.Recipes.Count} 个合成配方"); } } catch (JsonException e) { GD.PrintErr($"解析合成配方配置文件失败: {e.Message}"); } } public List GetAllRecipes() { return recipeData?.Recipes ?? new List(); } public CraftingRecipe GetRecipe(string recipeId) { return recipeMap.GetValueOrDefault(recipeId); } public List GetRecipesForItem(string itemId) { return outputItemMap.GetValueOrDefault(itemId) ?? new List(); } public bool CanCraft(string recipeId) { var recipe = GetRecipe(recipeId); if (recipe == null || InventoryManager.Instance == null) { return false; } // 检查是否有足够的材料 foreach (var ingredient in recipe.Ingredients) { if (InventoryManager.Instance.GetItemQuantity(ingredient.ItemId) < ingredient.Quantity) { return false; } } return true; } public override void _ExitTree() { if (Instance == this) { Instance = null; } } }