인벤토리 및 ui 로직 변경
This commit is contained in:
parent
ec6afcd2ae
commit
2084bbcb32
@ -6,11 +6,20 @@
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public enum InventorySortType
|
||||
{
|
||||
None = 0,
|
||||
NameAscending,
|
||||
NameDescending,
|
||||
QuantityAscending,
|
||||
QuantityDescending
|
||||
}
|
||||
|
||||
public class InventoryManager : Singleton<InventoryManager>, IManager
|
||||
{
|
||||
[Title("아이템 전체 목록")]
|
||||
[ShowInInspector, ReadOnly]
|
||||
private Dictionary<string, ItemData> _itemDataLookup;
|
||||
private Dictionary<string, ItemData> _allItemDataLookup;
|
||||
|
||||
[Title("아이템 보유 목록")]
|
||||
[ShowInInspector, ReadOnly]
|
||||
@ -41,7 +50,7 @@ private void InitializeItemData()
|
||||
var itemDataSo = DataManager.Instance.GetDataSo<ItemDataSo>();
|
||||
Debug.Assert(itemDataSo != null, "itemDataSo != null");
|
||||
|
||||
_itemDataLookup = itemDataSo.GetDataList()
|
||||
_allItemDataLookup = itemDataSo.GetDataList()
|
||||
.Where(item => !string.IsNullOrEmpty(item.Id))
|
||||
.ToDictionary(item => item.Id, item => item);
|
||||
|
||||
@ -72,7 +81,7 @@ private async void ApplyEditorTestData()
|
||||
|
||||
public bool AddItem(string id, int quantity = 1)
|
||||
{
|
||||
if (!_itemDataLookup.ContainsKey(id))
|
||||
if (!_allItemDataLookup.ContainsKey(id))
|
||||
{
|
||||
Debug.LogError($"[Inventory] 등록되지 않은 아이템 ID: {id}");
|
||||
return false;
|
||||
@ -123,12 +132,14 @@ public bool RemoveItem(string id, int quantity = 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<string, ItemData> AllItemDataLookup => _allItemDataLookup;
|
||||
public IReadOnlyDictionary<string, InventoryItemData> InventoryItems => _inventoryItemDatas;
|
||||
public bool TryGetItemData(string id, out ItemData itemData) => _itemDataLookup.TryGetValue(id, out itemData);
|
||||
public bool ContainInventoryItem(string id) => _inventoryItemDatas.ContainsKey(id);
|
||||
public bool TryGetInventoryItemData(string id, out InventoryItemData inventoryItemData) => _inventoryItemDatas.TryGetValue(id, out inventoryItemData);
|
||||
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);
|
||||
_allItemDataLookup.TryGetValue(id, out var itemData);
|
||||
return itemData;
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,33 @@ public class InventorySlotUiStrategy : IItemSlotUiStrategy
|
||||
|
||||
public void Setup(ItemSlotUi ui, ItemViewModel model)
|
||||
{
|
||||
ui.SetIcon(model.ItemSprite);
|
||||
ui.ShowCountText();
|
||||
if (InventoryManager.Instance.ContainInventoryItem(model.Id))
|
||||
{
|
||||
ui.SetIcon(model.ItemSprite);
|
||||
ui.ShowCountText();
|
||||
ui.HideMark();
|
||||
ui.SetButtonInteractable(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO : 임시 초기화 값
|
||||
string emptySpriteKey = SpriteConstants.EmptyFoodSpriteKey;
|
||||
if (model.ItemType == ItemType.Recipe)
|
||||
{
|
||||
if (model.RecipeType == RecipeType.FoodRecipe)
|
||||
{
|
||||
emptySpriteKey = SpriteConstants.EmptyFoodSpriteKey;
|
||||
}
|
||||
else if (model.RecipeType == RecipeType.DrinkRecipe)
|
||||
{
|
||||
emptySpriteKey = SpriteConstants.EmptyDrinkSpriteKey;
|
||||
}
|
||||
}
|
||||
|
||||
ui.SetIcon(DataManager.Instance.GetSprite(emptySpriteKey));
|
||||
ui.HideCountText();
|
||||
ui.HideMark();
|
||||
ui.SetButtonInteractable(true);
|
||||
ui.SetButtonInteractable(false);
|
||||
}
|
||||
|
||||
public async Task<RuntimeAnimatorController> GetAnimatorController()
|
||||
@ -22,10 +45,12 @@ public async Task<RuntimeAnimatorController> GetAnimatorController()
|
||||
|
||||
public void OnInventoryChanged(ItemSlotUi ui)
|
||||
{
|
||||
if (ui.Model == null) return;
|
||||
|
||||
ui.Model.UpdateCount();
|
||||
ui.ShowCountText();
|
||||
var model = ui.Model;
|
||||
if (InventoryManager.Instance.ContainInventoryItem(model.Id))
|
||||
{
|
||||
ui.Model.UpdateCount();
|
||||
ui.ShowCountText();
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanCrafting(ItemSlotUi ui)
|
||||
|
@ -1,23 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
|
||||
namespace DDD
|
||||
{
|
||||
public class InventoryView : MonoBehaviour, IEventHandler<InventoryChangedEvent>, IEventHandler<TodayMenuAddedEvent>, IEventHandler<TodayMenuRemovedEvent>
|
||||
public class InventoryView : MonoBehaviour, IEventHandler<InventoryChangedEvent>,
|
||||
IEventHandler<TodayMenuAddedEvent>, IEventHandler<TodayMenuRemovedEvent>
|
||||
{
|
||||
[SerializeField] private Transform _slotParent;
|
||||
|
||||
|
||||
private RestaurantManagementSo _restaurantManagementSo;
|
||||
private InventoryCategoryType _currenInventoryCategoryType = InventoryCategoryType.Food;
|
||||
|
||||
|
||||
private readonly Dictionary<string, ItemSlotUi> _slotLookup = new();
|
||||
private GameObject _firstSlot;
|
||||
|
||||
private InventorySortType _currentSortType = InventorySortType.None;
|
||||
|
||||
private const string ItemSlotUiName = "ItemSlotUi_";
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
EventBus.Register<InventoryChangedEvent>(this);
|
||||
@ -31,13 +32,15 @@ private void OnDisable()
|
||||
EventBus.Unregister<TodayMenuAddedEvent>(this);
|
||||
EventBus.Unregister<TodayMenuRemovedEvent>(this);
|
||||
}
|
||||
|
||||
|
||||
public GameObject GetInitialSelected() => _firstSlot;
|
||||
|
||||
public async Task Initialize()
|
||||
{
|
||||
_restaurantManagementSo = await AssetManager.LoadAsset<RestaurantManagementSo>(DataConstants.RestaurantManagementSo);
|
||||
_restaurantManagementSo =
|
||||
await AssetManager.LoadAsset<RestaurantManagementSo>(DataConstants.RestaurantManagementSo);
|
||||
Debug.Assert(_restaurantManagementSo != null, "_todayMenuDataSo != null");
|
||||
|
||||
|
||||
Clear();
|
||||
|
||||
var models = ItemViewModelFactory.CreateRestaurantManagementInventoryItem();
|
||||
@ -66,51 +69,79 @@ public async Task Initialize()
|
||||
_slotLookup[model.Id] = slot;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetSortType(InventorySortType sortType)
|
||||
{
|
||||
_currentSortType = sortType;
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private IEnumerable<ItemSlotUi> SortSlots(IEnumerable<ItemSlotUi> slots)
|
||||
{
|
||||
return _currentSortType switch
|
||||
{
|
||||
InventorySortType.NameAscending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenBy(slot => slot.Model.DisplayName),
|
||||
InventorySortType.NameDescending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenByDescending(slot => slot.Model.DisplayName),
|
||||
InventorySortType.QuantityAscending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenBy(slot => slot.Model.Count),
|
||||
InventorySortType.QuantityDescending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenByDescending(slot => slot.Model.Count),
|
||||
InventorySortType.None => slots.OrderBy(slot => slot.Model.Id),
|
||||
_ => slots
|
||||
};
|
||||
}
|
||||
|
||||
public void UpdateCategoryView(InventoryCategoryType category)
|
||||
{
|
||||
_currenInventoryCategoryType = category;
|
||||
|
||||
_firstSlot = null;
|
||||
foreach (var kvp in _slotLookup)
|
||||
|
||||
var filteredSlots = _slotLookup.Values;
|
||||
var sortedSlots = SortSlots(filteredSlots);
|
||||
|
||||
int siblingIndex = 0;
|
||||
|
||||
foreach (var slot in sortedSlots)
|
||||
{
|
||||
var id = kvp.Key;
|
||||
var slot = kvp.Value;
|
||||
var model = slot.Model;
|
||||
string id = model.Id;
|
||||
|
||||
// 1. 오늘의 메뉴에 등록된 경우 필터링
|
||||
bool isRegisteredTodayMenu = model.ItemType == ItemType.Recipe && _restaurantManagementSo.IsContainTodayMenu(id);
|
||||
|
||||
// 2. 현재 선택된 카테고리에 맞는지 필터링
|
||||
bool matchCategory = MatchesCategory(model, _currenInventoryCategoryType);
|
||||
|
||||
// 3. 조건을 모두 만족할 경우만 활성화
|
||||
bool shouldShow = !isRegisteredTodayMenu && matchCategory;
|
||||
|
||||
slot.SetActive(shouldShow);
|
||||
|
||||
if (shouldShow && _firstSlot == null)
|
||||
if (shouldShow && model.HasItem)
|
||||
{
|
||||
_firstSlot = slot.gameObject;
|
||||
slot.transform.SetSiblingIndex(siblingIndex++);
|
||||
|
||||
if (_firstSlot == null)
|
||||
{
|
||||
_firstSlot = slot.gameObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private bool MatchesCategory(ItemViewModel model, InventoryCategoryType category)
|
||||
{
|
||||
switch (category)
|
||||
{
|
||||
case InventoryCategoryType.Food:
|
||||
if (model.ItemType != ItemType.Recipe) return false;
|
||||
|
||||
return DataManager.Instance.GetDataSo<RecipeDataSo>().TryGetDataById(model.Id, out var foodRecipe) && foodRecipe.RecipeType == RecipeType.FoodRecipe;
|
||||
|
||||
return DataManager.Instance.GetDataSo<RecipeDataSo>()
|
||||
.TryGetDataById(model.Id, out var foodRecipe) && foodRecipe.RecipeType == RecipeType.FoodRecipe;
|
||||
case InventoryCategoryType.Drink:
|
||||
if (model.ItemType != ItemType.Recipe) return false;
|
||||
|
||||
return DataManager.Instance.GetDataSo<RecipeDataSo>().TryGetDataById(model.Id, out var drinkRecipe) && drinkRecipe.RecipeType == RecipeType.DrinkRecipe;
|
||||
|
||||
return DataManager.Instance.GetDataSo<RecipeDataSo>()
|
||||
.TryGetDataById(model.Id, out var drinkRecipe) &&
|
||||
drinkRecipe.RecipeType == RecipeType.DrinkRecipe;
|
||||
case InventoryCategoryType.Ingredient:
|
||||
return model.ItemType == ItemType.Ingredient;
|
||||
case InventoryCategoryType.Cookware:
|
||||
return DataManager.Instance.GetDataSo<CookwareDataSo>().TryGetDataById(model.Id, out var cookwareData);
|
||||
return DataManager.Instance.GetDataSo<CookwareDataSo>()
|
||||
.TryGetDataById(model.Id, out var cookwareData);
|
||||
case InventoryCategoryType.Special:
|
||||
return false;
|
||||
default:
|
||||
|
@ -25,6 +25,8 @@ public ItemViewModel(string id, ItemType itemType)
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
public bool HasItem => Count > 0;
|
||||
public string DisplayName => LocalizationManager.Instance.GetName(Id);
|
||||
public RecipeType RecipeType => ItemType == ItemType.Recipe ? DataManager.Instance.GetDataSo<RecipeDataSo>().GetDataById(Id).RecipeType : RecipeType.None;
|
||||
public Sprite ItemSprite
|
||||
{
|
||||
|
@ -7,18 +7,23 @@ public static class ItemViewModelFactory
|
||||
public static List<ItemViewModel> CreateRestaurantManagementInventoryItem()
|
||||
{
|
||||
var result = new List<ItemViewModel>();
|
||||
foreach (var kvp in InventoryManager.Instance.InventoryItems)
|
||||
var allItemDataLookup = InventoryManager.Instance.AllItemDataLookup;
|
||||
foreach (var keyItemDataPair in allItemDataLookup)
|
||||
{
|
||||
var id = kvp.Key;
|
||||
var item = InventoryManager.Instance.GetItemDataByIdOrNull(id);
|
||||
if (item == null) continue;
|
||||
var id = keyItemDataPair.Key;
|
||||
var itemData = keyItemDataPair.Value;
|
||||
|
||||
var modelCount = item.ItemType switch
|
||||
int modelCount = 0;
|
||||
if (InventoryManager.Instance.ContainInventoryItem(id))
|
||||
{
|
||||
ItemType.Recipe => CalculateCraftableCount(item.Id),
|
||||
_ => InventoryManager.Instance.GetItemCount(id)
|
||||
};
|
||||
var model = new ItemViewModel(item.Id, item.ItemType, modelCount);
|
||||
modelCount = itemData.ItemType switch
|
||||
{
|
||||
ItemType.Recipe => CalculateCraftableCount(itemData.Id),
|
||||
_ => InventoryManager.Instance.GetItemCount(id)
|
||||
};
|
||||
}
|
||||
|
||||
var model = new ItemViewModel(id, itemData.ItemType, modelCount);
|
||||
|
||||
result.Add(model);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user