466 lines
16 KiB
C#
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;
|
|
}
|
|
} |