using System; using DG.Tweening; using TMPro; using UnityEngine; public sealed class MachineCountersPanel : MonoBehaviour, IControlable { public event Action OnClosed; [SerializeField] private CanvasGroup _canvasGroup; [SerializeField] private TextMeshProUGUI[] _resettableValues; [SerializeField] private TextMeshProUGUI[] _lifetimeValues; [SerializeField] private TextMeshProUGUI _resetButton; [SerializeField] private TextMeshProUGUI _backButton; [SerializeField] private TextMeshProUGUI _status; [SerializeField] private RectTransform _holdProgressFill; [SerializeField] private float _resetHoldDuration = 1f; [SerializeField] private float _serviceHoldDuration = 1f; [SerializeField] private float _fadeDuration = 0.25f; [SerializeField] private Color _normalButtonColor = Color.white; [SerializeField] private Color _selectedButtonColor = new Color(1f, 0.85f, 0.1f, 1f); private const int ResetButtonIndex = 0; private const int BackButtonIndex = 1; private const int ValuesCount = 11; private Tween _fadeTween; private int _selectedButtonIndex; private float _resetHoldTime; private float _serviceHoldTime; private float _statusHideTime; private bool _actionReleased; private bool _serviceReleased; private bool _isClosing; public bool ControlsEnabled { get; set; } private void OnDisable() { _fadeTween?.Kill(); _fadeTween = null; ControlsEnabled = false; } public void Open() { _fadeTween?.Kill(); transform.SetAsLastSibling(); _canvasGroup.alpha = 0f; _canvasGroup.blocksRaycasts = true; _selectedButtonIndex = BackButtonIndex; _resetHoldTime = 0f; _serviceHoldTime = 0f; _statusHideTime = 0f; _actionReleased = false; _serviceReleased = false; _isClosing = false; _status.text = string.Empty; ControlsEnabled = true; RefreshValues(); UpdateButtonSelection(); SetHoldProgress(0f); _fadeTween = _canvasGroup.DOFade(1f, _fadeDuration).SetEase(Ease.OutCubic).SetUpdate(true); _fadeTween.PlayForward(); } public void UpdateControls() { UpdateStatus(); UpdateServiceExit(); if (_isClosing) return; int horizontal = In.GetAxis(JoystickSide.Both, InteractMode.Discrete).x; if (horizontal != 0) { _selectedButtonIndex = _selectedButtonIndex == ResetButtonIndex ? BackButtonIndex : ResetButtonIndex; _resetHoldTime = 0f; SetHoldProgress(0f); UpdateButtonSelection(); } bool actionHeld = In.GetAction(JoystickSide.Both, InteractMode.Continious); if (actionHeld == false) _actionReleased = true; if (_selectedButtonIndex == BackButtonIndex) { _resetHoldTime = 0f; SetHoldProgress(0f); if (_actionReleased && In.GetAction(JoystickSide.Both, InteractMode.Discrete)) Close(); return; } _resetHoldTime = _actionReleased && actionHeld ? Mathf.Min(_resetHoldTime + Time.unscaledDeltaTime, _resetHoldDuration) : 0f; SetHoldProgress(_resetHoldTime / _resetHoldDuration); if (_resetHoldTime < _resetHoldDuration) return; MachineCountersService.ResetResettableCounters(); _resetHoldTime = 0f; _actionReleased = false; SetHoldProgress(0f); RefreshValues(); ShowStatus("ОБНУЛЯЕМЫЕ СЧЁТЧИКИ СБРОШЕНЫ", 2f); } private void RefreshValues() { if (_resettableValues.Length < ValuesCount || _lifetimeValues.Length < ValuesCount) return; MachineCounterSet resettable = MachineCountersService.GetResettableCounters(); MachineCounterSet lifetime = MachineCountersService.GetLifetimeCounters(); SetValues(_resettableValues, resettable); SetValues(_lifetimeValues, lifetime); } private void SetValues(TextMeshProUGUI[] labels, MachineCounterSet counters) { labels[0].text = FormatRevenue(counters.revenue); labels[1].text = counters.prizesIssued.ToString(); labels[2].text = counters.gamesStarted.ToString(); labels[3].text = counters.pveGamesStarted.ToString(); labels[4].text = counters.pvpGamesStarted.ToString(); labels[5].text = FormatDuration(counters.AverageSessionDurationSeconds); for (int botIndex = 0; botIndex < MachineCounterSet.BotCount; botIndex++) labels[6 + botIndex].text = FormatBotResults(counters, botIndex); } private void UpdateButtonSelection() { SetButtonSelected(_resetButton, _selectedButtonIndex == ResetButtonIndex); SetButtonSelected(_backButton, _selectedButtonIndex == BackButtonIndex); } private void UpdateServiceExit() { bool serviceHeld = In.GetService(); if (serviceHeld == false) _serviceReleased = true; _serviceHoldTime = _serviceReleased && serviceHeld ? Mathf.Min(_serviceHoldTime + Time.unscaledDeltaTime, _serviceHoldDuration) : 0f; if (_serviceHoldTime >= _serviceHoldDuration) Close(); } private void ShowStatus(string message, float duration) { _status.text = message; _statusHideTime = Time.unscaledTime + duration; } private void UpdateStatus() { if (_statusHideTime <= 0f || Time.unscaledTime < _statusHideTime) return; _status.text = string.Empty; _statusHideTime = 0f; } private void SetHoldProgress(float progress) { Vector2 anchorMax = _holdProgressFill.anchorMax; anchorMax.x = Mathf.Clamp01(progress); _holdProgressFill.anchorMax = anchorMax; } private void SetButtonSelected(TextMeshProUGUI button, bool selected) { button.color = selected ? _selectedButtonColor : _normalButtonColor; button.rectTransform.localScale = selected ? Vector3.one * 1.08f : Vector3.one; } private void Close() { if (_isClosing) return; _isClosing = true; ControlsEnabled = false; _fadeTween?.Kill(); _fadeTween = _canvasGroup.DOFade(0f, _fadeDuration).SetEase(Ease.InCubic).SetUpdate(true); _fadeTween.OnComplete(() => { _canvasGroup.blocksRaycasts = false; OnClosed?.Invoke(); }); _fadeTween.PlayForward(); } private static string FormatRevenue(long revenue) { string currency = PluralizeUtil.GetValutaPluralized( PaymentSystem.ValutaName, (int)(revenue % 100)); if (currency == "Valuta_Error") currency = PaymentSystem.ValutaName; return $"{revenue:N0} {currency}"; } private static string FormatDuration(double seconds) { TimeSpan duration = TimeSpan.FromSeconds(Math.Max(0d, seconds)); return duration.TotalHours >= 1d ? $"{(int)duration.TotalHours:00}:{duration.Minutes:00}:{duration.Seconds:00}" : $"{duration.Minutes:00}:{duration.Seconds:00}"; } private static string FormatBotResults(MachineCounterSet counters, int botIndex) { return $"Л {counters.easyBotWins[botIndex]}/{counters.easyBotLosses[botIndex]} " + $"С {counters.mediumBotWins[botIndex]}/{counters.mediumBotLosses[botIndex]} " + $"Т {counters.hardBotWins[botIndex]}/{counters.hardBotLosses[botIndex]}"; } }