ProjectDDD/Assets/_DDD/_Scripts/Restaurant/RestaurantUi/CookUi/CookViewModel.cs

253 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Localization;
namespace DDD.Restaurant
{
public class SelectedCookSnapshot
{
public LocalizedString Name { get; }
public LocalizedString Description { get; }
public Sprite CookIcon { get; }
public string CookPrice { get; }
public IReadOnlyList<IngredientEntry> IngredientEntries { get; }
public IReadOnlyList<TasteData> Tastes { get; }
public Material TasteMaterial { get; }
public SelectedCookSnapshot(LocalizedString name,
LocalizedString description, Sprite cookIcon, string cookPrice, IReadOnlyList<IngredientEntry> ingredientEntries,
IReadOnlyList<TasteData> tastes, Material tasteMaterial)
{
Name = name;
Description = description;
CookIcon = cookIcon;
CookPrice = cookPrice;
IngredientEntries = ingredientEntries;
Tastes = tastes;
TasteMaterial = tasteMaterial;
}
public static readonly SelectedCookSnapshot Empty = new(
name: null,
description: null,
cookIcon: null,
cookPrice: null,
ingredientEntries: null,
tastes: System.Array.Empty<TasteData>(),
tasteMaterial: null);
}
public class CookViewModel : SimpleViewModel
{
private CookwareType _currentCookwareType = CookwareType.None;
private List<ItemSlotUi> _addedCookItemSlots;
private Sprite _cookwareIcon;
public Sprite CookwareIcon
{
get => _cookwareIcon;
set => SetField(ref _cookwareIcon, value);
}
private LocalizedString _cookwareName;
public LocalizedString CookwareName
{
get => _cookwareName;
set => SetField(ref _cookwareName, value);
}
private SelectedCookSnapshot _selectedCookSnapshot = SelectedCookSnapshot.Empty;
public SelectedCookSnapshot SelectedCookSnapshot
{
get => _selectedCookSnapshot;
private set => SetField(ref _selectedCookSnapshot, value);
}
public ItemSlotUi SelectedCookSlot { get; private set; }
private RestaurantManagementData GetRestaurantManagementData() => RestaurantData.Instance.ManagementData;
private RestaurantManagementState GetRestaurantManagementState() => RestaurantState.Instance.ManagementState;
private int _currentCookIndex = -1;
public int CurrentCookIndex
{
get => _currentCookIndex;
set => SetField(ref _currentCookIndex, value);
}
private readonly Dictionary<string, ItemSlotUi> _cookIngredientSlotLookup = new();
private InventorySortType _currentSortType = InventorySortType.None;
public event Action OnAddedIngredients;
public GameObject GetInitialSelected() => _addedCookItemSlots[0].gameObject;
public void SetCookwareType(CookwareType cookwareType)
{
if (_currentCookwareType == cookwareType) return;
_currentCookwareType = cookwareType;
var cookwareDatas = DataManager.Instance.GetDataSo<CookwareDataSo>().GetDataList();
var cookwareKey = cookwareDatas.Find(data => data.CookwareType == cookwareType).Id;
CookwareIcon = DataManager.Instance.GetIcon(cookwareKey);
CookwareName = LocalizationManager.Instance.GetLocalizedName(cookwareKey);
}
public void SetAddedCook(int index)
{
if (CurrentCookIndex == index) return;
CurrentCookIndex = index;
BeginUpdate();
SelectedCookSlot = _addedCookItemSlots[index];
UpdateSelectedCook();
EndUpdate();
}
public void CreateAddedCookItemSlot(Transform parent)
{
_addedCookItemSlots = new List<ItemSlotUi>(parent.GetComponentsInChildren<ItemSlotUi>());
// Dictionary 하나로 레시피 ID와 개수를 함께 관리
var matchingRecipes = new Dictionary<string, int>();
// CookwareType에 맞는 레시피들을 수집
foreach (var cookwareToRecipe in GetRestaurantManagementState().CookwareToRecipeIds)
{
var cookwareId = cookwareToRecipe.Key;
var recipeIds = cookwareToRecipe.Value;
if (DataManager.Instance.GetDataSo<CookwareDataSo>().TryGetDataById(cookwareId, out var cookwareData) &&
cookwareData.CookwareType == _currentCookwareType)
{
foreach (var recipeId in recipeIds)
{
if (matchingRecipes.ContainsKey(recipeId) == false)
{
// 레시피 개수 가져오기
int count = GetRestaurantManagementState().TodayFoodRecipeIds.TryGetValue(recipeId, out var foodCount) ? foodCount
: GetRestaurantManagementState().TodayDrinkRecipeIds.TryGetValue(recipeId, out var drinkCount) ? drinkCount
: 0;
matchingRecipes[recipeId] = count;
}
}
}
}
var recipeList = matchingRecipes.ToList();
for (int i = 0; i < _addedCookItemSlots.Count; i++)
{
ItemModel model = null;
if (i < recipeList.Count)
{
var recipe = recipeList[i];
model = ItemViewModelFactory.CreateByItemId(recipe.Key);
model?.SetCount(recipe.Value);
}
_addedCookItemSlots[i].Initialize(model, new AddedCookSlotUiStrategy(RecipeType.FoodRecipe));
}
}
public void CreateIngredientInventoryItemSlot(Transform parent)
{
Utils.DestroyAllChildren(parent);
var models = ItemViewModelFactory.CreateRestaurantManagementInventoryItem();
_cookIngredientSlotLookup.Clear();
foreach (var model in models)
{
if (model.ItemType != ItemType.Ingredient) continue;
var itemSlotUi = Instantiate(GetRestaurantManagementData().ItemSlotUiPrefab, parent);
var slot = itemSlotUi.GetComponent<ItemSlotUi>();
slot.Initialize(model, new InventorySlotUiStrategy());
itemSlotUi.name = model.Id;
// var interactor = itemSlotUi.GetComponent<ItemSlotInteractor>();
// if (model.ItemType == ItemType.Recipe)
// {
// interactor.Initialize(TodayMenuEventType.Add, new TodayMenuInteractorStrategy());
// }
// else
// {
// if (DataManager.Instance.GetDataSo<CookwareDataSo>().TryGetDataById(model.Id, out var cookwareData))
// {
// interactor.Initialize(TodayMenuEventType.Add, new TodayCookwareInteractorStrategy());
// }
// }
_cookIngredientSlotLookup[model.Id] = slot;
}
UpdateCookIngredient();
}
private IEnumerable<ItemSlotUi> SortSlots(IEnumerable<ItemSlotUi> slots)
{
return _currentSortType switch
{
InventorySortType.NameAscending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenBy(slot => slot.Model.DisplayName),
InventorySortType.NameDescending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenByDescending(slot => slot.Model.DisplayName),
InventorySortType.QuantityAscending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenBy(slot => slot.Model.Count),
InventorySortType.QuantityDescending => slots.OrderByDescending(slot => slot.Model.HasItem).ThenByDescending(slot => slot.Model.Count),
InventorySortType.None => slots.OrderBy(slot => slot.Model.Id),
_ => slots
};
}
public void UpdateCookIngredient()
{
var filteredSlots = _cookIngredientSlotLookup.Values;
var sortedSlots = SortSlots(filteredSlots);
int siblingIndex = 0;
foreach (var slot in sortedSlots)
{
var model = slot.Model;
if (model.HasItem)
{
slot.transform.SetSiblingIndex(siblingIndex++);
}
}
}
public TasteHashTagSlotUi CreateHashTag(Transform parent)
{
return Instantiate(GetRestaurantManagementData().TasteHashTagSlotUiPrefab, parent, false);
}
private void UpdateSelectedCook()
{
var selectedItemModel = SelectedCookSlot.Model;
string key = selectedItemModel.GetRecipeResultKey;
var nameLocalizedString = LocalizationManager.Instance.GetLocalizedName(key);
var descriptionLocalizedString = LocalizationManager.Instance.GetLocalizedDescription(key);
var cookIcon = selectedItemModel.GetResultIcon;
var cookPrice = selectedItemModel.GetPrice.ToGold();
var ingredientEntries = selectedItemModel.GetIngredients;
OnAddedIngredients?.Invoke();
var tastes = selectedItemModel.GetTasteDatas;
var tasteMat = selectedItemModel.RecipeType switch
{
RecipeType.FoodRecipe => RestaurantData.Instance.ManagementData.FoodTasteMaterial,
RecipeType.DrinkRecipe => RestaurantData.Instance.ManagementData.DrinkTasteMaterial,
_ => null
};
SelectedCookSnapshot = new SelectedCookSnapshot(
name: nameLocalizedString,
description: descriptionLocalizedString,
cookIcon: cookIcon,
cookPrice: cookPrice,
ingredientEntries: ingredientEntries,
tastes: tastes,
tasteMaterial: tasteMat);
}
}
}