diff --git a/Assets/_DDD/_Scripts/GameEvent/GameEvents.cs b/Assets/_DDD/_Scripts/GameEvent/GameEvents.cs index 364e9580a..50aa2a319 100644 --- a/Assets/_DDD/_Scripts/GameEvent/GameEvents.cs +++ b/Assets/_DDD/_Scripts/GameEvent/GameEvents.cs @@ -98,7 +98,7 @@ public class TodayMenuAddedEvent : IEvent {} public class TodayMenuRemovedEvent : IEvent { - public RecipeType RecipeType; + public InventoryCategoryType InventoryCategoryType; } #endregion diff --git a/Assets/_DDD/_Scripts/GameState/RestaurantManagementSo.cs b/Assets/_DDD/_Scripts/GameState/RestaurantManagementSo.cs index 2dc40859a..3f40aad3d 100644 --- a/Assets/_DDD/_Scripts/GameState/RestaurantManagementSo.cs +++ b/Assets/_DDD/_Scripts/GameState/RestaurantManagementSo.cs @@ -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 _todayFoodRecipeIds = new(); [ReadOnly, ShowInInspector] private Dictionary _todayDrinkRecipeIds = new(); [ReadOnly, ShowInInspector] private List _todayWorkerIds = new(); - [ReadOnly, ShowInInspector] private List _todayCookwareIds = new(); + [ReadOnly, ShowInInspector] private Dictionary> _cookwareToRecipeIds = new(); public IReadOnlyDictionary TodayFoodRecipeIds => _todayFoodRecipeIds; public IReadOnlyDictionary TodayDrinkRecipeIds => _todayDrinkRecipeIds; public IReadOnlyList TodayWorkerIds => _todayWorkerIds; - public IReadOnlyList TodayCookwareIds => _todayCookwareIds; + public IReadOnlyDictionary> 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().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().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().TryGetDataById(recipeId, out RecipeData recipeData)) return false; + if (DataManager.Instance.GetDataSo().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; + if (removed) + { + var cookwareKey = GetRequiredCookwareKey(recipeId); + if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeIds.TryGetValue(cookwareKey, out var recipeSet)) + { + recipeSet.Remove(recipeId); + } - EventBus.Broadcast(evt); - return true; + EventBus.Broadcast(evt); + } + + return removed; } - public bool TryAddTodayCookware(ItemSlotUi itemSlotUi) + public bool TryAddTodayCookware(ItemViewModel model) { - var itemId = itemSlotUi.Model.Id; + var cookwareId = model.Id; - if (itemSlotUi.Model.Count <= 0 || DataManager.Instance.GetDataSo().TryGetDataById(itemId, out CookwareData cookwareData) == false) return false; + if (model.HasItem == false || DataManager.Instance.GetDataSo().ContainsData(cookwareId) == false) return false; - if (_todayCookwareIds.Count >= MaxCookwareCount || _todayCookwareIds.Contains(itemId)) return false; - - _todayCookwareIds.Add(itemId); + if (_cookwareToRecipeIds.Count >= MaxCookwareCount || _cookwareToRecipeIds.ContainsKey(cookwareId)) return false; + + _cookwareToRecipeIds[cookwareId] = new HashSet(); + + foreach (var recipeId in _todayFoodRecipeIds.Keys.Concat(_todayDrinkRecipeIds.Keys)) + { + var required = GetRequiredCookwareKey(recipeId); + if (required == cookwareId) + { + _cookwareToRecipeIds[cookwareId].Add(recipeId); + } + } + EventBus.Broadcast(RestaurantEvents.TodayMenuAddedEvent); return true; } + + public bool IsContainTodayMenu(string recipeId)=> _todayFoodRecipeIds.ContainsKey(recipeId) || _todayDrinkRecipeIds.ContainsKey(recipeId); - public bool TryRemoveTodayCookware(ItemSlotUi itemSlotUi) + public bool TryRemoveTodayCookware(ItemViewModel model) { - var itemId = itemSlotUi.Model.Id; + var cookwareId = model.Id; - if (DataManager.Instance.GetDataSo().TryGetDataById(itemId, out CookwareData cookwareData) == false) return false; + if (DataManager.Instance.GetDataSo().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; } + + private string GetRequiredCookwareKey(string recipeId) + { + if (DataManager.Instance.GetDataSo().TryGetDataById(recipeId, out var recipeData) == false) return null; - public bool IsContainTodayMenu(string recipeId)=> _todayFoodRecipeIds.ContainsKey(recipeId) || _todayDrinkRecipeIds.ContainsKey(recipeId); + var resultKey = recipeData.RecipeResult; + + return recipeData.RecipeType switch + { + RecipeType.FoodRecipe => DataManager.Instance.GetDataSo().GetDataById(resultKey).CookwareKey, + RecipeType.DrinkRecipe => DataManager.Instance.GetDataSo().GetDataById(resultKey).CookwareKey, + _ => null + }; + } + + public bool IsCookwareMatched(string recipeId) + { + return _cookwareToRecipeIds.Values.Any(recipeHashSets => recipeHashSets.Contains(recipeId)); + } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs index b9b9cc6ec..17570e58b 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventorySlotUiStrategy.cs @@ -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 GetAnimatorController() diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventoryView.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventoryView.cs index 2e7a0090c..fb715f15e 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventoryView.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/InventoryUi/InventoryView.cs @@ -18,6 +18,8 @@ public class InventoryView : MonoBehaviour, IEventHandler private InventorySortType _currentSortType = InventorySortType.None; private const string ItemSlotUiName = "ItemSlotUi_"; + + public GameObject GetInitialSelected() => _firstSlot; private void OnEnable() { @@ -33,8 +35,6 @@ private void OnDisable() EventBus.Unregister(this); } - public GameObject GetInitialSelected() => _firstSlot; - public async Task Initialize() { _restaurantManagementSo = @@ -92,7 +92,7 @@ private IEnumerable SortSlots(IEnumerable 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) diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/IItemSlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/IItemSlotUiStrategy.cs index ba3b99566..ac0ed5bf0 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/IItemSlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/IItemSlotUiStrategy.cs @@ -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 GetAnimatorController(); } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/ItemSlotUi.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/ItemSlotUi.cs index cb28a31fd..07584f8c3 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/ItemSlotUi.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/ItemUi/ItemSlotUi.cs @@ -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; diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/RestaurantManagementUi.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/RestaurantManagementUi.cs index a57817096..bf850249a 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/RestaurantManagementUi.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/RestaurantManagementUi.cs @@ -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); } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs index 7e976f5e7..ce2b6e936 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuInteractorStrategy.cs @@ -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); } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs index b95fb9b9e..ad1d5ee36 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayMenuUi/TodayMenuSlotUiStrategy.cs @@ -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(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); } diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs index 6307ef45a..3c912097d 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareInteractorStrategy.cs @@ -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); } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs index 445f90a50..08487cb1f 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayCookwareSlotUiStrategy.cs @@ -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 GetAnimatorController() diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs index 2de616ab6..55c9a59e8 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayRestaurantStateView.cs @@ -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; diff --git a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs index 7b40bf9ad..6296f6deb 100644 --- a/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs +++ b/Assets/_DDD/_Scripts/GameUi/RestaurantManagementUi/TodayRestaurantStateUi/TodayWorkerSlotUiStrategy.cs @@ -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 GetAnimatorController()