290 lines
12 KiB
C#
290 lines
12 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;;
|
|
}
|
|
|
|
public bool TryCookingById(string recipeId)
|
|
{
|
|
if (_todayFoodRecipeIds.TryGetValue(recipeId, out var foodCount) && foodCount > 0)
|
|
{
|
|
_todayFoodRecipeIds[recipeId] -= 1;
|
|
return true;
|
|
}
|
|
|
|
if (_todayDrinkRecipeIds.TryGetValue(recipeId, out var drinkCount) && drinkCount > 0)
|
|
{
|
|
_todayDrinkRecipeIds[recipeId] -= 1;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
} |