96 lines
3.0 KiB
C#
96 lines
3.0 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using BITKit;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Net.Project.B.Inventory
|
|
{
|
|
public interface IPlayerEquipmentInventory
|
|
{
|
|
IReadOnlyDictionary<int, IRuntimeItem> Items { get; }
|
|
public event Action<int, IRuntimeItem> OnItemAdded;
|
|
public event Action<int, IRuntimeItem> OnItemUpdated;
|
|
public event Action<int, IRuntimeItem> OnItemConsumed;
|
|
public event Action<int, IRuntimeItem> OnItemRemoved;
|
|
bool AddOrUpdate(int slot, IRuntimeItem item);
|
|
bool Remove(int slot);
|
|
bool Consume(int slot);
|
|
}
|
|
|
|
public class PlayerEquipmentInventory : IPlayerEquipmentInventory
|
|
{
|
|
private readonly ILogger<PlayerEquipmentInventory> _logger;
|
|
private readonly IPlayerInventory _playerInventory;
|
|
|
|
public IReadOnlyDictionary<int, IRuntimeItem> Items => _items;
|
|
private readonly ConcurrentDictionary<int, IRuntimeItem> _items = new();
|
|
|
|
public PlayerEquipmentInventory(ILogger<PlayerEquipmentInventory> logger, IPlayerInventory playerInventory)
|
|
{
|
|
_logger = logger;
|
|
_playerInventory = playerInventory;
|
|
}
|
|
|
|
public event Action<int, IRuntimeItem> OnItemAdded;
|
|
public event Action<int, IRuntimeItem> OnItemUpdated;
|
|
public event Action<int, IRuntimeItem> OnItemConsumed;
|
|
public event Action<int, IRuntimeItem> OnItemRemoved;
|
|
|
|
public virtual bool AddOrUpdate(int slot, IRuntimeItem item)
|
|
{
|
|
if (_items.TryGetValue(slot, out var current))
|
|
{
|
|
if (current.Id != item.Id) return false;
|
|
|
|
_items[slot] = item;
|
|
OnItemUpdated?.Invoke(slot, item);
|
|
}
|
|
else
|
|
{
|
|
_items.TryAdd(slot, item);
|
|
OnItemAdded?.Invoke(slot, item);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public virtual bool Remove(int slot)
|
|
{
|
|
if (!_items.TryRemove(slot, out var item)) return false;
|
|
OnItemRemoved?.Invoke(slot, item);
|
|
return true;
|
|
|
|
}
|
|
|
|
public virtual bool Consume(int slot)
|
|
{
|
|
if (_items.TryRemove(slot, out var item) is false) return false;
|
|
|
|
try
|
|
{
|
|
OnItemConsumed?.Invoke(slot, item);
|
|
|
|
foreach (var (id, runtimeItem) in _playerInventory.Container.ItemDictionary)
|
|
{
|
|
if (runtimeItem.ScriptableId != item.ScriptableId) continue;
|
|
if (!_playerInventory.Container.Remove(id)) continue;
|
|
if (AddOrUpdate(slot, item))
|
|
{
|
|
break;
|
|
}
|
|
throw new InvalidOperationException("内部错误,无法从背包补充物品");
|
|
}
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
_logger.LogCritical(e,e.Message);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|