ProjectDDD/Assets/_DDD/_Scripts/Restaurant/State/FlowStates/RestaurantManagementState.cs

273 lines
11 KiB
C#

using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;
namespace DDD.Restaurant
{
public class RestaurantManagementState : ScriptableObject
{
private Dictionary<string, int> _todayFoodRecipeAndAmounts = new();
private Dictionary<string, int> _todayDrinkRecipeAndAmounts = new();
private List<string> _todayWorkers = new();
private Dictionary<string, HashSet<string>> _cookwareToRecipeMapping = new();
public IReadOnlyDictionary<string, int> TodayFoodRecipeAndAmounts => _todayFoodRecipeAndAmounts;
public IReadOnlyDictionary<string, int> TodayDrinkRecipeAndAmounts => _todayDrinkRecipeAndAmounts;
public IReadOnlyList<string> TodayWorkers => _todayWorkers;
public IReadOnlyDictionary<string, HashSet<string>> CookwareToRecipeMapping => _cookwareToRecipeMapping;
public int AddedTodayMenuCount => AddedTodayFoodCount + AddedTodayDrinkCount;
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)
_todayFoodRecipeAndAmounts.Clear();
_todayDrinkRecipeAndAmounts.Clear();
_todayWorkers.Clear();
_cookwareToRecipeMapping.Clear();
}
/// <summary>
/// 체크리스트 항목들의 상태를 확인하는 메서드
/// </summary>
/// <returns>체크리스트 완료 여부 배열 (순서: 음식레시피, 조리도구, 매칭여부)</returns>
public bool[] GetChecklistStates()
{
bool hasFood = HasFoodRecipes();
bool hasCookware = HasCookwares();
bool hasMatching = HasMatchedMenuWithCookware();
return new bool[] { hasFood, hasCookware, hasMatching };
}
public bool HasFoodRecipes()
{
return _todayFoodRecipeAndAmounts.Count > 0;
}
public bool HasCookwares()
{
return _cookwareToRecipeMapping.Count > 0;
}
public bool HasMatchedMenuWithCookware()
{
return _cookwareToRecipeMapping.Values.Any(recipeSet => recipeSet.Count > 0);
}
public List<string> GetTodayFoodMenus()
{
return _todayFoodRecipeAndAmounts.Keys.ToList();
}
public int GetTodayFoodAvailableCount(string recipeId)
{
return _todayFoodRecipeAndAmounts.GetValueOrDefault(recipeId, 0);
}
public bool IsOpenable()
{
// TODO : 영업 가능한 상태인지 조건 추가 (최소 요리, 요리도구 배치 등)
bool isExistedCookware = CookwareToRecipeMapping.Count > 0;
bool isExistedMatchedMenu = _cookwareToRecipeMapping.Values.Any(recipeSet => recipeSet is { Count: > 0 });
var isOpenable = isExistedCookware && isExistedMatchedMenu;
return isOpenable;
}
public bool TryAddTodayMenu(ItemModel model)
{
string recipeId = model.Id;
if (model.ItemType != ItemType.Recipe) return false;
if (DataManager.Instance.GetDataAsset<RecipeDataAsset>().TryGetDataById(recipeId, out RecipeDataEntry recipeData) == false) return false;
bool added = false;
if (recipeData.RecipeType == RecipeType.FoodRecipe)
{
if (_todayFoodRecipeAndAmounts.Count >= GetRestaurantManagementData().MaxFoodCount || _todayFoodRecipeAndAmounts.ContainsKey(recipeId)) return false;
var foodData = DataManager.Instance.GetDataAsset<FoodDataAsset>().GetDataById(recipeData.RecipeResult);
var craftableCount = foodData.GetCraftableCount();
foodData.ConsumeAllCraftableIngredients();
_todayFoodRecipeAndAmounts[recipeId] = craftableCount;
added = true;
}
else if (recipeData.RecipeType == RecipeType.DrinkRecipe)
{
if (_todayDrinkRecipeAndAmounts.Count >= GetRestaurantManagementData().MaxDrinkCount || _todayDrinkRecipeAndAmounts.ContainsKey(recipeId)) return false;
var drinkData = DataManager.Instance.GetDataAsset<DrinkDataAsset>().GetDataById(recipeData.RecipeResult);
var craftableCount = drinkData.GetCraftableCount();
drinkData.ConsumeAllCraftableIngredients();
_todayDrinkRecipeAndAmounts[recipeId] = craftableCount;
added = true;
}
if (added)
{
var cookwareKey = GetRequiredCookwareKey(recipeId);
if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeMapping.TryGetValue(cookwareKey, out var recipeSet))
{
recipeSet.Add(recipeId);
}
var dirtyEvt = GameEvents.SmartVariablesDirtyEvent;
dirtyEvt.DomainFlags = SmartVariablesDomain.RestaurantToday;
EventBus.Broadcast(dirtyEvt);
EventBus.Broadcast(RestaurantEvents.TodayMenuAddedEvent);
}
return added;
}
public bool TryRemoveTodayMenu(ItemModel model)
{
string recipeId = model.Id;
var removedEvt = RestaurantEvents.TodayMenuRemovedEvent;
if (DataManager.Instance.GetDataAsset<RecipeDataAsset>().TryGetDataById(recipeId, out RecipeDataEntry recipeData) == false) return false;
bool removed = false;
int refundCount = 0;
if (recipeData.RecipeType == RecipeType.FoodRecipe)
{
if (_todayFoodRecipeAndAmounts.TryGetValue(recipeId, out refundCount))
{
removed = _todayFoodRecipeAndAmounts.Remove(recipeId);
removedEvt.InventoryCategoryType = InventoryCategoryType.Food;
if (removed)
{
var foodData = DataManager.Instance.GetDataAsset<FoodDataAsset>().GetDataById(recipeData.RecipeResult);
foodData.RefundIngredients(refundCount);
}
}
}
else if (recipeData.RecipeType == RecipeType.DrinkRecipe)
{
if (_todayDrinkRecipeAndAmounts.TryGetValue(recipeId, out refundCount))
{
removed = _todayDrinkRecipeAndAmounts.Remove(recipeId);
removedEvt.InventoryCategoryType = InventoryCategoryType.Drink;
if (removed)
{
var drinkData = DataManager.Instance.GetDataAsset<DrinkDataAsset>().GetDataById(recipeData.RecipeResult);
drinkData.RefundIngredients(refundCount);
}
}
}
if (removed)
{
var cookwareKey = GetRequiredCookwareKey(recipeId);
if (string.IsNullOrWhiteSpace(cookwareKey) == false && _cookwareToRecipeMapping.TryGetValue(cookwareKey, out var recipeSet))
{
recipeSet.Remove(recipeId);
}
var dirtyEvt = GameEvents.SmartVariablesDirtyEvent;
dirtyEvt.DomainFlags = SmartVariablesDomain.RestaurantToday;
EventBus.Broadcast(dirtyEvt);
EventBus.Broadcast(removedEvt);
}
return removed;
}
public bool TryAddTodayCookware(ItemModel model)
{
var cookwareId = model.Id;
if (model.HasItem == false || DataManager.Instance.GetDataAsset<CookwareDataAsset>().ContainsData(cookwareId) == false) return false;
if (_cookwareToRecipeMapping.Count >= GetRestaurantManagementData().MaxCookwareCount || _cookwareToRecipeMapping.ContainsKey(cookwareId)) return false;
_cookwareToRecipeMapping[cookwareId] = new HashSet<string>();
foreach (var recipeId in _todayFoodRecipeAndAmounts.Keys.Concat(_todayDrinkRecipeAndAmounts.Keys))
{
var required = GetRequiredCookwareKey(recipeId);
if (required == cookwareId)
{
_cookwareToRecipeMapping[cookwareId].Add(recipeId);
}
}
var dirtyEvt = GameEvents.SmartVariablesDirtyEvent;
dirtyEvt.DomainFlags = SmartVariablesDomain.RestaurantToday;
EventBus.Broadcast(dirtyEvt);
EventBus.Broadcast(RestaurantEvents.TodayMenuAddedEvent);
return true;
}
public bool IsContainTodayMenu(string recipeId) => _todayFoodRecipeAndAmounts.ContainsKey(recipeId) || _todayDrinkRecipeAndAmounts.ContainsKey(recipeId);
public bool TryRemoveTodayCookware(ItemModel model)
{
var cookwareId = model.Id;
if (DataManager.Instance.GetDataAsset<CookwareDataAsset>().ContainsData(cookwareId) == false) return false;
if (_cookwareToRecipeMapping.Remove(cookwareId) == false) return false;
var dirtyEvt = GameEvents.SmartVariablesDirtyEvent;
dirtyEvt.DomainFlags = SmartVariablesDomain.RestaurantToday;
EventBus.Broadcast(dirtyEvt);
var evt = RestaurantEvents.TodayMenuRemovedEvent;
evt.InventoryCategoryType = InventoryCategoryType.Cookware;
EventBus.Broadcast(evt);
return true;
}
private string GetRequiredCookwareKey(string recipeId)
{
if (DataManager.Instance.GetDataAsset<RecipeDataAsset>().TryGetDataById(recipeId, out var recipeData) == false) return null;
var resultKey = recipeData.RecipeResult;
return recipeData.RecipeType switch
{
RecipeType.FoodRecipe => DataManager.Instance.GetDataAsset<FoodDataAsset>().GetDataById(resultKey).CookwareKey,
RecipeType.DrinkRecipe => DataManager.Instance.GetDataAsset<DrinkDataAsset>().GetDataById(resultKey).CookwareKey,
_ => null
};
}
public bool IsCookwareMatched(string recipeId)
{
return _cookwareToRecipeMapping.Values.Any(recipeHashSets => recipeHashSets.Contains(recipeId));
}
public bool IsTodayMenuMatched(string cookwareId)
{
if (_cookwareToRecipeMapping.TryGetValue(cookwareId, out var recipeSet))
{
return recipeSet.Count > 0;
}
return false;
}
public bool HasAddedCookByCookwareKey(string cookwareKey)
{
return _cookwareToRecipeMapping.ContainsKey(cookwareKey) && _cookwareToRecipeMapping[cookwareKey].Count > 0;;
}
}
}