135 lines
4.3 KiB
C#
135 lines
4.3 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
|
|
namespace DDD
|
|
{
|
|
public class InventoryManager : Singleton<InventoryManager>, IManager
|
|
{
|
|
[Title("아이템 전체 목록")]
|
|
[ShowInInspector, ReadOnly]
|
|
private Dictionary<string, ItemData> _itemDataLookup;
|
|
|
|
[Title("아이템 보유 목록")]
|
|
[ShowInInspector, ReadOnly]
|
|
private Dictionary<string, InventoryItemData> _inventoryItemDatas;
|
|
|
|
#if UNITY_EDITOR
|
|
[Title("테스트용")]
|
|
private InventoryTestDataSo _inventoryTestDataSo;
|
|
#endif
|
|
|
|
public void PreInit()
|
|
{
|
|
|
|
}
|
|
|
|
public Task Init()
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public void PostInit()
|
|
{
|
|
InitializeItemData();
|
|
}
|
|
|
|
private void InitializeItemData()
|
|
{
|
|
var itemDataSo = DataManager.Instance.GetDataSo<ItemDataSo>();
|
|
Debug.Assert(itemDataSo != null, "itemDataSo != null");
|
|
|
|
_itemDataLookup = itemDataSo.GetDataList()
|
|
.Where(item => !string.IsNullOrEmpty(item.Id))
|
|
.ToDictionary(item => item.Id, item => item);
|
|
|
|
_inventoryItemDatas = new Dictionary<string, InventoryItemData>(itemDataSo.GetDataCount());
|
|
|
|
#if UNITY_EDITOR
|
|
ApplyEditorTestData();
|
|
#endif
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private async void ApplyEditorTestData()
|
|
{
|
|
_inventoryTestDataSo = await AssetManager.LoadAsset<InventoryTestDataSo>(DataConstants.InventoryTestDataSo);
|
|
|
|
if (_inventoryTestDataSo == null || !_inventoryTestDataSo.UseTestData) return;
|
|
|
|
foreach (var entry in _inventoryTestDataSo.TestItems)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(entry.ItemId)) continue;
|
|
|
|
AddItem(entry.ItemId, entry.Quantity);
|
|
}
|
|
|
|
Debug.Log("[InventoryManager] 테스트용 인벤토리 적용 완료");
|
|
}
|
|
#endif
|
|
|
|
public bool AddItem(string id, int quantity = 1)
|
|
{
|
|
if (!_itemDataLookup.ContainsKey(id))
|
|
{
|
|
Debug.LogError($"[Inventory] 등록되지 않은 아이템 ID: {id}");
|
|
return false;
|
|
}
|
|
|
|
if (_inventoryItemDatas.TryGetValue(id, out var itemData))
|
|
{
|
|
itemData.Quantity += quantity;
|
|
}
|
|
else
|
|
{
|
|
_inventoryItemDatas[id] = new InventoryItemData(id, quantity);
|
|
}
|
|
|
|
InventoryChangedEvent evt = GameEvents.InventoryChangedEvent;
|
|
evt.ItemId = id;
|
|
evt.NewCount = GetItemCount(id);
|
|
EventBus.Broadcast(evt);
|
|
return true;
|
|
}
|
|
|
|
public bool RemoveItem(string id, int quantity = 1)
|
|
{
|
|
if (!_inventoryItemDatas.TryGetValue(id, out var itemData))
|
|
{
|
|
Debug.LogError($"[Inventory] 등록되지 않은 아이템 ID: {id}");
|
|
return false;
|
|
}
|
|
|
|
if (itemData.Quantity < quantity)
|
|
{
|
|
Debug.LogWarning($"[Inventory] 보유 수량보다 삭제하는 수량이 더 많습니다 " +
|
|
$"{id}, 보유 수량 : {itemData.Quantity}, 삭제 수량 : {quantity}");
|
|
return false;
|
|
}
|
|
|
|
itemData.Quantity -= quantity;
|
|
|
|
if (itemData.Quantity <= 0)
|
|
{
|
|
_inventoryItemDatas.Remove(id);
|
|
}
|
|
|
|
InventoryChangedEvent evt = GameEvents.InventoryChangedEvent;
|
|
evt.ItemId = id;
|
|
evt.NewCount = GetItemCount(id);
|
|
EventBus.Broadcast(evt);
|
|
return true;
|
|
}
|
|
|
|
public IReadOnlyDictionary<string, InventoryItemData> InventoryItems => _inventoryItemDatas;
|
|
public bool TryGetItemData(string id, out ItemData itemData) => _itemDataLookup.TryGetValue(id, out itemData);
|
|
public int GetItemCount(string id) => _inventoryItemDatas.TryGetValue(id, out var itemData) ? itemData.Quantity : 0;
|
|
public ItemData GetItemDataByIdOrNull(string id)
|
|
{
|
|
_itemDataLookup.TryGetValue(id, out var itemData);
|
|
return itemData;
|
|
}
|
|
}
|
|
} |