RestaurantManagementUi 상호작용 오류 수정 및 로직 변경

This commit is contained in:
NTG_Lenovo 2025-08-07 17:52:45 +09:00
parent f02fe591dc
commit 26cd093313
13 changed files with 128 additions and 58 deletions

View File

@ -98,7 +98,7 @@ public class TodayMenuAddedEvent : IEvent {}
public class TodayMenuRemovedEvent : IEvent
{
public RecipeType RecipeType;
public InventoryCategoryType InventoryCategoryType;
}
#endregion

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Sirenix.OdinInspector;
using UnityEngine;
@ -26,12 +27,12 @@ public class RestaurantManagementSo : GameFlowTask
[ReadOnly, ShowInInspector] private Dictionary<string, int> _todayFoodRecipeIds = new();
[ReadOnly, ShowInInspector] private Dictionary<string, int> _todayDrinkRecipeIds = new();
[ReadOnly, ShowInInspector] private List<string> _todayWorkerIds = new();
[ReadOnly, ShowInInspector] private List<string> _todayCookwareIds = new();
[ReadOnly, ShowInInspector] private Dictionary<string, HashSet<string>> _cookwareToRecipeIds = new();
public IReadOnlyDictionary<string, int> TodayFoodRecipeIds => _todayFoodRecipeIds;
public IReadOnlyDictionary<string, int> TodayDrinkRecipeIds => _todayDrinkRecipeIds;
public IReadOnlyList<string> TodayWorkerIds => _todayWorkerIds;
public IReadOnlyList<string> TodayCookwareIds => _todayCookwareIds;
public IReadOnlyDictionary<string, HashSet<string>> CookwareToRecipeIds => _cookwareToRecipeIds;
public override Task OnReadyNewFlow(GameFlowState newFlowState)
{
@ -48,16 +49,25 @@ private void InitializeReadyForRestaurant()
_todayFoodRecipeIds.Clear();
_todayDrinkRecipeIds.Clear();
_todayWorkerIds.Clear();
_todayCookwareIds.Clear();
_cookwareToRecipeIds.Clear();
}
public bool TryAddTodayMenu(ItemSlotUi itemSlotUi)
public bool IsOpenable()
{
string recipeId = itemSlotUi.Model.Id;
// TODO : 영업 가능한 상태인지 조건 추가 (최소 요리, 요리도구 배치 등)
bool isExistedCookware = CookwareToRecipeIds.Count > 0;
bool isExistedMatchedMenu = _cookwareToRecipeIds.Values.Any(recipeSet => recipeSet is { Count: > 0 });
if (itemSlotUi.Model.ItemType != ItemType.Recipe) return false;
return isExistedCookware && isExistedMatchedMenu;
}
if (!DataManager.Instance.GetDataSo<RecipeDataSo>().TryGetDataById(recipeId, out RecipeData recipeData)) return false;
public bool TryAddTodayMenu(ItemViewModel model)
{
string recipeId = model.Id;
if (model.ItemType != ItemType.Recipe) return false;
if (DataManager.Instance.GetDataSo<RecipeDataSo>().TryGetDataById(recipeId, out RecipeData recipeData) == false) return false;
bool added = false;
@ -86,18 +96,24 @@ public bool TryAddTodayMenu(ItemSlotUi itemSlotUi)
if (added)
{
var cookwareKey = GetRequiredCookwareKey(recipeId);
if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeIds.TryGetValue(cookwareKey, out var recipeSet))
{
recipeSet.Add(recipeId);
}
EventBus.Broadcast(RestaurantEvents.TodayMenuAddedEvent);
}
return added;
}
public bool TryRemoveTodayMenu(ItemSlotUi itemSlotUi)
public bool TryRemoveTodayMenu(ItemViewModel model)
{
string recipeId = itemSlotUi.Model.Id;
string recipeId = model.Id;
var evt = RestaurantEvents.TodayMenuRemovedEvent;
if (!DataManager.Instance.GetDataSo<RecipeDataSo>().TryGetDataById(recipeId, out RecipeData recipeData)) return false;
if (DataManager.Instance.GetDataSo<RecipeDataSo>().TryGetDataById(recipeId, out RecipeData recipeData) == false) return false;
bool removed = false;
int refundCount = 0;
@ -107,7 +123,7 @@ public bool TryRemoveTodayMenu(ItemSlotUi itemSlotUi)
if (_todayFoodRecipeIds.TryGetValue(recipeId, out refundCount))
{
removed = _todayFoodRecipeIds.Remove(recipeId);
evt.RecipeType = RecipeType.FoodRecipe;
evt.InventoryCategoryType = InventoryCategoryType.Food;
if (removed)
{
@ -121,7 +137,7 @@ public bool TryRemoveTodayMenu(ItemSlotUi itemSlotUi)
if (_todayDrinkRecipeIds.TryGetValue(recipeId, out refundCount))
{
removed = _todayDrinkRecipeIds.Remove(recipeId);
evt.RecipeType = RecipeType.DrinkRecipe;
evt.InventoryCategoryType = InventoryCategoryType.Drink;
if (removed)
{
@ -131,39 +147,78 @@ public bool TryRemoveTodayMenu(ItemSlotUi itemSlotUi)
}
}
if (!removed) return false;
EventBus.Broadcast(evt);
return true;
if (removed)
{
var cookwareKey = GetRequiredCookwareKey(recipeId);
if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeIds.TryGetValue(cookwareKey, out var recipeSet))
{
recipeSet.Remove(recipeId);
}
public bool TryAddTodayCookware(ItemSlotUi itemSlotUi)
EventBus.Broadcast(evt);
}
return removed;
}
public bool TryAddTodayCookware(ItemViewModel model)
{
var itemId = itemSlotUi.Model.Id;
var cookwareId = model.Id;
if (itemSlotUi.Model.Count <= 0 || DataManager.Instance.GetDataSo<CookwareDataSo>().TryGetDataById(itemId, out CookwareData cookwareData) == false) return false;
if (model.HasItem == false || DataManager.Instance.GetDataSo<CookwareDataSo>().ContainsData(cookwareId) == false) return false;
if (_todayCookwareIds.Count >= MaxCookwareCount || _todayCookwareIds.Contains(itemId)) return false;
if (_cookwareToRecipeIds.Count >= MaxCookwareCount || _cookwareToRecipeIds.ContainsKey(cookwareId)) return false;
_cookwareToRecipeIds[cookwareId] = new HashSet<string>();
foreach (var recipeId in _todayFoodRecipeIds.Keys.Concat(_todayDrinkRecipeIds.Keys))
{
var required = GetRequiredCookwareKey(recipeId);
if (required == cookwareId)
{
_cookwareToRecipeIds[cookwareId].Add(recipeId);
}
}
_todayCookwareIds.Add(itemId);
EventBus.Broadcast(RestaurantEvents.TodayMenuAddedEvent);
return true;
}
public bool TryRemoveTodayCookware(ItemSlotUi itemSlotUi)
public bool IsContainTodayMenu(string recipeId)=> _todayFoodRecipeIds.ContainsKey(recipeId) || _todayDrinkRecipeIds.ContainsKey(recipeId);
public bool TryRemoveTodayCookware(ItemViewModel model)
{
var itemId = itemSlotUi.Model.Id;
var cookwareId = model.Id;
if (DataManager.Instance.GetDataSo<CookwareDataSo>().TryGetDataById(itemId, out CookwareData cookwareData) == false) return false;
if (DataManager.Instance.GetDataSo<CookwareDataSo>().ContainsData(cookwareId) == false) return false;
if (_todayCookwareIds.Remove(itemId) == false) return false;
if (_cookwareToRecipeIds.Remove(cookwareId) == false) return false;
EventBus.Broadcast( RestaurantEvents.TodayMenuRemovedEvent);
var evt = RestaurantEvents.TodayMenuRemovedEvent;
evt.InventoryCategoryType = InventoryCategoryType.Cookware;
EventBus.Broadcast(evt);
return true;
}
public bool IsContainTodayMenu(string recipeId)=> _todayFoodRecipeIds.ContainsKey(recipeId) || _todayDrinkRecipeIds.ContainsKey(recipeId);
private string GetRequiredCookwareKey(string recipeId)
{
if (DataManager.Instance.GetDataSo<RecipeDataSo>().TryGetDataById(recipeId, out var recipeData) == false) return null;
var resultKey = recipeData.RecipeResult;
return recipeData.RecipeType switch
{
RecipeType.FoodRecipe => DataManager.Instance.GetDataSo<FoodDataSo>().GetDataById(resultKey).CookwareKey,
RecipeType.DrinkRecipe => DataManager.Instance.GetDataSo<DrinkDataSo>().GetDataById(resultKey).CookwareKey,
_ => null
};
}
public bool IsCookwareMatched(string recipeId)
{
return _cookwareToRecipeIds.Values.Any(recipeHashSets => recipeHashSets.Contains(recipeId));
}
}
}

View File

@ -7,7 +7,7 @@ public class InventorySlotUiStrategy : IItemSlotUiStrategy
{
public string AnimatorControllerKey => "InventorySlotUi";
public void Setup(ItemSlotUi ui, ItemViewModel model)
public Task Setup(ItemSlotUi ui, ItemViewModel model)
{
if (InventoryManager.Instance.ContainInventoryItem(model.Id))
{
@ -15,7 +15,8 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
ui.ShowCountText();
ui.HideMark();
ui.SetButtonInteractable(true);
return;
return Task.CompletedTask;
}
// TODO : 임시 초기화 값
@ -36,6 +37,8 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
ui.HideCountText();
ui.HideMark();
ui.SetButtonInteractable(false);
return Task.CompletedTask;
}
public async Task<RuntimeAnimatorController> GetAnimatorController()

View File

@ -19,6 +19,8 @@ public class InventoryView : MonoBehaviour, IEventHandler<InventoryChangedEvent>
private const string ItemSlotUiName = "ItemSlotUi_";
public GameObject GetInitialSelected() => _firstSlot;
private void OnEnable()
{
EventBus.Register<InventoryChangedEvent>(this);
@ -33,8 +35,6 @@ private void OnDisable()
EventBus.Unregister<TodayMenuRemovedEvent>(this);
}
public GameObject GetInitialSelected() => _firstSlot;
public async Task Initialize()
{
_restaurantManagementSo =
@ -92,7 +92,7 @@ private IEnumerable<ItemSlotUi> SortSlots(IEnumerable<ItemSlotUi> slots)
public void UpdateCategoryView(InventoryCategoryType category)
{
_currenInventoryCategoryType = category;
_firstSlot = null;
GameObject firstValidSlot = null;
var filteredSlots = _slotLookup.Values;
var sortedSlots = SortSlots(filteredSlots);
@ -114,12 +114,14 @@ public void UpdateCategoryView(InventoryCategoryType category)
{
slot.transform.SetSiblingIndex(siblingIndex++);
if (_firstSlot == null)
if (firstValidSlot == null)
{
_firstSlot = slot.gameObject;
firstValidSlot = slot.gameObject;
}
}
}
_firstSlot = firstValidSlot;
}
private bool MatchesCategory(ItemViewModel model, InventoryCategoryType category)

View File

@ -6,7 +6,7 @@ namespace DDD
public interface IItemSlotUiStrategy
{
string AnimatorControllerKey { get; }
void Setup(ItemSlotUi ui, ItemViewModel model);
Task Setup(ItemSlotUi ui, ItemViewModel model);
Task<RuntimeAnimatorController> GetAnimatorController();
}
}

View File

@ -26,7 +26,7 @@ public async Task Initialize(ItemViewModel model, IItemSlotUiStrategy strategy)
var controller = await strategy.GetAnimatorController();
_animator.runtimeAnimatorController = controller;
Strategy.Setup(this, model);
_ = Strategy.Setup(this, model);
}
public void SetIcon(Sprite sprite) => _icon.sprite = sprite;

View File

@ -172,16 +172,7 @@ private void OnCategoryTabSelected(InventoryCategoryType category)
public void Invoke(TodayMenuRemovedEvent evt)
{
InventoryCategoryType newInventoryCategoryType = evt.RecipeType switch
{
RecipeType.FoodRecipe => InventoryCategoryType.Food,
RecipeType.DrinkRecipe => InventoryCategoryType.Drink,
_ => InventoryCategoryType.None
};
if (newInventoryCategoryType == InventoryCategoryType.None) return;
_menuCategoryTabs.SelectTab(newInventoryCategoryType);
_menuCategoryTabs.SelectTab(evt.InventoryCategoryType);
}
}
}

View File

@ -8,7 +8,7 @@ public void OnAdded(ItemSlotUi itemSlotUi, RestaurantManagementSo restaurantMana
if (inventorySlotUiStrategy.CanCrafting(itemSlotUi))
{
restaurantManagementSo.TryAddTodayMenu(itemSlotUi);
restaurantManagementSo.TryAddTodayMenu(itemSlotUi.Model);
}
else
{
@ -25,7 +25,7 @@ public void OnRemoved(ItemSlotUi itemSlotUi, RestaurantManagementSo restaurantMa
{
if (itemSlotUi.Strategy is InventorySlotUiStrategy) return;
restaurantManagementSo.TryRemoveTodayMenu(itemSlotUi);
restaurantManagementSo.TryRemoveTodayMenu(itemSlotUi.Model);
}
}
}

View File

@ -6,6 +6,7 @@ namespace DDD
public class TodayMenuSlotUiStrategy : IItemSlotUiStrategy
{
private readonly RecipeType _recipeType;
private RestaurantManagementSo _restaurantManagementSo;
public string AnimatorControllerKey => "TodayMenuSlotUi";
@ -14,8 +15,10 @@ public TodayMenuSlotUiStrategy(RecipeType recipeType)
_recipeType = recipeType;
}
public void Setup(ItemSlotUi ui, ItemViewModel model)
public async Task Setup(ItemSlotUi ui, ItemViewModel model)
{
_restaurantManagementSo = await AssetManager.LoadAsset<RestaurantManagementSo>(DataConstants.RestaurantManagementSo);
if (model == null)
{
string emptySpriteKey = null;
@ -32,12 +35,22 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
ui.HideCountText();
ui.HideMark();
ui.SetButtonInteractable(false);
return;
}
string markSpriteKey = null;
if (_restaurantManagementSo.IsCookwareMatched(ui.Model.Id))
{
markSpriteKey = SpriteConstants.CheckYesSpriteKey;
}
else
{
markSpriteKey = SpriteConstants.CheckNoSpriteKey;
}
ui.SetIcon(model.ItemSprite);
ui.HideCountText();
ui.ShowMark(DataManager.Instance.GetSprite(SpriteConstants.CheckNoSpriteKey)); // TODO : 추후에 장비와 매칭
ui.ShowMark(DataManager.Instance.GetSprite(markSpriteKey));
ui.SetButtonInteractable(true);
}

View File

@ -8,7 +8,7 @@ public void OnAdded(ItemSlotUi itemSlotUi, RestaurantManagementSo restaurantMana
if (inventorySlotUiStrategy.CanCrafting(itemSlotUi))
{
restaurantManagementSo.TryAddTodayCookware(itemSlotUi);
restaurantManagementSo.TryAddTodayCookware(itemSlotUi.Model);
}
else
{
@ -25,7 +25,7 @@ public void OnRemoved(ItemSlotUi itemSlotUi, RestaurantManagementSo restaurantMa
{
if (itemSlotUi.Strategy is InventorySlotUiStrategy) return;
restaurantManagementSo.TryRemoveTodayCookware(itemSlotUi);
restaurantManagementSo.TryRemoveTodayCookware(itemSlotUi.Model);
}
}
}

View File

@ -9,7 +9,7 @@ public class TodayCookwareSlotUiStrategy : IItemSlotUiStrategy
public string AnimatorControllerKey => "TodayMenuSlotUi";
public void Setup(ItemSlotUi ui, ItemViewModel model)
public Task Setup(ItemSlotUi ui, ItemViewModel model)
{
if (model == null)
{
@ -17,13 +17,16 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
ui.HideCountText();
ui.HideMark();
ui.SetButtonInteractable(false);
return;
return Task.CompletedTask;
}
ui.SetIcon(model.ItemSprite);
ui.HideCountText();
ui.ShowMark(DataManager.Instance.GetSprite(SpriteConstants.CheckNoSpriteKey)); // TODO : 추후에 장비와 매칭
ui.SetButtonInteractable(true);
return Task.CompletedTask;
}
public async Task<RuntimeAnimatorController> GetAnimatorController()

View File

@ -101,7 +101,7 @@ private void UpdateView()
}
int cookwareIndex = 0;
foreach (var cookwareKey in _restaurantManagementSo.TodayCookwareIds)
foreach (var cookwareKey in _restaurantManagementSo.CookwareToRecipeIds.Keys)
{
if (cookwareIndex >= _cookwareSlots.Count) break;

View File

@ -9,7 +9,7 @@ public class TodayWorkerSlotUiStrategy : IItemSlotUiStrategy
public string AnimatorControllerKey => "TodayMenuSlotUi";
public void Setup(ItemSlotUi ui, ItemViewModel model)
public Task Setup(ItemSlotUi ui, ItemViewModel model)
{
if (model == null)
{
@ -17,13 +17,16 @@ public void Setup(ItemSlotUi ui, ItemViewModel model)
ui.HideCountText();
ui.HideMark();
ui.SetButtonInteractable(false);
return;
return Task.CompletedTask;
}
ui.SetIcon(model.ItemSprite);
ui.HideCountText();
ui.ShowMark(DataManager.Instance.GetSprite(SpriteConstants.CheckNoSpriteKey)); // TODO : 추후에 장비와 매칭
ui.SetButtonInteractable(true);
return Task.CompletedTask;
}
public async Task<RuntimeAnimatorController> GetAnimatorController()