CapersProject/Assets/02.Scripts/DDD/Ui/Tycoon/AddMenuUi.cs
2025-02-18 18:35:13 +09:00

466 lines
16 KiB
C#

using System.Collections.Generic;
using System.Threading.Tasks;
using DDD.ScriptableObjects;
using DDD.Utility;
using DG.Tweening;
using Sirenix.OdinInspector;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
namespace DDD.Uis.Tycoon
{
public class AddMenuUi : PopupUi
{
[Title("프리팹")]
[SerializeField]
private MenuHashTag _menuHashTagPrefab;
[SerializeField]
private SelectedCraftRecipeIngredient _selectedCraftRecipeIngredientPrefab;
[Title("컴포넌트")]
[SerializeField]
private GameObject _panel;
[SerializeField]
private RectTransform _panelRect;
[SerializeField]
private Image _menuButtonImage;
[SerializeField]
private Button _menuButton;
[SerializeField]
private GameObject _emptyPanel;
[SerializeField]
private GameObject _addedPanel;
[SerializeField]
private Button _decreaseButton;
[SerializeField]
private TMP_Text _countText;
[SerializeField]
private Button _increaseButton;
[SerializeField]
private TMP_Text _nameText;
[SerializeField]
private TMP_Text _descriptionText;
[SerializeField]
private GameObject _menuHashTagsPanel;
[SerializeField]
private GameObject _selectedCraftRecipeIngredientsPanel;
[Title("클래스")]
[SerializeField]
private CraftRecipeUi _craftRecipeUi;
[Title("데이터")]
[SerializeField]
private int _maxHashTagCount = 3;
[SerializeField]
private int _maxIngredientCount = 3;
[Title("연출")]
[SerializeField]
private Vector2 _panelScale = new(0f, 1f);
[SerializeField]
private float _duration = 0.3f;
[SerializeField]
private Ease _ease = Ease.InQuint;
[Title("데이터")]
[SerializeField]
private Sprite _emptySprite;
[Title("실시간 데이터")]
[SerializeField, DisableIf("@true")]
private bool _isAddedMenu;
public bool IsAddedMenu
{
get => _isAddedMenu;
private set
{
_isAddedMenu = value;
if (_isAddedMenu)
{
_emptyPanel.SetActive(false);
_addedPanel.SetActive(true);
for (int i = 0; i < 3; i++)
{
if (i < AddedCraftRecipeData.ValidIngredients.Count)
{
_selectedCraftRecipeIngredients[i].UpdateIngredients(AddedCraftRecipeData.ValidIngredients[i]);
_selectedCraftRecipeIngredients[i].ShowUi();
if (!_selectedCraftRecipeIngredients[i].IsCraftable)
{
IsCraftable = false;
}
}
else
{
_selectedCraftRecipeIngredients[i].HideUi();
}
}
}
else
{
_menuButtonImage.sprite = _emptySprite;
_emptyPanel.SetActive(true);
_addedPanel.SetActive(false);
for (int i = 0; i < 3; i++)
{
_selectedCraftRecipeIngredients[i].HideUi();
}
}
}
}
[field: SerializeField]
public bool IsCraftable { get; private set; }
[SerializeField]
private List<MenuHashTag> _menuHashTags;
[SerializeField]
private List<SelectedCraftRecipeIngredient> _selectedCraftRecipeIngredients;
public CraftRecipeData AddedCraftRecipeData { get; private set; }
public int AddedCount { get; private set; }
public Tween OpenTween { get; private set; }
public Tween CloseTween { get; private set; }
private TodayMenu _currentTodayMenu;
private Sequence _closeSequence;
private InputAction _interactionEAction;
private InputAction _cancelAction;
private InputAction _pressFAction;
private InputAction _pressQAction;
private InputAction _pressRAction;
private int _maxCraftingCount;
private void Awake()
{
foreach (Transform element in _menuHashTagsPanel.transform)
{
if (element)
{
Destroy(element.gameObject);
}
}
foreach (Transform element in _selectedCraftRecipeIngredientsPanel.transform)
{
if (element)
{
Destroy(element.gameObject);
}
}
_craftRecipeUi = FindAnyObjectByType<CraftRecipeUi>();
OpenTween = _panelRect.DOScaleY(_panelScale.y, _duration)
.From(_panelScale.x)
.SetEase(_ease)
.SetAutoKill(false)
.Pause();
CloseTween = _panelRect.DOScaleY(_panelScale.x, _duration)
.From(_panelScale.y)
.SetEase(_ease)
.OnComplete(() =>
{
_panel.SetActive(false);
base.Close();
_currentTodayMenu = null;
})
.SetAutoKill(false)
.Pause();
}
private void Start()
{
_interactionEAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.InteractionE);
_cancelAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.Cancel);
_pressFAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressF);
_pressQAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressQ);
_pressRAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressR);
_menuHashTags = new List<MenuHashTag>(_maxHashTagCount);
for (int i = 0; i < _maxHashTagCount; i++)
{
MenuHashTag menuHashTag = Instantiate(_menuHashTagPrefab, _menuHashTagsPanel.transform);
menuHashTag.HideUi();
_menuHashTags.Add(menuHashTag);
}
_selectedCraftRecipeIngredients = new List<SelectedCraftRecipeIngredient>(_maxIngredientCount);
for (int i = 0; i < _maxHashTagCount; i++)
{
SelectedCraftRecipeIngredient selectedCraftRecipeIngredient = Instantiate(_selectedCraftRecipeIngredientPrefab, _selectedCraftRecipeIngredientsPanel.transform);
selectedCraftRecipeIngredient.HideUi();
_selectedCraftRecipeIngredients.Add(selectedCraftRecipeIngredient);
}
_menuButton.onClick.AddListener(OnClickEmptyButton);
_decreaseButton.onClick.AddListener(DecreaseButton);
_increaseButton.onClick.AddListener(IncreaseButton);
_craftRecipeUi.SetSelectRecipeAction(SelectCraftRecipe);
_panel.transform.localScale = new Vector3(1f, 0f, 1f);
_panel.SetActive(false);
}
private void OnDestroy()
{
OpenTween?.Kill();
CloseTween?.Kill();
_closeSequence?.Kill();
_interactionEAction = null;
_cancelAction = null;
_pressFAction = null;
_pressQAction = null;
_pressRAction = null;
}
public override void Open()
{
AddedCount = 1;
if (_currentTodayMenu.IsAddedMenu)
{
AddedCraftRecipeData = _currentTodayMenu.AddedCraftRecipeData;
SelectCraftRecipe();
}
else
{
AddedCraftRecipeData = null;
}
IsAddedMenu = _currentTodayMenu.IsAddedMenu;
base.Open();
_panel.SetActive(true);
}
public void OnClose(InputAction.CallbackContext context)
{
Close();
}
public override void Close()
{
_closeSequence?.Restart();
}
public override void EnableInput()
{
_interactionEAction.performed += OnInteractionE;
_cancelAction.performed += OnClose;
_pressFAction.performed += OnClose;
_pressQAction.performed += OnDecreaseButton;
_pressRAction.performed += OnIncreaseButton;
}
public override void DisableInput()
{
_interactionEAction.performed -= OnInteractionE;
_cancelAction.performed -= OnClose;
_pressFAction.performed -= OnClose;
_pressQAction.performed -= OnDecreaseButton;
_pressRAction.performed -= OnIncreaseButton;
}
private void OnInteractionE(InputAction.CallbackContext context)
{
if (IsAddedMenu)
{
// 메뉴 등록
if (IsCraftable)
{
UseIngredients();
_currentTodayMenu.AddMenu(AddedCraftRecipeData, AddedCount);
Close();
}
}
else
{
// 레시피 선택
_menuButton.onClick.Invoke();
}
}
public void OnClickEmptyButton()
{
_craftRecipeUi.Open();
}
public void SelectCraftRecipe()
{
if (AddedCraftRecipeData == null)
{
AddedCraftRecipeData = _craftRecipeUi.CurrentCraftRecipeButton.CraftRecipeData;
}
IsCraftable = true;
for (int i = 0; i < 3; i++)
{
if (i < AddedCraftRecipeData.ValidIngredients.Count)
{
_selectedCraftRecipeIngredients[i].UpdateIngredients(AddedCraftRecipeData.ValidIngredients[i]);
_selectedCraftRecipeIngredients[i].ShowUi();
if (!_selectedCraftRecipeIngredients[i].IsCraftable)
{
IsCraftable = false;
}
}
else
{
_selectedCraftRecipeIngredients[i].HideUi();
}
}
_maxCraftingCount = int.MaxValue;
foreach (CraftingIngredient craftingIngredient in AddedCraftRecipeData.ValidIngredients)
{
string ingredientIdx = craftingIngredient.Idx;
int requiredCount = craftingIngredient.Count;
int inventoryCount = DataManager.Instance.Inventory.GetItemByIdx(ingredientIdx)?.Count ?? 0;
int craftingCount = inventoryCount / requiredCount;
if (_maxCraftingCount > craftingCount)
{
_maxCraftingCount = craftingCount;
}
}
_menuButtonImage.sprite = AddedCraftRecipeData.Sprite;
_nameText.text = Utils.GetLocalizedString(AddedCraftRecipeData.Idx);
_descriptionText.text = Utils.GetLocalizedString(AddedCraftRecipeData.Description);
_countText.text = $"{AddedCount}/{_maxCraftingCount}";
int validHashTagCount = AddedCraftRecipeData.ValidHashTags.Count;
for (int i = 0; i < _maxHashTagCount; i++)
{
if (i >= validHashTagCount)
{
_menuHashTags[i].HideUi();
continue;
}
_menuHashTags[i].SetTag(AddedCraftRecipeData.ValidHashTags[i]);
_menuHashTags[i].ShowUi();
}
IsAddedMenu = true;
}
private void OnDecreaseButton(InputAction.CallbackContext context)
{
if (!IsAddedMenu) return;
DecreaseButton();
}
public async void DecreaseButton()
{
PointerEventData pointerData = new PointerEventData(EventSystem.current);
ExecuteEvents.Execute(_decreaseButton.gameObject, pointerData, ExecuteEvents.pointerDownHandler);
await Task.Delay(100);
ExecuteEvents.Execute(_decreaseButton.gameObject, pointerData, ExecuteEvents.pointerUpHandler);
if (AddedCount <= 1) return;
AddedCount--;
_countText.text = $"{AddedCount}/{_maxCraftingCount}";
for (int i = 0; i < AddedCraftRecipeData.ValidIngredients.Count; i++)
{
_selectedCraftRecipeIngredients[i].UpdateCraftableCount(AddedCount);
}
}
private void OnIncreaseButton(InputAction.CallbackContext context)
{
if (!IsAddedMenu) return;
IncreaseButton();
}
public async void IncreaseButton()
{
PointerEventData pointerData = new PointerEventData(EventSystem.current);
ExecuteEvents.Execute(_increaseButton.gameObject, pointerData, ExecuteEvents.pointerDownHandler);
await Task.Delay(100);
ExecuteEvents.Execute(_increaseButton.gameObject, pointerData, ExecuteEvents.pointerUpHandler);
if (AddedCraftRecipeData == null) return;
int newCount = AddedCount + 1;
foreach (var ingredient in AddedCraftRecipeData.ValidIngredients)
{
var slot = DataManager.Instance.Inventory.GetItemByIdx(ingredient.Idx);
int available = slot != null ? slot.Count : 0;
if (available < newCount * ingredient.Count) return;
}
AddedCount = newCount;
_countText.text = $"{AddedCount}/{_maxCraftingCount}";
for (int i = 0; i < AddedCraftRecipeData.ValidIngredients.Count; i++)
{
_selectedCraftRecipeIngredients[i].UpdateCraftableCount(AddedCount);
}
}
public void UseIngredients()
{
if (AddedCraftRecipeData == null)
{
Debug.LogWarning("현재 선택된 레시피가 없습니다.");
return;
}
foreach (var ingredient in AddedCraftRecipeData.ValidIngredients)
{
var slot = DataManager.Instance.Inventory.GetItemByIdx(ingredient.Idx);
DataManager.Instance.Inventory.RemoveItem(slot, AddedCount * ingredient.Count);
}
Close();
}
public void RestoreIngredients()
{
foreach (CraftingIngredient craftingIngredient in AddedCraftRecipeData.ValidIngredients)
{
InventoryItemSlot newSlot = new InventoryItemSlot(craftingIngredient.Idx, AddedCount * craftingIngredient.Count);
DataManager.Instance.Inventory.AddItem(newSlot);
}
}
public void SetCloseSequence(Sequence closeSequence) => _closeSequence = closeSequence;
public void SetCurrentTodayMenu(TodayMenu todayMenu) => _currentTodayMenu = todayMenu;
}
}