diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs b/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs index 172e0487b..8ff387554 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/Cosmetic/InteractableHighlight.cs @@ -26,10 +26,16 @@ public struct InteractionOutlineData public float Opacity; } + public interface IInteractionHighlight + { + void RegisterHighlightProxy(GameObject highlightProxyObject); + void ClearHighlightProxy(); + } + [RequireComponent(typeof(HighlightEffect))] [RequireComponent(typeof(RestaurantInteractionComponent))] [AddComponentMenu("DDD/Interaction/InteractableHighlight")] - public class InteractableHighlight : MonoBehaviour + public class InteractableHighlight : MonoBehaviour, IInteractionHighlight { [Title("Outline Styles")] [SerializeField] private InteractionOutlineData _availableStyle = new() {Color = Color.white, Width = 1f, Opacity = 1f}; @@ -66,7 +72,7 @@ public class InteractableHighlight : MonoBehaviour private RestaurantInteractionComponent _interactionComponent; private IInteractor _interactor; private InteractionOutlineType _lastAppliedType = InteractionOutlineType.None; -` + private void Awake() { // OutlineData 딕셔너리 초기화 @@ -85,13 +91,14 @@ private HighlightEffect GetHighlightComponent() return _highlightProxy? _highlightProxy : _highlightComponent; } - public void RegisterHighlightProxy(HighlightEffect highlightProxy) + public void RegisterHighlightProxy(GameObject highlightProxyObject) { + var highlightProxy = highlightProxyObject.GetComponent(); _highlightProxy = highlightProxy; ApplyHighlightSettings(highlightProxy); } - public void UnregisterHighlightProxy() + public void ClearHighlightProxy() { _highlightProxy = null; } diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs index f006c3e85..99e36aa31 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/RestaurantInteractionEvents.cs @@ -57,10 +57,10 @@ public bool RequestInteraction(GameObject causer, GameObject target, Interaction // Cast solverComponent to IInteractable if (solver is not null && interactor is not null) { - bool canExecute = solver.CanExecuteInteraction(interactor, interactable, payload); + bool canExecute = solver.CanExecuteInteraction(interactor, interactable, evt.Payload); if (canExecute) { - evt.EventResult = solver.ExecuteInteraction(interactor, interactable, payload); + evt.EventResult = solver.ExecuteInteraction(interactor, interactable, evt.Payload); } else { diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs b/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs index ecdda7900..369947a00 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Order.cs @@ -1,11 +1,43 @@ using UnityEngine; +using UnityEngine.Serialization; namespace DDD.Restaurant { + public class RestaurantOrderMenuPayload : ScriptableObject + { + [SerializeField] private string _menuId; + public string MenuId + { + get => _menuId; + set => _menuId = value; + } + } + public class RestaurantOrderSolver_Order : RestaurantOrderSolverBase { public override bool ExecuteInteractionSubsystem(IInteractor interactor, IInteractable interactable, ScriptableObject payload = null) { + // Clear interaction highlight proxy + var highlightObject = interactable?.GetInteractableGameObject(); + var highlightComponent = highlightObject?.GetComponent(); + highlightComponent?.ClearHighlightProxy(); + + // Pick random menu from today's menu list + var foodCandidates = RestaurantState.Instance.ManagementState.GetTodayFoodMenus(); + if (foodCandidates == null || foodCandidates.Count == 0) + { + Debug.LogError("[RestaurantOrderSolver_Order] No food menu found"); + return false; + } + + // TODO : 손님 데이터를 바탕으로 선호하는 음식을 골라야 할수도 있음. interactable에서 직접 가져오거나 payload로 전달받아야 함. payload를 받을 경우 RestaurantOrderMenuPayload와 통합해야함 + var foodMenu = foodCandidates[Random.Range(0, foodCandidates.Count)]; + + // Create payload and set the menu + RestaurantOrderMenuPayload orderPayload = ScriptableObject.CreateInstance(); + orderPayload.MenuId = foodMenu; + payload = orderPayload; + return base.ExecuteInteractionSubsystem(interactor, interactable, payload); } diff --git a/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Reserved.cs b/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Reserved.cs index cdd9bf324..e7bd285c3 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Reserved.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Event/Solvers/RestaurantOrders/RestaurantOrderSolver_Reserved.cs @@ -6,6 +6,10 @@ public class RestaurantOrderSolver_Reserved : RestaurantOrderSolverBase { public override bool ExecuteInteractionSubsystem(IInteractor interactor, IInteractable interactable, ScriptableObject payload = null) { + // Register interaction highlight proxy as interactor + var highlightObject = interactable?.GetInteractableGameObject(); + var highlightComponent = highlightObject?.GetComponent(); + highlightComponent?.RegisterHighlightProxy(interactor?.GetInteractorGameObject()); return base.ExecuteInteractionSubsystem(interactor, interactable, payload); } diff --git a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantManagementState.cs b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantManagementState.cs index 72747e35b..727541fe9 100644 --- a/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantManagementState.cs +++ b/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantManagementState.cs @@ -7,32 +7,32 @@ namespace DDD.Restaurant { public class RestaurantManagementState : ScriptableObject { - private Dictionary _todayFoodRecipeIds = new(); - private Dictionary _todayDrinkRecipeIds = new(); - private List _todayWorkerIds = new(); - private Dictionary> _cookwareToRecipeIds = new(); + private Dictionary _todayFoodRecipeAndAmounts = new(); + private Dictionary _todayDrinkRecipeAndAmounts = new(); + private List _todayWorkers = new(); + private Dictionary> _cookwareToRecipeMapping = new(); - public IReadOnlyDictionary TodayFoodRecipeIds => _todayFoodRecipeIds; - public IReadOnlyDictionary TodayDrinkRecipeIds => _todayDrinkRecipeIds; - public IReadOnlyList TodayWorkerIds => _todayWorkerIds; - public IReadOnlyDictionary> CookwareToRecipeIds => _cookwareToRecipeIds; + public IReadOnlyDictionary TodayFoodRecipeAndAmounts => _todayFoodRecipeAndAmounts; + public IReadOnlyDictionary TodayDrinkRecipeAndAmounts => _todayDrinkRecipeAndAmounts; + public IReadOnlyList TodayWorkers => _todayWorkers; + public IReadOnlyDictionary> CookwareToRecipeMapping => _cookwareToRecipeMapping; public int AddedTodayMenuCount => AddedTodayFoodCount + AddedTodayDrinkCount; - public int AddedTodayFoodCount => _todayFoodRecipeIds.Count; - public int AddedTodayDrinkCount => _todayDrinkRecipeIds.Count; - public int AddedTodayWorkerCount => _todayWorkerIds.Count; - public int AddedTodayCookwareCount => _cookwareToRecipeIds.Count; - public int MatchedTodayMenuWithCookwareCount => _cookwareToRecipeIds.Values.Count(recipeSet => recipeSet.Count > 0); + public int AddedTodayFoodCount => _todayFoodRecipeAndAmounts.Count; + public int AddedTodayDrinkCount => _todayDrinkRecipeAndAmounts.Count; + public int AddedTodayWorkerCount => _todayWorkers.Count; + public int AddedTodayCookwareCount => _cookwareToRecipeMapping.Count; + public int MatchedTodayMenuWithCookwareCount => _cookwareToRecipeMapping.Values.Count(recipeSet => recipeSet.Count > 0); private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData; public void InitializeReadyForRestaurant() { // TODO : Load from disk if possible (save data) - _todayFoodRecipeIds.Clear(); - _todayDrinkRecipeIds.Clear(); - _todayWorkerIds.Clear(); - _cookwareToRecipeIds.Clear(); + _todayFoodRecipeAndAmounts.Clear(); + _todayDrinkRecipeAndAmounts.Clear(); + _todayWorkers.Clear(); + _cookwareToRecipeMapping.Clear(); } /// @@ -50,24 +50,34 @@ public bool[] GetChecklistStates() public bool HasFoodRecipes() { - return _todayFoodRecipeIds.Count > 0; + return _todayFoodRecipeAndAmounts.Count > 0; } public bool HasCookwares() { - return _cookwareToRecipeIds.Count > 0; + return _cookwareToRecipeMapping.Count > 0; } public bool HasMatchedMenuWithCookware() { - return _cookwareToRecipeIds.Values.Any(recipeSet => recipeSet.Count > 0); + return _cookwareToRecipeMapping.Values.Any(recipeSet => recipeSet.Count > 0); + } + + public List GetTodayFoodMenus() + { + return _todayFoodRecipeAndAmounts.Keys.ToList(); + } + + public int GetTodayFoodAvailableCount(string recipeId) + { + return _todayFoodRecipeAndAmounts.GetValueOrDefault(recipeId, 0); } public bool IsOpenable() { // TODO : 영업 가능한 상태인지 조건 추가 (최소 요리, 요리도구 배치 등) - bool isExistedCookware = CookwareToRecipeIds.Count > 0; - bool isExistedMatchedMenu = _cookwareToRecipeIds.Values.Any(recipeSet => recipeSet is { Count: > 0 }); + bool isExistedCookware = CookwareToRecipeMapping.Count > 0; + bool isExistedMatchedMenu = _cookwareToRecipeMapping.Values.Any(recipeSet => recipeSet is { Count: > 0 }); var isOpenable = isExistedCookware && isExistedMatchedMenu; return isOpenable; @@ -85,31 +95,31 @@ public bool TryAddTodayMenu(ItemModel model) if (recipeData.RecipeType == RecipeType.FoodRecipe) { - if (_todayFoodRecipeIds.Count >= GetRestaurantManagementData().MaxFoodCount || _todayFoodRecipeIds.ContainsKey(recipeId)) return false; + if (_todayFoodRecipeAndAmounts.Count >= GetRestaurantManagementData().MaxFoodCount || _todayFoodRecipeAndAmounts.ContainsKey(recipeId)) return false; var foodData = DataManager.Instance.GetDataAsset().GetDataById(recipeData.RecipeResult); var craftableCount = foodData.GetCraftableCount(); foodData.ConsumeAllCraftableIngredients(); - _todayFoodRecipeIds[recipeId] = craftableCount; + _todayFoodRecipeAndAmounts[recipeId] = craftableCount; added = true; } else if (recipeData.RecipeType == RecipeType.DrinkRecipe) { - if (_todayDrinkRecipeIds.Count >= GetRestaurantManagementData().MaxDrinkCount || _todayDrinkRecipeIds.ContainsKey(recipeId)) return false; + if (_todayDrinkRecipeAndAmounts.Count >= GetRestaurantManagementData().MaxDrinkCount || _todayDrinkRecipeAndAmounts.ContainsKey(recipeId)) return false; var drinkData = DataManager.Instance.GetDataAsset().GetDataById(recipeData.RecipeResult); var craftableCount = drinkData.GetCraftableCount(); drinkData.ConsumeAllCraftableIngredients(); - _todayDrinkRecipeIds[recipeId] = craftableCount; + _todayDrinkRecipeAndAmounts[recipeId] = craftableCount; added = true; } if (added) { var cookwareKey = GetRequiredCookwareKey(recipeId); - if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeIds.TryGetValue(cookwareKey, out var recipeSet)) + if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeMapping.TryGetValue(cookwareKey, out var recipeSet)) { recipeSet.Add(recipeId); } @@ -135,9 +145,9 @@ public bool TryRemoveTodayMenu(ItemModel model) if (recipeData.RecipeType == RecipeType.FoodRecipe) { - if (_todayFoodRecipeIds.TryGetValue(recipeId, out refundCount)) + if (_todayFoodRecipeAndAmounts.TryGetValue(recipeId, out refundCount)) { - removed = _todayFoodRecipeIds.Remove(recipeId); + removed = _todayFoodRecipeAndAmounts.Remove(recipeId); removedEvt.InventoryCategoryType = InventoryCategoryType.Food; if (removed) @@ -149,9 +159,9 @@ public bool TryRemoveTodayMenu(ItemModel model) } else if (recipeData.RecipeType == RecipeType.DrinkRecipe) { - if (_todayDrinkRecipeIds.TryGetValue(recipeId, out refundCount)) + if (_todayDrinkRecipeAndAmounts.TryGetValue(recipeId, out refundCount)) { - removed = _todayDrinkRecipeIds.Remove(recipeId); + removed = _todayDrinkRecipeAndAmounts.Remove(recipeId); removedEvt.InventoryCategoryType = InventoryCategoryType.Drink; if (removed) @@ -165,7 +175,7 @@ public bool TryRemoveTodayMenu(ItemModel model) if (removed) { var cookwareKey = GetRequiredCookwareKey(recipeId); - if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeIds.TryGetValue(cookwareKey, out var recipeSet)) + if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeMapping.TryGetValue(cookwareKey, out var recipeSet)) { recipeSet.Remove(recipeId); } @@ -185,16 +195,16 @@ public bool TryAddTodayCookware(ItemModel model) if (model.HasItem == false || DataManager.Instance.GetDataAsset().ContainsData(cookwareId) == false) return false; - if (_cookwareToRecipeIds.Count >= GetRestaurantManagementData().MaxCookwareCount || _cookwareToRecipeIds.ContainsKey(cookwareId)) return false; + if (_cookwareToRecipeMapping.Count >= GetRestaurantManagementData().MaxCookwareCount || _cookwareToRecipeMapping.ContainsKey(cookwareId)) return false; - _cookwareToRecipeIds[cookwareId] = new HashSet(); + _cookwareToRecipeMapping[cookwareId] = new HashSet(); - foreach (var recipeId in _todayFoodRecipeIds.Keys.Concat(_todayDrinkRecipeIds.Keys)) + foreach (var recipeId in _todayFoodRecipeAndAmounts.Keys.Concat(_todayDrinkRecipeAndAmounts.Keys)) { var required = GetRequiredCookwareKey(recipeId); if (required == cookwareId) { - _cookwareToRecipeIds[cookwareId].Add(recipeId); + _cookwareToRecipeMapping[cookwareId].Add(recipeId); } } @@ -206,7 +216,7 @@ public bool TryAddTodayCookware(ItemModel model) return true; } - public bool IsContainTodayMenu(string recipeId) => _todayFoodRecipeIds.ContainsKey(recipeId) || _todayDrinkRecipeIds.ContainsKey(recipeId); + public bool IsContainTodayMenu(string recipeId) => _todayFoodRecipeAndAmounts.ContainsKey(recipeId) || _todayDrinkRecipeAndAmounts.ContainsKey(recipeId); public bool TryRemoveTodayCookware(ItemModel model) { @@ -214,7 +224,7 @@ public bool TryRemoveTodayCookware(ItemModel model) if (DataManager.Instance.GetDataAsset().ContainsData(cookwareId) == false) return false; - if (_cookwareToRecipeIds.Remove(cookwareId) == false) return false; + if (_cookwareToRecipeMapping.Remove(cookwareId) == false) return false; var dirtyEvt = GameEvents.SmartVariablesDirtyEvent; dirtyEvt.DomainFlags = SmartVariablesDomain.RestaurantToday; @@ -242,12 +252,12 @@ private string GetRequiredCookwareKey(string recipeId) public bool IsCookwareMatched(string recipeId) { - return _cookwareToRecipeIds.Values.Any(recipeHashSets => recipeHashSets.Contains(recipeId)); + return _cookwareToRecipeMapping.Values.Any(recipeHashSets => recipeHashSets.Contains(recipeId)); } public bool IsTodayMenuMatched(string cookwareId) { - if (_cookwareToRecipeIds.TryGetValue(cookwareId, out var recipeSet)) + if (_cookwareToRecipeMapping.TryGetValue(cookwareId, out var recipeSet)) { return recipeSet.Count > 0; } @@ -257,7 +267,7 @@ public bool IsTodayMenuMatched(string cookwareId) public bool HasAddedCookByCookwareKey(string cookwareKey) { - return _cookwareToRecipeIds.ContainsKey(cookwareKey) && _cookwareToRecipeIds[cookwareKey].Count > 0;; + return _cookwareToRecipeMapping.ContainsKey(cookwareKey) && _cookwareToRecipeMapping[cookwareKey].Count > 0;; } } } \ No newline at end of file diff --git a/Assets/_DDD/_Scripts/Restaurant/Ui/CookUi/CookViewModel.cs b/Assets/_DDD/_Scripts/Restaurant/Ui/CookUi/CookViewModel.cs index d0ef8f05c..91ce01972 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Ui/CookUi/CookViewModel.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Ui/CookUi/CookViewModel.cs @@ -114,7 +114,7 @@ public void CreateAddedCookItemSlot(Transform parent) var matchingRecipes = new Dictionary(); // CookwareType에 맞는 레시피들을 수집 - foreach (var cookwareToRecipe in GetRestaurantManagementState().CookwareToRecipeIds) + foreach (var cookwareToRecipe in GetRestaurantManagementState().CookwareToRecipeMapping) { var cookwareId = cookwareToRecipe.Key; var recipeIds = cookwareToRecipe.Value; @@ -127,8 +127,8 @@ public void CreateAddedCookItemSlot(Transform parent) if (matchingRecipes.ContainsKey(recipeId) == false) { // 레시피 개수 가져오기 - int count = GetRestaurantManagementState().TodayFoodRecipeIds.TryGetValue(recipeId, out var foodCount) ? foodCount - : GetRestaurantManagementState().TodayDrinkRecipeIds.TryGetValue(recipeId, out var drinkCount) ? drinkCount + int count = GetRestaurantManagementState().TodayFoodRecipeAndAmounts.TryGetValue(recipeId, out var foodCount) ? foodCount + : GetRestaurantManagementState().TodayDrinkRecipeAndAmounts.TryGetValue(recipeId, out var drinkCount) ? drinkCount : 0; matchingRecipes[recipeId] = count; diff --git a/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantManagementUi/RestaurantManagementViewModel.cs b/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantManagementUi/RestaurantManagementViewModel.cs index 8f4c71065..f03d4ee03 100644 --- a/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantManagementUi/RestaurantManagementViewModel.cs +++ b/Assets/_DDD/_Scripts/Restaurant/Ui/RestaurantManagementUi/RestaurantManagementViewModel.cs @@ -489,7 +489,7 @@ public void CreateDrinkSlot(Transform parent) public void UpdateTodayMenuItems() { int foodIndex = 0; - foreach (var foodRecipeIdCountPair in GetRestaurantManagementState().TodayFoodRecipeIds) + foreach (var foodRecipeIdCountPair in GetRestaurantManagementState().TodayFoodRecipeAndAmounts) { if (foodIndex >= _foodSlots.Count) break; @@ -506,7 +506,7 @@ public void UpdateTodayMenuItems() } int drinkIndex = 0; - foreach (var drinkRecipeIdCountPair in GetRestaurantManagementState().TodayDrinkRecipeIds) + foreach (var drinkRecipeIdCountPair in GetRestaurantManagementState().TodayDrinkRecipeAndAmounts) { if (drinkIndex >= _drinkSlots.Count) break; @@ -569,7 +569,7 @@ public void CreateTodayCookwareSlot(Transform parent) public void UpdateTodayRestaurantStateView() { int workerIndex = 0; - foreach (var workerKey in GetRestaurantManagementState().TodayWorkerIds) + foreach (var workerKey in GetRestaurantManagementState().TodayWorkers) { if (workerIndex >= _workerSlots.Count) break; @@ -586,7 +586,7 @@ public void UpdateTodayRestaurantStateView() } int cookwareIndex = 0; - foreach (var cookwareKey in GetRestaurantManagementState().CookwareToRecipeIds.Keys) + foreach (var cookwareKey in GetRestaurantManagementState().CookwareToRecipeMapping.Keys) { if (cookwareIndex >= _cookwareSlots.Count) break;