This commit is contained in:
2025-06-16 07:59:50 +08:00
commit 7a6cd423fc
54 changed files with 4068 additions and 0 deletions

View File

@ -0,0 +1,368 @@
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<string, InventoryItem> inventory = new Dictionary<string, InventoryItem>();
// 线程锁
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<string, int> 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<string, int> 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<string, InventoryItem> GetAllInventory()
{
lock (inventoryLock)
{
var result = new Dictionary<string, InventoryItem>();
foreach (var item in inventory)
{
result[item.Key] = new InventoryItem(item.Value.ItemId, item.Value.Quantity);
}
return result;
}
}
// 获取有库存的物品(数量>0
public Dictionary<string, InventoryItem> GetAvailableItems()
{
lock (inventoryLock)
{
var result = new Dictionary<string, InventoryItem>();
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<string, InventoryItem> GetInventoryByCategory(GameData.ItemCategory category)
{
lock (inventoryLock)
{
var result = new Dictionary<string, InventoryItem>();
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<string, int> oldQuantities;
lock (inventoryLock)
{
oldQuantities = new Dictionary<string, int>();
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;
}
}
}