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