274 lines
11 KiB
C#
274 lines
11 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
|
|
namespace DDD
|
|
{
|
|
public class RestaurantManagementState : ScriptableObject
|
|
{
|
|
// TODO : 데이터에서 초기화하고, 동적으로 변경
|
|
[Title("오늘의 레스토랑 상태")]
|
|
public int MaxFoodCount = 8;
|
|
public int MaxDrinkCount = 6;
|
|
public int MaxCookwareCount = 6;
|
|
|
|
[Title("체크리스트 조건")]
|
|
public int ChecklistFoodCount = 1;
|
|
public int ChecklistCookwareCount = 1;
|
|
public int ChecklistMatchedMenuWithCookwareCount = 1;
|
|
|
|
[Title("실시간 데이터")]
|
|
[ReadOnly, SerializeField] private bool _isOpenable;
|
|
[ReadOnly, ShowInInspector] private Dictionary<string, int> _todayFoodRecipeIds = new();
|
|
[ReadOnly, ShowInInspector] private Dictionary<string, int> _todayDrinkRecipeIds = new();
|
|
[ReadOnly, ShowInInspector] private List<string> _todayWorkerIds = new();
|
|
[ReadOnly, ShowInInspector] private Dictionary<string, HashSet<string>> _cookwareToRecipeIds = new();
|
|
|
|
public IReadOnlyDictionary<string, int> TodayFoodRecipeIds => _todayFoodRecipeIds;
|
|
public IReadOnlyDictionary<string, int> TodayDrinkRecipeIds => _todayDrinkRecipeIds;
|
|
public IReadOnlyList<string> TodayWorkerIds => _todayWorkerIds;
|
|
public IReadOnlyDictionary<string, HashSet<string>> CookwareToRecipeIds => _cookwareToRecipeIds;
|
|
|
|
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 void InitializeReadyForRestaurant()
|
|
{
|
|
// TODO : Load from disk if possible (save data)
|
|
_todayFoodRecipeIds.Clear();
|
|
_todayDrinkRecipeIds.Clear();
|
|
_todayWorkerIds.Clear();
|
|
_cookwareToRecipeIds.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 _todayFoodRecipeIds.Count > 0;
|
|
}
|
|
|
|
public bool HasCookwares()
|
|
{
|
|
return _cookwareToRecipeIds.Count > 0;
|
|
}
|
|
|
|
public bool HasMatchedMenuWithCookware()
|
|
{
|
|
return _cookwareToRecipeIds.Values.Any(recipeSet => recipeSet.Count > 0);
|
|
}
|
|
|
|
public bool IsOpenable()
|
|
{
|
|
// TODO : 영업 가능한 상태인지 조건 추가 (최소 요리, 요리도구 배치 등)
|
|
bool isExistedCookware = CookwareToRecipeIds.Count > 0;
|
|
bool isExistedMatchedMenu = _cookwareToRecipeIds.Values.Any(recipeSet => recipeSet is { Count: > 0 });
|
|
|
|
_isOpenable = isExistedCookware && isExistedMatchedMenu;
|
|
return _isOpenable;
|
|
}
|
|
|
|
public RestaurantManagementData GetManagementData()
|
|
{
|
|
return RestaurantController.Instance.RestaurantData.ManagementData;
|
|
}
|
|
|
|
public bool TryAddTodayMenu(ItemViewModel model)
|
|
{
|
|
string recipeId = model.Id;
|
|
|
|
if (model.ItemType != ItemType.Recipe) return false;
|
|
|
|
if (DataManager.Instance.GetDataSo<RecipeDataSo>().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<FoodDataSo>().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<DrinkDataSo>().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);
|
|
}
|
|
|
|
var dirtyEvt = GameEvents.SmartVariablesDirtyEvent;
|
|
dirtyEvt.DomainFlags = SmartVariablesDomain.RestaurantToday;
|
|
EventBus.Broadcast(dirtyEvt);
|
|
EventBus.Broadcast(RestaurantEvents.TodayMenuAddedEvent);
|
|
}
|
|
|
|
return added;
|
|
}
|
|
|
|
public bool TryRemoveTodayMenu(ItemViewModel model)
|
|
{
|
|
string recipeId = model.Id;
|
|
var removedEvt = RestaurantEvents.TodayMenuRemovedEvent;
|
|
|
|
if (DataManager.Instance.GetDataSo<RecipeDataSo>().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);
|
|
removedEvt.InventoryCategoryType = InventoryCategoryType.Food;
|
|
|
|
if (removed)
|
|
{
|
|
var foodData = DataManager.Instance.GetDataSo<FoodDataSo>().GetDataById(recipeData.RecipeResult);
|
|
foodData.RefundIngredients(refundCount);
|
|
}
|
|
}
|
|
}
|
|
else if (recipeData.RecipeType == RecipeType.DrinkRecipe)
|
|
{
|
|
if (_todayDrinkRecipeIds.TryGetValue(recipeId, out refundCount))
|
|
{
|
|
removed = _todayDrinkRecipeIds.Remove(recipeId);
|
|
removedEvt.InventoryCategoryType = InventoryCategoryType.Drink;
|
|
|
|
if (removed)
|
|
{
|
|
var drinkData = DataManager.Instance.GetDataSo<DrinkDataSo>().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);
|
|
}
|
|
|
|
var dirtyEvt = GameEvents.SmartVariablesDirtyEvent;
|
|
dirtyEvt.DomainFlags = SmartVariablesDomain.RestaurantToday;
|
|
EventBus.Broadcast(dirtyEvt);
|
|
EventBus.Broadcast(removedEvt);
|
|
}
|
|
|
|
return removed;
|
|
}
|
|
|
|
public bool TryAddTodayCookware(ItemViewModel model)
|
|
{
|
|
var cookwareId = model.Id;
|
|
|
|
if (model.HasItem == false || DataManager.Instance.GetDataSo<CookwareDataSo>().ContainsData(cookwareId) == false) return false;
|
|
|
|
if (_cookwareToRecipeIds.Count >= MaxCookwareCount || _cookwareToRecipeIds.ContainsKey(cookwareId)) return false;
|
|
|
|
_cookwareToRecipeIds[cookwareId] = new HashSet<string>();
|
|
|
|
foreach (var recipeId in _todayFoodRecipeIds.Keys.Concat(_todayDrinkRecipeIds.Keys))
|
|
{
|
|
var required = GetRequiredCookwareKey(recipeId);
|
|
if (required == cookwareId)
|
|
{
|
|
_cookwareToRecipeIds[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) => _todayFoodRecipeIds.ContainsKey(recipeId) || _todayDrinkRecipeIds.ContainsKey(recipeId);
|
|
|
|
public bool TryRemoveTodayCookware(ItemViewModel model)
|
|
{
|
|
var cookwareId = model.Id;
|
|
|
|
if (DataManager.Instance.GetDataSo<CookwareDataSo>().ContainsData(cookwareId) == false) return false;
|
|
|
|
if (_cookwareToRecipeIds.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.GetDataSo<RecipeDataSo>().TryGetDataById(recipeId, out var recipeData) == false) return null;
|
|
|
|
var resultKey = recipeData.RecipeResult;
|
|
|
|
return recipeData.RecipeType switch
|
|
{
|
|
RecipeType.FoodRecipe => DataManager.Instance.GetDataSo<FoodDataSo>().GetDataById(resultKey).CookwareKey,
|
|
RecipeType.DrinkRecipe => DataManager.Instance.GetDataSo<DrinkDataSo>().GetDataById(resultKey).CookwareKey,
|
|
_ => null
|
|
};
|
|
}
|
|
|
|
public bool IsCookwareMatched(string recipeId)
|
|
{
|
|
return _cookwareToRecipeIds.Values.Any(recipeHashSets => recipeHashSets.Contains(recipeId));
|
|
}
|
|
|
|
public bool IsTodayMenuMatched(string cookwareId)
|
|
{
|
|
if (_cookwareToRecipeIds.TryGetValue(cookwareId, out var recipeSet))
|
|
{
|
|
return recipeSet.Count > 0;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
} |