(client)feat:视野范围检测,
This commit is contained in:
@ -1,70 +1,149 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Item;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Entity
|
||||
{
|
||||
public class Inventory
|
||||
{
|
||||
public Entity from; // 物品所属实体
|
||||
public List<ItemBase> items = new List<ItemBase>(); // 背包中的物品列表
|
||||
public Entity From { get; private set; }
|
||||
private readonly List<InventorySlot> _slots;
|
||||
public int Capacity { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加物品到背包
|
||||
/// </summary>
|
||||
/// <param name="item">要添加的物品</param>
|
||||
/// <param name="count">添加的数量</param>
|
||||
public void AddItem(ItemResource resource, int count)
|
||||
public event System.Action<Item.ItemResource, int> OnItemAdded;
|
||||
public event System.Action<Item.ItemResource, int> OnItemRemoved;
|
||||
public event System.Action OnInventoryChanged;
|
||||
|
||||
public Inventory(Entity owner, int capacity = 20)
|
||||
{
|
||||
if (count <= 0) return; // 如果数量小于等于0,直接返回
|
||||
From = owner;
|
||||
Capacity = Mathf.Max(1, capacity);
|
||||
_slots = new List<InventorySlot>(Capacity);
|
||||
}
|
||||
|
||||
// 检查背包中是否已存在相同物品
|
||||
foreach (var item in items)
|
||||
public int AddItem(Item.ItemResource itemResource, int quantity)
|
||||
{
|
||||
if (itemResource == null || quantity <= 0)
|
||||
{
|
||||
if (item.resource.Equals(resource))
|
||||
Debug.LogWarning(
|
||||
$"Inventory for {From?.ToString() ?? "Unknown"}: Attempted to add null item or zero/negative quantity.");
|
||||
return quantity;
|
||||
}
|
||||
|
||||
var remainingQuantity = quantity;
|
||||
var addedTotal = 0;
|
||||
|
||||
// 1. 尝试堆叠到现有槽位 (使用 DefName 进行比较)
|
||||
if (itemResource.MaxStack > 1)
|
||||
{
|
||||
foreach (var slot in _slots.Where(s =>
|
||||
s.Item != null && s.Item.DefName == itemResource.DefName && !s.IsFull))
|
||||
{
|
||||
item.count += count; // 增加数量
|
||||
return;
|
||||
var addedToSlot = slot.AddQuantity(remainingQuantity);
|
||||
remainingQuantity -= addedToSlot;
|
||||
addedTotal += addedToSlot;
|
||||
if (remainingQuantity <= 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到相同物品,则创建新物品并添加到背包
|
||||
var newItem = new ItemBase { resource = resource, count = count };
|
||||
items.Add(newItem);
|
||||
// 2. 如果还有剩余,尝试添加到新槽位
|
||||
while (remainingQuantity > 0 && _slots.Count < Capacity)
|
||||
{
|
||||
var quantityToAdd = Mathf.Min(remainingQuantity, itemResource.MaxStack);
|
||||
var newSlot = new InventorySlot(itemResource, quantityToAdd);
|
||||
_slots.Add(newSlot);
|
||||
remainingQuantity -= quantityToAdd;
|
||||
addedTotal += quantityToAdd;
|
||||
}
|
||||
|
||||
if (addedTotal > 0)
|
||||
{
|
||||
OnItemAdded?.Invoke(itemResource, addedTotal);
|
||||
OnInventoryChanged?.Invoke();
|
||||
}
|
||||
|
||||
if (remainingQuantity > 0)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"Inventory for {From?.ToString() ?? "Unknown"} is full or cannot stack. {remainingQuantity} of {itemResource.Name} (DefName: {itemResource.DefName}) could not be added.");
|
||||
}
|
||||
|
||||
return remainingQuantity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从背包中取出物品
|
||||
/// </summary>
|
||||
/// <param name="itemName">物品名称</param>
|
||||
/// <param name="count">取出的数量</param>
|
||||
/// <returns>是否成功取出</returns>
|
||||
public bool RemoveItem(string itemName, int count)
|
||||
public int RemoveItem(Item.ItemResource itemResource, int quantity)
|
||||
{
|
||||
if (count <= 0) return false; // 如果数量小于等于0,直接返回失败
|
||||
|
||||
foreach (var item in items)
|
||||
if (itemResource == null || quantity <= 0)
|
||||
{
|
||||
if (item.resource.name == itemName)
|
||||
{
|
||||
if (item.count >= count)
|
||||
{
|
||||
item.count -= count; // 减少数量
|
||||
if (item.count == 0)
|
||||
{
|
||||
items.Remove(item); // 如果数量为0,则移除该物品
|
||||
}
|
||||
Debug.LogWarning(
|
||||
$"Inventory for {From?.ToString() ?? "Unknown"}: Attempted to remove null item or zero/negative quantity.");
|
||||
return quantity;
|
||||
}
|
||||
|
||||
return true; // 成功取出
|
||||
}
|
||||
else
|
||||
var remainingQuantity = quantity;
|
||||
var removedTotal = 0;
|
||||
var slotsToClean = new List<InventorySlot>();
|
||||
|
||||
// 从后往前遍历,以便安全地移除空槽位 (使用 DefName 进行比较)
|
||||
for (var i = _slots.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var slot = _slots[i];
|
||||
if (slot.Item != null && slot.Item.DefName == itemResource.DefName)
|
||||
{
|
||||
var removedFromSlot = slot.RemoveQuantity(remainingQuantity);
|
||||
remainingQuantity -= removedFromSlot;
|
||||
removedTotal += removedFromSlot;
|
||||
|
||||
if (slot.IsEmpty)
|
||||
{
|
||||
return false; // 数量不足
|
||||
slotsToClean.Add(slot);
|
||||
}
|
||||
|
||||
if (remainingQuantity <= 0) break;
|
||||
}
|
||||
}
|
||||
return false; // 未找到物品
|
||||
}
|
||||
|
||||
|
||||
foreach (var slot in slotsToClean)
|
||||
{
|
||||
_slots.Remove(slot);
|
||||
}
|
||||
|
||||
if (removedTotal > 0)
|
||||
{
|
||||
OnItemRemoved?.Invoke(itemResource, removedTotal);
|
||||
OnInventoryChanged?.Invoke();
|
||||
}
|
||||
|
||||
if (remainingQuantity > 0)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"Inventory for {From?.ToString() ?? "Unknown"}: Not enough {itemResource.Name} (DefName: {itemResource.DefName}). {remainingQuantity} could not be removed.");
|
||||
}
|
||||
|
||||
return remainingQuantity;
|
||||
}
|
||||
|
||||
public bool HasItem(Item.ItemResource itemResource, int quantity = 1)
|
||||
{
|
||||
if (itemResource == null || quantity <= 0) return false;
|
||||
return GetItemCount(itemResource) >= quantity;
|
||||
}
|
||||
|
||||
public int GetItemCount(Item.ItemResource itemResource)
|
||||
{
|
||||
if (itemResource == null) return 0;
|
||||
// 使用 DefName 进行计数
|
||||
return _slots.Where(s => s.Item != null && s.Item.DefName == itemResource.DefName)
|
||||
.Sum(s => s.Quantity);
|
||||
}
|
||||
|
||||
public IReadOnlyList<InventorySlot> GetSlots()
|
||||
{
|
||||
return _slots.AsReadOnly();
|
||||
}
|
||||
|
||||
public int OccupiedSlotsCount => _slots.Count;
|
||||
public int AvailableSlotsCount => Capacity - _slots.Count;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user