251 lines
6.9 KiB
C#
251 lines
6.9 KiB
C#
using CharacterSystem;
|
|
using PrizeSystem;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.Serialization;
|
|
using UnityEngine.UI;
|
|
|
|
public class PrizesSelector : MonoBehaviour, IControlable
|
|
{
|
|
public event Action OnConfirmed;
|
|
|
|
[SerializeField] private RectTransform _addedPrizesTable;
|
|
[SerializeField] private AvailablePrizesTable _availablePrizesTable;
|
|
[SerializeField] private MSignalButton _selectButton;
|
|
[SerializeField, FormerlySerializedAs("pointer")] private RectTransform _pointer;
|
|
|
|
private readonly List<PrizeButton> _addedPrizeButtons = new();
|
|
private PrizeSet _prizeSet;
|
|
private SelectionArea _selectionArea;
|
|
private int _rowIndex;
|
|
private bool _waitForActionRelease;
|
|
|
|
public bool ControlsEnabled { get; set; } = true;
|
|
|
|
private enum SelectionArea
|
|
{
|
|
Available,
|
|
Added,
|
|
Confirm
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
_availablePrizesTable.OnPrizeConfigured += OnPrizeConfigured;
|
|
_selectButton.OnClick += Confirm;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
_availablePrizesTable.OnPrizeConfigured -= OnPrizeConfigured;
|
|
_selectButton.OnClick -= Confirm;
|
|
}
|
|
|
|
public void Open(Character character)
|
|
{
|
|
gameObject.SetActive(true);
|
|
_prizeSet = PrizeSystemManager.PrizeContainer.Sets[character.CharacterIndex];
|
|
RefreshView();
|
|
|
|
_selectionArea = _availablePrizesTable.PrizeButtons.Count > 0
|
|
? SelectionArea.Available
|
|
: GetInitialFallbackArea();
|
|
_rowIndex = 0;
|
|
_waitForActionRelease = In.GetAction(JoystickSide.Both, InteractMode.Continious);
|
|
RebuildLayouts();
|
|
UpdatePointer();
|
|
}
|
|
|
|
public void UpdateControls()
|
|
{
|
|
bool actionPressed = In.GetAction(JoystickSide.Both, InteractMode.Continious);
|
|
if (_waitForActionRelease)
|
|
{
|
|
_waitForActionRelease = actionPressed;
|
|
return;
|
|
}
|
|
|
|
Vector2Int axes = In.GetAxis(JoystickSide.Both, InteractMode.Discrete);
|
|
NavigateHorizontal(axes.x);
|
|
NavigateVertical(axes.y);
|
|
GetSelectedButton()?.TakeInput(actionPressed);
|
|
}
|
|
|
|
private void RefreshView()
|
|
{
|
|
ClearAddedPrizes();
|
|
DisplayAddedPrizes();
|
|
_availablePrizesTable.Refresh(_prizeSet);
|
|
}
|
|
|
|
private void DisplayAddedPrizes()
|
|
{
|
|
foreach (Prize prize in _prizeSet.Prizes.Where(prize => prize is not EmptyPrize))
|
|
{
|
|
PrizeButton button = Instantiate(_availablePrizesTable.PrizeButtonPrefab, _addedPrizesTable);
|
|
button.Configure(prize);
|
|
button.OnPrize += _ => RemovePrize(prize);
|
|
_addedPrizeButtons.Add(button);
|
|
}
|
|
}
|
|
|
|
private void ClearAddedPrizes()
|
|
{
|
|
_addedPrizeButtons.Clear();
|
|
for (int i = _addedPrizesTable.childCount - 1; i >= 0; i--)
|
|
{
|
|
Transform child = _addedPrizesTable.GetChild(i);
|
|
child.SetParent(null, false);
|
|
Destroy(child.gameObject);
|
|
}
|
|
}
|
|
|
|
private void OnPrizeConfigured(Prize prize)
|
|
{
|
|
_prizeSet.Prizes.RemoveAll(item => item is EmptyPrize);
|
|
_prizeSet.Prizes.Add(prize);
|
|
RefreshView();
|
|
|
|
_selectionArea = SelectionArea.Added;
|
|
_rowIndex = _addedPrizeButtons.Count - 1;
|
|
_waitForActionRelease = true;
|
|
RebuildLayouts();
|
|
UpdatePointer();
|
|
ControlsPerformer.Instance.SetControlable(this);
|
|
}
|
|
|
|
private void RemovePrize(Prize prize)
|
|
{
|
|
_prizeSet.Prizes.Remove(prize);
|
|
EnsureEmptyPrizeWhenNeeded();
|
|
RefreshView();
|
|
|
|
_selectionArea = _availablePrizesTable.PrizeButtons.Count > 0
|
|
? SelectionArea.Available
|
|
: GetInitialFallbackArea();
|
|
_rowIndex = 0;
|
|
_waitForActionRelease = true;
|
|
RebuildLayouts();
|
|
UpdatePointer();
|
|
}
|
|
|
|
private void EnsureEmptyPrizeWhenNeeded()
|
|
{
|
|
if (_prizeSet.Prizes.Count == 0)
|
|
_prizeSet.Prizes.Add(new EmptyPrize());
|
|
}
|
|
|
|
private void NavigateHorizontal(int direction)
|
|
{
|
|
if (direction < 0 && _availablePrizesTable.PrizeButtons.Count > 0)
|
|
{
|
|
_selectionArea = SelectionArea.Available;
|
|
ClampRowIndex();
|
|
UpdatePointer();
|
|
}
|
|
else if (direction > 0 && _addedPrizeButtons.Count > 0)
|
|
{
|
|
_selectionArea = SelectionArea.Added;
|
|
ClampRowIndex();
|
|
UpdatePointer();
|
|
}
|
|
}
|
|
|
|
private void NavigateVertical(int direction)
|
|
{
|
|
if (direction == 0)
|
|
return;
|
|
|
|
if (_selectionArea == SelectionArea.Confirm)
|
|
{
|
|
if (direction > 0)
|
|
SelectBottomAvailableRow();
|
|
return;
|
|
}
|
|
|
|
int buttonsCount = GetCurrentButtons().Count;
|
|
if (buttonsCount == 0)
|
|
{
|
|
SelectConfirm();
|
|
return;
|
|
}
|
|
|
|
if (direction < 0 && _rowIndex == buttonsCount - 1)
|
|
SelectConfirm();
|
|
else
|
|
_rowIndex = Mathf.Clamp(_rowIndex - direction, 0, buttonsCount - 1);
|
|
|
|
UpdatePointer();
|
|
}
|
|
|
|
private void SelectBottomAvailableRow()
|
|
{
|
|
if (_availablePrizesTable.PrizeButtons.Count > 0)
|
|
{
|
|
_selectionArea = SelectionArea.Available;
|
|
_rowIndex = _availablePrizesTable.PrizeButtons.Count - 1;
|
|
}
|
|
else if (_addedPrizeButtons.Count > 0)
|
|
{
|
|
_selectionArea = SelectionArea.Added;
|
|
_rowIndex = _addedPrizeButtons.Count - 1;
|
|
}
|
|
|
|
UpdatePointer();
|
|
}
|
|
|
|
private void SelectConfirm()
|
|
{
|
|
_selectionArea = SelectionArea.Confirm;
|
|
_rowIndex = 0;
|
|
}
|
|
|
|
private void ClampRowIndex()
|
|
{
|
|
_rowIndex = Mathf.Clamp(_rowIndex, 0, GetCurrentButtons().Count - 1);
|
|
}
|
|
|
|
private void UpdatePointer()
|
|
{
|
|
MSignalButton selectedButton = GetSelectedButton();
|
|
if (selectedButton != null)
|
|
_pointer.position = selectedButton.transform.position;
|
|
}
|
|
|
|
private void RebuildLayouts()
|
|
{
|
|
Canvas.ForceUpdateCanvases();
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)_availablePrizesTable.transform);
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(_addedPrizesTable);
|
|
Canvas.ForceUpdateCanvases();
|
|
}
|
|
|
|
private MSignalButton GetSelectedButton()
|
|
{
|
|
if (_selectionArea == SelectionArea.Confirm)
|
|
return _selectButton;
|
|
|
|
IReadOnlyList<PrizeButton> buttons = GetCurrentButtons();
|
|
return buttons.Count > 0 ? buttons[_rowIndex] : null;
|
|
}
|
|
|
|
private IReadOnlyList<PrizeButton> GetCurrentButtons()
|
|
{
|
|
return _selectionArea == SelectionArea.Added
|
|
? _addedPrizeButtons
|
|
: _availablePrizesTable.PrizeButtons;
|
|
}
|
|
|
|
private SelectionArea GetInitialFallbackArea()
|
|
{
|
|
return _addedPrizeButtons.Count > 0 ? SelectionArea.Added : SelectionArea.Confirm;
|
|
}
|
|
|
|
private void Confirm()
|
|
{
|
|
OnConfirmed?.Invoke();
|
|
}
|
|
}
|