using Godot; using System; using System.Collections.Generic; using System.Linq; using System.Threading; public partial class InventoryManager : Node { // 库存数据结构 public class InventoryItem { public string ItemId { get; set; } public int Quantity { get; set; } public InventoryItem(string itemId, int quantity = 0) { ItemId = itemId; Quantity = quantity; } } // 单例实例 private static InventoryManager instance; public static InventoryManager Instance { get { return instance; } } // 库存数据字典 - 物品ID -> 库存项 private Dictionary inventory = new Dictionary(); // 线程锁 private readonly object inventoryLock = new object(); // 事件委托 public delegate void InventoryChangedEventHandler(string itemId, int oldQuantity, int newQuantity); public event InventoryChangedEventHandler InventoryChanged; public override void _Ready() { GD.Print("InventoryManager _Ready 开始"); // 确保单例 if (instance == null) { instance = this; InitializeInventory(); } else { GD.PrintErr("InventoryManager 实例已存在!"); QueueFree(); } } // 初始化库存 private void InitializeInventory() { GD.Print("初始化库存系统"); lock (inventoryLock) { // 为所有已知物品创建库存条目(初始数量为0) if (GameData.Instance != null) { var allItems = GameData.Instance.GetAllItems(); foreach (var item in allItems) { inventory[item.Key] = new InventoryItem(item.Key, 0); } GD.Print($"初始化了 {inventory.Count} 个物品的库存条目"); } else { GD.PrintErr("GameData.Instance 为 null,无法初始化库存"); } } // 添加一些测试数据 AddTestData(); } // 添加测试数据 private void AddTestData() { GD.Print("添加测试库存数据"); AddItem("iron_ore", 100); AddItem("copper_ore", 50); AddItem("coal_ore", 75); AddItem("water", 200); AddItem("iron_ingot", 25); AddItem("copper_ingot", 15); } // 添加物品到库存 public bool AddItem(string itemId, int quantity) { if (quantity <= 0) return false; lock (inventoryLock) { int oldQuantity = GetItemQuantityUnsafe(itemId); if (!inventory.ContainsKey(itemId)) { inventory[itemId] = new InventoryItem(itemId, quantity); } else { inventory[itemId].Quantity += quantity; } int newQuantity = inventory[itemId].Quantity; GD.Print($"添加物品: {itemId} +{quantity} (总量: {newQuantity})"); // 在锁外触发事件 CallDeferred(nameof(TriggerInventoryChanged), itemId, oldQuantity, newQuantity); return true; } } // 从库存中移除物品 public bool RemoveItem(string itemId, int quantity) { if (quantity <= 0) return false; lock (inventoryLock) { if (!inventory.ContainsKey(itemId)) return false; int oldQuantity = inventory[itemId].Quantity; if (oldQuantity < quantity) return false; // 库存不足 inventory[itemId].Quantity -= quantity; int newQuantity = inventory[itemId].Quantity; GD.Print($"移除物品: {itemId} -{quantity} (剩余: {newQuantity})"); // 在锁外触发事件 CallDeferred(nameof(TriggerInventoryChanged), itemId, oldQuantity, newQuantity); return true; } } // 设置物品数量 public void SetItemQuantity(string itemId, int quantity) { lock (inventoryLock) { int oldQuantity = GetItemQuantityUnsafe(itemId); if (!inventory.ContainsKey(itemId)) { inventory[itemId] = new InventoryItem(itemId, quantity); } else { inventory[itemId].Quantity = quantity; } GD.Print($"设置物品数量: {itemId} = {quantity}"); // 在锁外触发事件 CallDeferred(nameof(TriggerInventoryChanged), itemId, oldQuantity, quantity); } } // 获取物品数量(线程安全) public int GetItemQuantity(string itemId) { lock (inventoryLock) { return GetItemQuantityUnsafe(itemId); } } // 获取物品数量(非线程安全,内部使用) private int GetItemQuantityUnsafe(string itemId) { if (inventory.ContainsKey(itemId)) { return inventory[itemId].Quantity; } return 0; } // 检查是否有足够的物品 public bool HasEnoughItems(string itemId, int requiredQuantity) { return GetItemQuantity(itemId) >= requiredQuantity; } // 检查是否有足够的材料(用于配方检查) public bool HasEnoughMaterials(Dictionary recipe) { if (recipe == null) return true; lock (inventoryLock) { foreach (var requirement in recipe) { if (GetItemQuantityUnsafe(requirement.Key) < requirement.Value) { return false; } } return true; } } // 消耗材料(用于生产) public bool ConsumeMaterials(Dictionary recipe) { if (recipe == null) return true; lock (inventoryLock) { // 先检查是否有足够材料 foreach (var requirement in recipe) { if (GetItemQuantityUnsafe(requirement.Key) < requirement.Value) { return false; } } // 消耗材料 foreach (var requirement in recipe) { int oldQuantity = GetItemQuantityUnsafe(requirement.Key); inventory[requirement.Key].Quantity -= requirement.Value; int newQuantity = inventory[requirement.Key].Quantity; // 在锁外触发事件 CallDeferred(nameof(TriggerInventoryChanged), requirement.Key, oldQuantity, newQuantity); } return true; } } // 获取所有库存物品 public Dictionary GetAllInventory() { lock (inventoryLock) { var result = new Dictionary(); foreach (var item in inventory) { result[item.Key] = new InventoryItem(item.Value.ItemId, item.Value.Quantity); } return result; } } // 获取有库存的物品(数量>0) public Dictionary GetAvailableItems() { lock (inventoryLock) { var result = new Dictionary(); foreach (var item in inventory) { if (item.Value.Quantity > 0) { result[item.Key] = new InventoryItem(item.Value.ItemId, item.Value.Quantity); } } return result; } } // 获取指定分类的库存物品 public Dictionary GetInventoryByCategory(GameData.ItemCategory category) { lock (inventoryLock) { var result = new Dictionary(); foreach (var item in inventory) { var itemData = GameData.Instance?.GetItem(item.Key); if (itemData != null && itemData.Category == category) { result[item.Key] = new InventoryItem(item.Value.ItemId, item.Value.Quantity); } } return result; } } // 清空库存 public void ClearInventory() { Dictionary oldQuantities; lock (inventoryLock) { oldQuantities = new Dictionary(); foreach (var item in inventory) { oldQuantities[item.Key] = item.Value.Quantity; item.Value.Quantity = 0; } GD.Print("清空所有库存"); } // 在锁外触发事件 foreach (var item in oldQuantities) { if (item.Value > 0) { CallDeferred(nameof(TriggerInventoryChanged), item.Key, item.Value, 0); } } } // 获取库存总数量 public int GetTotalItemCount() { lock (inventoryLock) { return inventory.Values.Sum(item => item.Quantity); } } // 调试:打印所有库存 public void PrintInventory() { lock (inventoryLock) { GD.Print("=== 当前库存 ==="); foreach (var item in inventory) { if (item.Value.Quantity > 0) { var itemData = GameData.Instance?.GetItem(item.Key); string itemName = itemData?.Name ?? item.Key; GD.Print($"{itemName}: {item.Value.Quantity}"); } } GD.Print("==============="); } } // 触发库存变化事件(在主线程中调用) private void TriggerInventoryChanged(string itemId, int oldQuantity, int newQuantity) { InventoryChanged?.Invoke(itemId, oldQuantity, newQuantity); } // 清理单例 public override void _ExitTree() { if (instance == this) { instance = null; } } }