Files
ft/Client/Assets/Scripts/UI/OfferTreasureAscent/OfferTreasureAscentMainPanel.cs
2026-06-29 21:18:33 +08:00

319 lines
11 KiB
C#

using UnityEngine;
using OfferTreasureAscent;
using asap.core;
using UnityEngine.UI;
using GameCore;
using System.Collections.Generic;
using TMPro;
using System.Threading.Tasks;
using System.Linq;
using game;
using UniRx;
using System;
public class OfferTreasureAscentMainPanel : MonoBehaviour
{
[SerializeField] private OfferTreasureAscentItemView[] itemViews;
[SerializeField] private OfferTreasureAscentGrandRewardView grandRewardView;
[SerializeField] private Button btnClaim, btnClose, btnProbability;
[SerializeField] private TMP_Text textBtnClaim;
[SerializeField] private float selectionDuration = 0.1f, finalSelectionGap = 0.2f, durationMargin = 0.1f;
[SerializeField] private float[] selectionGapList = { 0.08f, 0.08f, 0.1f, 0.14f }, fxDurationList = { 0.06f, 0.12f, 0.24f, 0.36f, 0.48f };
[SerializeField] private BingoTimer timer;
[SerializeField] private GameObject fxGrandReward;
private int _idx = -1;
private List<ItemData> _finalRewards = null;
private OfferTreasureAscentPanelState _state = OfferTreasureAscentPanelState.Normal;
private bool _isAnimating = false;
private void Awake()
{
btnClose.onClick.AddListener(OnClickClose);
btnClaim.onClick.AddListener(OnClickClaim);
btnProbability.onClick.AddListener(OnClickProbability);
GContext.OnEvent<FishingTurnTableContinueMultiDraw>()
.Subscribe(OnRewardClaimed).AddTo(this);
}
private void Start()
{
var manager = GContext.container.Resolve<Manager>();
grandRewardView.Init(manager.GetGrandReward());
var rewards = manager.GetRewards();
for (int i = 0; i < itemViews.Length; i++)
itemViews[i].Init(rewards[i], manager.IsClaimed(i));
UpdateButton();
timer.Init(manager.GetEntranceData().TimerData);
}
private void OnClickClose()
{
if (_isAnimating)
return;
UIManager.Instance.DestroyUI(UITypes.OfferTreasureAscentMainPanel);
}
private async void OnClickClaim()
{
try
{
int evIapId, evEventId, evRewardId;
if (_isAnimating)
return;
OnEnterAnimation();
var manager = GContext.container.Resolve<Manager>();
(_idx, _finalRewards, evIapId) = await manager.GrantRandomReward();
if (_idx < 0)
{
Debug.LogError("[OfferTreasureAscent] No reward to claim. Something went wrong.");
OnExitAnimation();
return;
}
evEventId = manager.EventId;
evRewardId = manager.GetRandomizedRewardList()[_idx].ID;
// Debug.Log($"[OfferTreasureAscent] event tracking EventId: {evEventId}");
// Debug.Log($"[OfferTreasureAscent] event tracking IapId: {evIapId}");
// Debug.Log($"[OfferTreasureAscent] event tracking RewardId: {evRewardId}");
#if AGG
using (var e = GEvent.GameEvent("event_OfferTreasureAscent"))
{
e.AddContent("event_id", evEventId)
.AddContent("iap_id", evIapId)
.AddContent("reward_id", evRewardId);
}
#endif
await PlaySelectionAnimation(_idx);
GContext.Publish(new ShowData());
if (_finalRewards != null)
_state = OfferTreasureAscentPanelState.Final;
}
catch (Exception e)
{
Debug.LogError(e);
}
}
private async void OnRewardClaimed(FishingTurnTableContinueMultiDraw e)
{
try
{
if (_state == OfferTreasureAscentPanelState.Normal)
{
itemViews[_idx].SetClaimed();
UpdateButton();
OnExitAnimation();
}
else if (_state == OfferTreasureAscentPanelState.Final)
{
itemViews[_idx].SetClaimed();
PlayGrandRewardFx();
await Task.Delay(TimeSpan.FromSeconds(0.7f));
Debug.Log("[OfferTreasureAscent] Show special panel.");
var openGo = await UIManager.Instance.ShowUINotLoading(UITypes.OfferTreasureAscentBoxPanel);
await openGo.GetComponent<OfferTreasureAscentGrandRewardPopup>().PlayAnimation();
UIManager.Instance.DestroyUI(UITypes.OfferTreasureAscentBoxPanel);
GContext.Publish(new ShowData(_finalRewards));
GContext.Publish(new ShowData());
_state = OfferTreasureAscentPanelState.Close;
}
else if (_state == OfferTreasureAscentPanelState.Close)
{
GContext.Publish(new EventOfferTreasureAscentHide());
UIManager.Instance.DestroyUI(UITypes.OfferTreasureAscentMainPanel);
}
}
catch (Exception ex)
{
Debug.LogError(ex);
OnExitAnimation();
}
}
private void PlayGrandRewardFx()
{
fxGrandReward.SetActive(false);
fxGrandReward.SetActive(true);
}
private async Task PlaySelectionAnimation(int idx)
{
var availableViews = GetAvailableRewardViews();
if (availableViews.Length <= 0)
{
Debug.LogError("[OfferTreasureAscent] No available rewards to claim.");
return;
}
if (availableViews.Length == 1)
{
await availableViews[0].PlaySelectedAsync(selectionDuration);
availableViews[0].SetClaimed();
return;
}
// all available views
var reversedAvailableViews = new List<OfferTreasureAscentItemView>();
for (int j = itemViews.Length - 1; j >= 0; j--)
{
if (itemViews[j].IsClaimed)
continue;
reversedAvailableViews.Add(itemViews[j]);
}
for (int i = 0; i < selectionGapList.Length - 1; i++)
{
var minimalGap = (fxDurationList[i] + durationMargin) / reversedAvailableViews.Count;
foreach (var iv in reversedAvailableViews)
{
iv.PlayFxBlink(i);
var gap = selectionGapList[i];
await Task.Delay(TimeSpan.FromSeconds(Mathf.Max(minimalGap, gap)));
}
}
// all available views, till the picked one
reversedAvailableViews.Clear();
for (int j = itemViews.Length - 1; j > idx; j--)
{
if (itemViews[j].IsClaimed)
continue;
reversedAvailableViews.Add(itemViews[j]);
}
if (reversedAvailableViews.Count == 1)
{
// reversedAvailableViews[0].PlayFxLong();
reversedAvailableViews[0].PlayFxBlink(selectionGapList.Length - 1);
Debug.Log($"[OfferTreasureAscent] single.");
// var gap = Mathf.Lerp(selectionGapList[^1], finalSelectionGap, (j) / (float)reversedAvailableViews.Count - 1);
await Task.Delay(TimeSpan.FromSeconds(finalSelectionGap));
}
else
{
for (int j = 0; j < reversedAvailableViews.Count; j++)
{
// reversedAvailableViews[j].PlayFxLong();
var minimalGap = (fxDurationList[^1] + durationMargin) / reversedAvailableViews.Count;
reversedAvailableViews[j].PlayFxBlink(selectionGapList.Length - 1);
// Debug.Log($"[OfferTreasureAscent] {j} / ({reversedAvailableViews.Count - 1}) = {j / ((float)reversedAvailableViews.Count - 1)}.");
var gap = Mathf.Lerp(selectionGapList[^1], finalSelectionGap, j / ((float)reversedAvailableViews.Count - 1));
await Task.Delay(TimeSpan.FromSeconds(Mathf.Max(gap, minimalGap)));
}
}
await itemViews[idx].PlaySelectedAsync(selectionDuration);
}
private OfferTreasureAscentItemView[] GetAvailableRewardViews()
{
return itemViews.Where(v => !v.IsClaimed).ToArray();
}
private void UpdateButton()
{
var manager = GContext.container.Resolve<Manager>();
var iapId = manager.GetIapId();
if (iapId <= 0)
{
textBtnClaim.text = LocalizationMgr.GetText("OfferTreasureAscentSunTemplePanel_3");
}
else
{
GContext.container.Resolve<PlayerItemData>().ResolveIapId(iapId, out _, out var price);
textBtnClaim.text = LocalizationMgr.GetFormatTextValue("OfferTreasureAscentSunTemplePanel_2", price);
}
}
private async void OnClickProbability()
{
try
{
if (_isAnimating)
return;
var manager = GContext.container.Resolve<Manager>();
var panelGo = await UIManager.Instance.ShowUINotLoading(UITypes.OfferTreasureAscentProbabilityPanel);
panelGo.GetComponent<GeneralProbabilityPanel>().Init(manager.GetProbabilityData());
}
catch (System.Exception e)
{
Debug.Log(e);
}
}
private void OnEnterAnimation()
{
_isAnimating = true;
btnClaim.gameObject.SetActive(false);
}
private void OnExitAnimation()
{
_isAnimating = false;
btnClaim.gameObject.SetActive(true);
}
private void OnDestroy()
{
var manager = GContext.container.Resolve<Manager>();
RedPointManager.Instance.SetRedPointState(manager.RedPointKey, manager.DoNeedRedPoint());
if (_finalRewards != null)
GContext.Publish(new EventOfferTreasureAscentHide());
}
#if UNITY_EDITOR
// private List<Dictionary<int, int>> _testRes;
// [SerializeField] private int testCount = 50;
// private void Update()
// {
// if (Input.GetKeyDown(KeyCode.T))
// {
// _testRes = new List<Dictionary<int, int>>();
// for (int i = 0; i < testCount; i++)
// {
// Debug.Log($"<color=red>[OfferTreasureAscent] Test {i} ===============================================================</color>");
// var manager = GContext.container.Resolve<Manager>();
// manager.InitTest();
// for (int j = 0; j < manager.GetRewardCount(); j++)
// {
// var idx = manager.PickRandomAvailableRewardIdx();
// if (_testRes.Count <= j)
// _testRes.Add(new Dictionary<int, int>());
// if (_testRes[j].ContainsKey(idx + 1))
// _testRes[j][idx + 1]++;
// else
// _testRes[j].Add(idx + 1, 1);
// manager.Claim(idx);
// manager.TryGrantReward(idx);
// }
// }
// for (int i = 0; i < _testRes.Count; i++)
// {
// Debug.Log($"@{i + 1}: {Newtonsoft.Json.JsonConvert.SerializeObject(_testRes[i], Newtonsoft.Json.Formatting.Indented)}");
// }
// }
// else if (Input.GetKeyDown(KeyCode.F))
// {
// ShowGrandPopup();
// }
// }
#endif
private async void ShowGrandPopup()
{
var openGo = await UIManager.Instance.ShowUINotLoading(UITypes.OfferTreasureAscentBoxPanel);
await openGo.GetComponent<OfferTreasureAscentGrandRewardPopup>().PlayAnimation();
UIManager.Instance.DestroyUI(UITypes.OfferTreasureAscentBoxPanel);
}
}
public enum OfferTreasureAscentPanelState
{
Normal,
Final,
Close
}