Добавить таймеры и шкалы прогресса, расширить призовую систему и контроль остатков, восстановить настройки и обновить таблицу призов главного меню.
186 lines
5.2 KiB
C#
186 lines
5.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
|
|
public class VitrinaPanel : MonoBehaviour, IControlable
|
|
{
|
|
public event Action<bool> OnComplete;
|
|
|
|
[SerializeField] private Transform BoxesRoot;
|
|
[SerializeField] private GameObject BoxViewPrefab;
|
|
|
|
private readonly List<VitrinaBox> _generatedBoxes = new();
|
|
private int _pointerIndex;
|
|
private bool _initialized;
|
|
private bool _waitForActionRelease;
|
|
private bool _waitingForResult;
|
|
|
|
public bool ControlsEnabled { get; set; }
|
|
private VitrinaBox CurrentBox => _generatedBoxes[_pointerIndex];
|
|
|
|
private void OnDisable()
|
|
{
|
|
ControlsEnabled = false;
|
|
_initialized = false;
|
|
_waitingForResult = false;
|
|
UnsubscribeFromResult();
|
|
ClearBoxes();
|
|
}
|
|
|
|
public async void Initialize(int[] requiredBoxes)
|
|
{
|
|
if (_initialized)
|
|
return;
|
|
|
|
_initialized = true;
|
|
ControlsEnabled = false;
|
|
ClearBoxes();
|
|
|
|
if (VitrinaCatcher.Instance == null)
|
|
{
|
|
Debug.LogError("VitrinaCatcher не инициализирован", gameObject);
|
|
_initialized = false;
|
|
gameObject.SetActive(false);
|
|
OnComplete?.Invoke(false);
|
|
return;
|
|
}
|
|
|
|
SubscribeToResult();
|
|
|
|
if (!PrizeStandController.Initialized)
|
|
{
|
|
_waitingForResult = true;
|
|
VitrinaCatcher.Instance.DisplayOpenResult(false, "Витрина не подключена");
|
|
return;
|
|
}
|
|
|
|
int[] readyBoxes = await PrizeStandController.GetReadyBoxesAsync();
|
|
|
|
if (!_initialized)
|
|
return;
|
|
|
|
int[] availableBoxes = FindIntersection(requiredBoxes, readyBoxes);
|
|
|
|
if (availableBoxes.Length == 0)
|
|
{
|
|
_waitingForResult = true;
|
|
VitrinaCatcher.Instance.DisplayOpenResult(false, "Нет доступных призов в витрине");
|
|
return;
|
|
}
|
|
|
|
_pointerIndex = 0;
|
|
GenerateBoxes(availableBoxes);
|
|
CurrentBox.SetEnabled(true);
|
|
_waitForActionRelease = true;
|
|
ControlsEnabled = true;
|
|
ControlsPerformer.Instance.SetControlable(this);
|
|
}
|
|
|
|
public void UpdateControls()
|
|
{
|
|
if (!_initialized || _waitingForResult)
|
|
return;
|
|
|
|
if (_waitForActionRelease)
|
|
{
|
|
if (In.GetAction(JoystickSide.Both, InteractMode.Continious))
|
|
return;
|
|
|
|
_waitForActionRelease = false;
|
|
}
|
|
|
|
int direction = In.GetAxis(JoystickSide.Both, InteractMode.Discrete).x;
|
|
|
|
if (direction != 0 && _generatedBoxes.Count > 1)
|
|
{
|
|
CurrentBox.SetEnabled(false);
|
|
CurrentBox.shake = false;
|
|
_pointerIndex = (_pointerIndex + direction + _generatedBoxes.Count) % _generatedBoxes.Count;
|
|
CurrentBox.SetEnabled(true);
|
|
}
|
|
|
|
if (!In.GetAction(JoystickSide.Both, InteractMode.Discrete))
|
|
return;
|
|
|
|
ControlsEnabled = false;
|
|
ControlsPerformer.Instance.SetControlable(null);
|
|
CurrentBox.shake = true;
|
|
_waitingForResult = true;
|
|
_ = PrizeStandController.OpenBoxAsync(CurrentBox.Number);
|
|
}
|
|
|
|
public static int[] FindIntersection(int[] array1, int[] array2)
|
|
{
|
|
if (array1 == null || array2 == null || array1.Length == 0 || array2.Length == 0)
|
|
return Array.Empty<int>();
|
|
|
|
HashSet<int> requiredBoxes = new(array1);
|
|
return array2.Where(requiredBoxes.Contains).Distinct().OrderBy(number => number).ToArray();
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
ControlsEnabled = false;
|
|
ControlsPerformer.Instance.SetControlable(null);
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
private void GenerateBoxes(int[] indexes)
|
|
{
|
|
foreach (int index in indexes)
|
|
{
|
|
GameObject boxObject = Instantiate(BoxViewPrefab, BoxesRoot);
|
|
|
|
if (boxObject.TryGetComponent(out VitrinaBox box))
|
|
{
|
|
_generatedBoxes.Add(box);
|
|
box.SetNumber(index);
|
|
}
|
|
else
|
|
{
|
|
Destroy(boxObject);
|
|
Debug.LogError("Префаб не содержит компонента VitrinaBox", gameObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ClearBoxes()
|
|
{
|
|
foreach (VitrinaBox box in _generatedBoxes)
|
|
{
|
|
if (box != null)
|
|
Destroy(box.gameObject);
|
|
}
|
|
|
|
_generatedBoxes.Clear();
|
|
}
|
|
|
|
private void SubscribeToResult()
|
|
{
|
|
if (VitrinaCatcher.Instance == null)
|
|
return;
|
|
|
|
VitrinaCatcher.Instance.ResultClosed -= HandleResultClosed;
|
|
VitrinaCatcher.Instance.ResultClosed += HandleResultClosed;
|
|
}
|
|
|
|
private void UnsubscribeFromResult()
|
|
{
|
|
if (VitrinaCatcher.Instance != null)
|
|
VitrinaCatcher.Instance.ResultClosed -= HandleResultClosed;
|
|
}
|
|
|
|
private void HandleResultClosed(bool success)
|
|
{
|
|
if (!_initialized || !_waitingForResult)
|
|
return;
|
|
|
|
UnsubscribeFromResult();
|
|
_initialized = false;
|
|
_waitingForResult = false;
|
|
gameObject.SetActive(false);
|
|
OnComplete?.Invoke(success);
|
|
}
|
|
}
|