using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sirenix.OdinInspector; using UnityEngine; namespace DDD { [CreateAssetMenu(fileName = "RestaurantManagementSo", menuName = "GameState/RestaurantManagementSo")] public class RestaurantManagementSo : GameFlowTask { // TODO : 체크리스트 기능 public ItemSlotUi ItemSlotUiPrefab; [Title("선택된 메뉴 상세 내용")] public TasteHashTagSlotUi TasteHashTagSlotUiPrefab; public Color FoodTasteOutlineColor = Color.magenta; public Color DrinkTasteOutlineColor = Color.magenta; [Title("오늘의 레스토랑 상태")] public int MaxFoodCount = 8; public int MaxDrinkCount = 6; public int MaxCookwareCount = 6; [Title("실시간 데이터")] [ReadOnly, ShowInInspector] private Dictionary _todayFoodRecipeIds = new(); [ReadOnly, ShowInInspector] private Dictionary _todayDrinkRecipeIds = new(); [ReadOnly, ShowInInspector] private List _todayWorkerIds = new(); [ReadOnly, ShowInInspector] private Dictionary> _cookwareToRecipeIds = new(); public IReadOnlyDictionary TodayFoodRecipeIds => _todayFoodRecipeIds; public IReadOnlyDictionary TodayDrinkRecipeIds => _todayDrinkRecipeIds; public IReadOnlyList TodayWorkerIds => _todayWorkerIds; public IReadOnlyDictionary> CookwareToRecipeIds => _cookwareToRecipeIds; public override Task OnReadyNewFlow(GameFlowState newFlowState) { if (newFlowState == GameFlowState.ReadyForRestaurant) { InitializeReadyForRestaurant(); } return Task.CompletedTask; } private void InitializeReadyForRestaurant() { _todayFoodRecipeIds.Clear(); _todayDrinkRecipeIds.Clear(); _todayWorkerIds.Clear(); _cookwareToRecipeIds.Clear(); } public bool IsOpenable() { // TODO : 영업 가능한 상태인지 조건 추가 (최소 요리, 요리도구 배치 등) bool isExistedCookware = CookwareToRecipeIds.Count > 0; bool isExistedMatchedMenu = _cookwareToRecipeIds.Values.Any(recipeSet => recipeSet is { Count: > 0 }); return isExistedCookware && isExistedMatchedMenu; } 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; if (recipeData.RecipeType == RecipeType.FoodRecipe) { if (_todayFoodRecipeIds.Count >= MaxFoodCount || _todayFoodRecipeIds.ContainsKey(recipeId)) return false; var foodData = DataManager.Instance.GetDataSo().GetDataById(recipeData.RecipeResult); var craftableCount = foodData.GetCraftableCount(); foodData.ConsumeAllCraftableIngredients(); _todayFoodRecipeIds[recipeId] = craftableCount; added = true; } else if (recipeData.RecipeType == RecipeType.DrinkRecipe) { if (_todayDrinkRecipeIds.Count >= MaxDrinkCount || _todayDrinkRecipeIds.ContainsKey(recipeId)) return false; var drinkData = DataManager.Instance.GetDataSo().GetDataById(recipeData.RecipeResult); var craftableCount = drinkData.GetCraftableCount(); drinkData.ConsumeAllCraftableIngredients(); _todayDrinkRecipeIds[recipeId] = craftableCount; added = true; } 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(ItemViewModel model) { string recipeId = model.Id; var evt = RestaurantEvents.TodayMenuRemovedEvent; if (DataManager.Instance.GetDataSo().TryGetDataById(recipeId, out RecipeData recipeData) == false) return false; bool removed = false; int refundCount = 0; if (recipeData.RecipeType == RecipeType.FoodRecipe) { if (_todayFoodRecipeIds.TryGetValue(recipeId, out refundCount)) { removed = _todayFoodRecipeIds.Remove(recipeId); evt.InventoryCategoryType = InventoryCategoryType.Food; if (removed) { var foodData = DataManager.Instance.GetDataSo().GetDataById(recipeData.RecipeResult); foodData.RefundIngredients(refundCount); } } } else if (recipeData.RecipeType == RecipeType.DrinkRecipe) { if (_todayDrinkRecipeIds.TryGetValue(recipeId, out refundCount)) { removed = _todayDrinkRecipeIds.Remove(recipeId); evt.InventoryCategoryType = InventoryCategoryType.Drink; if (removed) { var drinkData = DataManager.Instance.GetDataSo().GetDataById(recipeData.RecipeResult); drinkData.RefundIngredients(refundCount); } } } if (removed) { var cookwareKey = GetRequiredCookwareKey(recipeId); if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeIds.TryGetValue(cookwareKey, out var recipeSet)) { recipeSet.Remove(recipeId); } EventBus.Broadcast(evt); } return removed; } public bool TryAddTodayCookware(ItemViewModel model) { var cookwareId = model.Id; if (model.HasItem == false || DataManager.Instance.GetDataSo().ContainsData(cookwareId) == false) return false; 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(ItemViewModel model) { var cookwareId = model.Id; if (DataManager.Instance.GetDataSo().ContainsData(cookwareId) == false) return false; if (_cookwareToRecipeIds.Remove(cookwareId) == false) return false; 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; 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)); } } }