301 lines
12 KiB
C#
301 lines
12 KiB
C#
using DG.Tweening;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using System.Collections.Generic;
|
||
using asap.core;
|
||
using PinballUncountable;
|
||
using UniRx;
|
||
using System.Threading.Tasks;
|
||
using System;
|
||
using Game;
|
||
using GameCore;
|
||
using game;
|
||
|
||
public class PinballUncountableProgressBarView : MonoBehaviour
|
||
{
|
||
[SerializeField] private Image[] bars;
|
||
[SerializeField] private PinballUncountableProgressRewardItemView[] rewards;
|
||
[SerializeField] private OfferTreasureAscentGrandRewardView grandRewardView;
|
||
[SerializeField] private RectTransform scroller;
|
||
[SerializeField] private float startPos = 1246.9f, gap = 188f;
|
||
[SerializeField] private TMP_Text textScore, textRewardCount;
|
||
[SerializeField] private PinballUncountableGaugeAnimationView gauge;
|
||
private int _scoreDisplay, _scoreLogic, _idx;
|
||
private readonly int _displayCount = 3;
|
||
private Tween _tween = null;
|
||
private readonly Queue<int> _scoreQueue = new Queue<int>();
|
||
private bool _isProcessingQueue = false;
|
||
// public bool IsProcessingQueue => _isProcessingQueue;
|
||
|
||
private void Awake()
|
||
{
|
||
var manager = GContext.container.Resolve<Manager>();
|
||
manager.EventAggregator.GetEvent<EventExit>().Subscribe(OnScore).AddTo(this);
|
||
}
|
||
|
||
public void Init(int idx, List<PinballUncountableProgressRewardData> items)
|
||
{
|
||
var manager = GContext.container.Resolve<Manager>();
|
||
_idx = idx;
|
||
if (items.Count < rewards.Length)
|
||
Debug.LogError($"Rewards count {items.Count}, less than {rewards.Length}.", this);
|
||
for (int i = 0; i < rewards.Length; i++)
|
||
rewards[i].Init(items[i]);
|
||
grandRewardView.Init(items[^1].Item, manager.InflationRate);
|
||
_scoreLogic = manager.Score;
|
||
_scoreDisplay = _scoreLogic;
|
||
SetScrollerToIdx(idx);
|
||
(var barIdx, var percentage) = manager.TableContext.GetBarProgressDataFromScore(_scoreDisplay);
|
||
SetBarsByScore(barIdx, percentage);
|
||
SetScoreText(manager.TableContext.GetScopeScoreFromActualScore(_scoreLogic), manager.TableContext.GetCurrentMaxScore(_scoreLogic));
|
||
|
||
UpdateRewardCount(0, rewards.Length + 1);
|
||
for (int i = items.Count - 1; i >= 0; i--)
|
||
{
|
||
if (items[i].IsReceived)
|
||
{
|
||
UpdateRewardCount(i + 1, rewards.Length + 1);
|
||
break;
|
||
}
|
||
}
|
||
|
||
// _maxScore = manager.TableContext.GetMaxScore(manager.Score);
|
||
}
|
||
|
||
private void ResetProgressBar()
|
||
{
|
||
var manager = GContext.container.Resolve<Manager>();
|
||
_idx = 0;
|
||
var items = manager.TableContext.GetRewardsData(manager.InflationRate, manager.Score);
|
||
if (items.Count < rewards.Length)
|
||
Debug.LogError($"Rewards count {items.Count}, less than {rewards.Length}.", this);
|
||
for (int i = 0; i < rewards.Length; i++)
|
||
rewards[i].Init(items[i]);
|
||
SetScrollerToIdx(0);
|
||
SetBarsByScore(0, 0);
|
||
SetScoreText(0, manager.TableContext.GetCurrentMaxScore(_scoreLogic));
|
||
foreach (var reward in rewards)
|
||
reward.SetReceived(false);
|
||
grandRewardView.Init(items[^1].Item, manager.InflationRate);
|
||
grandRewardView.SetClaimed(false);
|
||
// _maxScore = manager.TableContext.GetMaxScore(manager.Score);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Update score text, update score progress bar, and while at it, if a new reward is to be given, tick it and move the scroller
|
||
/// </summary>
|
||
/// <param name="e">The incoming exit event</param>
|
||
private void OnScore(EventExit e)
|
||
{
|
||
var manager = GContext.container.Resolve<Manager>();
|
||
var score2Add = manager.TableContext.GetScoreFromExitIndex(e.ExitIdx);
|
||
_scoreLogic += score2Add;
|
||
_scoreQueue.Enqueue(_scoreLogic);
|
||
gauge.OnAddScore(score2Add);
|
||
ProcessQueue();
|
||
}
|
||
|
||
private async void ProcessQueue()
|
||
{
|
||
if (_isProcessingQueue)
|
||
return;
|
||
var manager = GContext.container.Resolve<Manager>();
|
||
_isProcessingQueue = true;
|
||
|
||
while (_scoreQueue.Count > 0)
|
||
{
|
||
var targetScore = _scoreQueue.Dequeue();
|
||
await MoveBarsByScoreAsync(targetScore);
|
||
}
|
||
_isProcessingQueue = false;
|
||
}
|
||
|
||
#region ScoreText
|
||
private void SetScoreText(int score, int maxScore)
|
||
{
|
||
textScore.text = score.ToString() + "/" + maxScore.ToString();
|
||
}
|
||
#endregion
|
||
|
||
#region Bars
|
||
private void SetBarsByScore(int idx, float percentage)
|
||
{
|
||
var manager = GContext.container.Resolve<Manager>();
|
||
// (var idx, var percentage) = manager.TableContext.GetBarProgressDataFromScore(score);
|
||
for (int i = 0; i < bars.Length; i++)
|
||
{
|
||
if (i < idx)
|
||
bars[i].fillAmount = 1;
|
||
else if (i == idx)
|
||
bars[i].fillAmount = percentage;
|
||
else
|
||
bars[i].fillAmount = 0;
|
||
}
|
||
}
|
||
|
||
[SerializeField] private float barSpeed = 1f;
|
||
private async Task MoveBarsByScoreAsync(int targetScore)
|
||
{
|
||
try
|
||
{
|
||
var manager = GContext.container.Resolve<Manager>();
|
||
(var oldIdx, var oldPercentage) = manager.TableContext.GetBarProgressDataFromScore(_scoreDisplay);
|
||
(var newIdx, var newPercentage) = manager.TableContext.GetBarProgressDataFromScore(targetScore);
|
||
// Debug.Log($"[PinballUncountable] From {_scoreDisplay} To {targetScore} !");
|
||
if (oldIdx == newIdx)
|
||
{
|
||
// Debug.Log("[PinballUncountable] BarMove: Same!");
|
||
await bars[oldIdx].DOFillAmount(newPercentage, (newPercentage - oldPercentage) / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
MoveScrollerToIdx(oldIdx);
|
||
_scoreDisplay = targetScore;
|
||
SetScoreText(manager.TableContext.GetScopeScoreFromActualScore(targetScore), manager.TableContext.GetCurrentMaxScore(targetScore));
|
||
}
|
||
else if (oldIdx < newIdx)
|
||
{
|
||
// Debug.Log("[PinballUncountable] BarMove: Next!");
|
||
await bars[oldIdx].DOFillAmount(1, (1 - oldPercentage) / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
await SetReceived(oldIdx);
|
||
MoveScrollerToIdx(oldIdx);
|
||
for (int i = oldIdx + 1; i < newIdx; i++)
|
||
{
|
||
await bars[i].DOFillAmount(1, 1 / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
await SetReceived(i);
|
||
MoveScrollerToIdx(i);
|
||
}
|
||
await bars[newIdx].DOFillAmount(newPercentage, newPercentage / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
MoveScrollerToIdx(newIdx);
|
||
_scoreDisplay = targetScore;
|
||
SetScoreText(manager.TableContext.GetScopeScoreFromActualScore(targetScore), manager.TableContext.GetCurrentMaxScore(targetScore));
|
||
}
|
||
else
|
||
{
|
||
// Debug.Log("[PinballUncountable] BarMove: Twist!");
|
||
await bars[oldIdx].DOFillAmount(1, (1 - oldPercentage) / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
SetScoreText(manager.TableContext.GetCurrentMaxScore(_scoreDisplay), manager.TableContext.GetCurrentMaxScore(_scoreDisplay));
|
||
await SetReceived(oldIdx);
|
||
|
||
Debug.Log("[OfferTreasureAscent] Show special panel.");
|
||
var openGo = await UIManager.Instance.ShowUINotLoading(UITypes.PinballUncountableBoxPanel);
|
||
await openGo.GetComponent<OfferTreasureAscentGrandRewardPopup>().PlayAnimation();
|
||
UIManager.Instance.DestroyUI(UITypes.PinballUncountableBoxPanel);
|
||
// 等待玩家在奖励弹窗中点击领取后再继续:订阅一次 FishingTurnTableContinueMultiDraw,弹窗关闭时会发布该事件
|
||
var claimTcs = new TaskCompletionSource<bool>();
|
||
IDisposable claimSub = null;
|
||
claimSub = GContext.OnEvent<FishingTurnTableContinueMultiDraw>()
|
||
.Take(1)
|
||
.Subscribe(_ =>
|
||
{
|
||
claimTcs.TrySetResult(true);
|
||
claimSub?.Dispose();
|
||
});
|
||
GContext.Publish(new ShowData(grandRewardView.RewardItems));
|
||
GContext.Publish(new ShowData());
|
||
await claimTcs.Task;
|
||
claimSub?.Dispose();
|
||
|
||
MoveScrollerToIdx(oldIdx);
|
||
for (int i = oldIdx + 1; i < bars.Length; i++)
|
||
{
|
||
await bars[i].DOFillAmount(1, 1 / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
await SetReceived(i);
|
||
MoveScrollerToIdx(i);
|
||
}
|
||
ResetProgressBar();
|
||
for (int i = 0; i < newIdx; i++)
|
||
{
|
||
await bars[i].DOFillAmount(1, 1 / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
await SetReceived(i);
|
||
MoveScrollerToIdx(i);
|
||
}
|
||
await bars[newIdx].DOFillAmount(newPercentage, newPercentage / barSpeed).SetId(this).AsyncWaitForCompletion();
|
||
MoveScrollerToIdx(newIdx);
|
||
_scoreDisplay = targetScore;
|
||
SetScoreText(manager.TableContext.GetScopeScoreFromActualScore(targetScore), manager.TableContext.GetCurrentMaxScore(targetScore));
|
||
}
|
||
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Debug.LogError(e);
|
||
|
||
}
|
||
|
||
}
|
||
#endregion
|
||
|
||
#region Scroller
|
||
private void MoveScrollerToIdx(int idx)
|
||
{
|
||
idx -= 1;
|
||
idx = Mathf.Clamp(idx, 0, rewards.Length - _displayCount);
|
||
_idx = idx;
|
||
// scroller.anchoredPosition = new Vector2(startPos - gap * idx, scroller.anchoredPosition.y);
|
||
_tween?.Kill();
|
||
_tween = scroller.DOAnchorPosX(startPos - gap * idx, 0.5f);
|
||
// Debug.Log($"[PinballUncountable] move to {idx}");
|
||
}
|
||
|
||
private void SetScrollerToIdx(int idx)
|
||
{
|
||
idx = Mathf.Clamp(idx, 0, rewards.Length - _displayCount);
|
||
_idx = idx;
|
||
scroller.anchoredPosition = new Vector2(startPos - gap * idx, scroller.anchoredPosition.y);
|
||
}
|
||
#endregion
|
||
|
||
#region Reward
|
||
// UGLY: may be able to separate final reward display
|
||
private async Task SetReceived(int idx)
|
||
{
|
||
if (idx < 0 || idx > rewards.Length)
|
||
return;
|
||
if (idx == rewards.Length)
|
||
{
|
||
Debug.Log("[PinballUncountable] SetReceived: Final reward!!!!!!!!!!");
|
||
grandRewardView.SetClaimed();
|
||
GContext.Publish(new EventUISound("audio_ui_reward_claim"));
|
||
UpdateRewardCount(idx + 1, rewards.Length + 1);
|
||
// await Task.Delay(TimeSpan.FromSeconds(2f));
|
||
return;
|
||
}
|
||
if (rewards[idx] == null)
|
||
return;
|
||
rewards[idx].SetReceived(true);
|
||
GContext.Publish(new EventUISound("audio_ui_reward_claim"));
|
||
UpdateRewardCount(idx + 1, rewards.Length + 1);
|
||
await Task.Delay(TimeSpan.FromSeconds(0.5f));
|
||
}
|
||
#endregion
|
||
|
||
private void UpdateRewardCount(int receivedRewardCount, int maxRewardCount)
|
||
{
|
||
// textRewardCount.text = $"我拿到了{receivedRewardCount}/{maxRewardCount},缺少多语言";
|
||
textRewardCount.text = LocalizationMgr.GetFormatTextValue("UI_EventPinballUncountableCowboyPanel_2", receivedRewardCount, maxRewardCount);
|
||
}
|
||
|
||
#if UNITY_EDITOR
|
||
[SerializeField] private int testScore;
|
||
private void Update()
|
||
{
|
||
if (Input.GetKeyDown(KeyCode.Space))
|
||
{
|
||
MoveScrollerToIdx(_idx + 1);
|
||
}
|
||
if (Input.GetKeyDown(KeyCode.R))
|
||
{
|
||
scroller.anchoredPosition = new Vector2(startPos, 0);
|
||
_idx = 0;
|
||
}
|
||
// if (Input.GetKeyDown(KeyCode.B))
|
||
// {
|
||
// SetBarsByScore(testScore);
|
||
// }
|
||
}
|
||
|
||
// private void OnGUI()
|
||
// {
|
||
// GUI.Box(new Rect(20, 20, 200, 20), $"IsProcessingQueue: {_isProcessingQueue}");
|
||
// }
|
||
#endif
|
||
} |