Files
2026-05-26 16:15:54 +08:00

345 lines
12 KiB
C#

using asap.core;
using UnityEngine;
using UnityEngine.UI;
using game;
using System.Linq;
using TMPro;
using UniRx;
using GameCore;
using System;
using asap.core.common;
using System.Threading.Tasks;
using Game;
public class EventBingoPanel : MonoBehaviour
{
[SerializeField] private EventBingoBlockView[] blockViews;
[SerializeField] private Button btnPlay, btnClose, btnInfo;
[SerializeField] private EventBingoScrollView rewardScrollView;
[SerializeField] private EventBingoNumberRollerView numberRollerView;
[SerializeField] private RewardFly flyingNumberItem;
[SerializeField] private EventBingoTaskView taskView;
[SerializeField] private TMP_Text textTicketCount;
[SerializeField] private BingoTimer timer;
[SerializeField] private RewardFly rewardFlyPrefab;
[SerializeField] private Animator btnAni;
[SerializeField] private GameObject goClickMask;
// [SerializeField] private ChainPackBtn btnPack;
private IObjectPoolService _objectPoolService;
private const float RewardFlyDuration = 1.2f, BaseBallChangeDuration = 1f;
private const string ButtonPlayAnimation = "Pressed", ButtonNormalAnimation = "Normal";
private void Awake()
{
btnClose.onClick.AddListener(OnClickClose);
btnPlay.onClick.AddListener(OnClickPlay);
btnInfo.onClick.AddListener(OnClickInfo);
}
public void Init()
{
var model = GContext.container.Resolve<EventBingoModel>();
var blockViewDataList = model.GetBoardInitiationData();
for (int i = 0; i < blockViews.Length; i++)
blockViews[i].Init(blockViewDataList[i],
new EventBingoNumberItemFlyData
{
StartPos = numberRollerView.StartPos,
FlyingNumberItem = flyingNumberItem
});
numberRollerView.Init(model.NumberRollerDataList.ToList());
taskView.Init(model.TaskData);
UpdateTicketCount();
EventBingoAct.EventAggregator.GetEvent<EventBingoTicketUpdateEvent>()
.Subscribe(_ => UpdateTicketCount())
.AddTo(this);
var timeLimit = model.Ctx.GetTimeLimit();
var timerContext = new TimerContext
{
StartTime = timeLimit.Item1,
ExpiryTime = timeLimit.Item2,
OnExpire = OnClickClose
};
timer.Init(timerContext);
CreateRewardFlyObjectPool();
rewardScrollView.ToggleBingoGlitterFx(false);
}
public async void Start()
{
float duration = 0;
try
{
Debug.Log($"[EventBingo] Start.");
for (int i = 0; i < blockViews.Length; i++)
duration = blockViews[i].SetInto();
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
GContext.Publish(new EventUISound(EventBingoModel.SfxItemIn));
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
PlayNearBingoLoopFx();
}
catch (Exception ex)
{
Debug.LogError("[EventBingo] Panel start error.");
Debug.LogError(ex);
}
}
private void OnClickClose()
{
var _model = GContext.container.Resolve<EventBingoModel>();
_model.ToPlayfabData().Save();
_model.ToPlayerPreferenceData().Save();
ReleaseRewardFlyObjectPool();
GContext.Publish(new UnloadActToNextAct());
}
private async void OnClickPlay()
{
// Debug.Log($"[EventBingo] Play.");
try
{
BlockInput();
PlayButtonAnimation();
var model = GContext.container.Resolve<EventBingoModel>();
var ticketStatus = model.AddTicket(-1);
if (!ticketStatus)
{
Debug.Log($"[EventBingo] Insufficient tickets.");
var res = await OnClickPack();
if (!res)
{
ToastPanel.Show(LocalizationMgr.GetFormatTextValue("UI_ToastPanel_75", LocalizationMgr.GetText(model.Ctx.GetTicketNameKey())));
UnblockInput();
return;
}
UnblockInput();
return;
}
model.NextStep();
var stepState = model.StepState;
model.AddNumberRecord(stepState.Number);
var haveMinorReward = model.DeliverMinorReward(stepState.Index, out var minorReward);
var bingo = EventBingoSystem.CheckBingo(stepState.BoardState, out var pickedIndices);
var hit = model.IsHit(stepState.Number);
int evSuccessMultiple = bingo;
int evItemConsume = model.StepInRound;
int evIsCorrect = hit ? 1 : 0;
string evBoxReward = haveMinorReward ? $"{minorReward.id},{minorReward.count}" : "";
int evMilestoneReward = model.TaskData.TaskId != taskView.TaskId ? model.Ctx.GetTaskRewardDropId(taskView.TaskId) : 0;
// Debug.Log($"<color=red>[EventBingo] -------------------Event Tracking---------------------</color>");
// Debug.Log($"[EventBingo] success_multiple: {evSuccessMultiple}");
// Debug.Log($"[EventBingo] item_consume: {evItemConsume}");
// Debug.Log($"[EventBingo] is_correct: {evIsCorrect}");
// Debug.Log($"[EventBingo] box_reward: {evBoxReward}");
// Debug.Log($"[EventBingo] milestone_reward: {evMilestoneReward}");
// Debug.Log($"[EventBingo] -------------------End of Event Tracking---------------------");
#if AGG
using (var e = GEvent.GameEvent("event_bingo_start"))
{
e.AddContent("success_multiple", evSuccessMultiple)
.AddContent("item_consume", evItemConsume)
.AddContent("is_correct", evIsCorrect)
.AddContent("box_reward", evBoxReward)
.AddContent("milestone_reward", evMilestoneReward);
}
#endif
await numberRollerView.RollIn(model.NumberRollerDataList.Last.Value);
if (!hit)
{
await taskView.UpdateProgress();
// PlayNearBingoLoopFx();
UnblockInput();
return;
}
CancelNearBingoLoopFx();
EventBingoAct.EventAggregator.Publish(new EventBingoNumberShown { Number = stepState.Number });
await Task.Delay(TimeSpan.FromSeconds(RewardFlyDuration));
// all animation in nml
// foreach (var v in blockViews)
// {
// v.SetStandBy();
// }
// Debug.Log($"[EventBingo] Clear animation.");
await Awaiters.NextFrame;
if (haveMinorReward)
{
GContext.Publish(new EventRewardFlyStashRequest(reward: minorReward,
sourceIconRt: blockViews[stepState.Index].GetComponent<RectTransform>(),
doesPlayOpen: true));
await Task.Delay(TimeSpan.FromSeconds(RewardFlyDuration));
}
if (bingo > 0)
{
Debug.Log($"[EventBingo] Bingo * {bingo}!");
var rewards = model.Ctx.GetBingoRewards(bingo, model.RoundCount);
rewards.ForEach(EventBingoSystem.GrantReward);
model.NextRound();
rewardScrollView.ToggleBingoGlitterFx(true);
var bingoDuration = PlayBingoAnimation(pickedIndices);
await Task.Delay(TimeSpan.FromSeconds(bingoDuration));
var rewardPanel = (await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoRewardPanel))
.GetComponent<EventBingoRewardPanel>();
var tcs = new TaskCompletionSource<bool>();
rewardPanel.Init(new EventBingoRewardPanelData { BingoCount = bingo, Rewards = rewards }, EventBingoAct.EventAggregator, tcs);
await tcs.Task;
rewardScrollView.ToggleBingoGlitterFx(false);
await taskView.UpdateProgress();
rewardScrollView.ReloadData(model.RoundCount);
await RefreshPanel();
UnblockInput();
}
else
{
await taskView.UpdateProgress();
PlayNearBingoLoopFx();
UnblockInput();
}
}
catch (Exception e)
{
Debug.LogError("[EventBingo] Bingo play error.");
Debug.LogError(e);
}
}
private async void PlayButtonAnimation()
{
try
{
btnAni.Play(ButtonPlayAnimation);
await Task.Delay(TimeSpan.FromSeconds(0.3f));
btnAni.Play(ButtonNormalAnimation);
}
catch (Exception e)
{
Debug.LogError(e);
}
}
private async Task RefreshPanel()
{
var model = GContext.container.Resolve<EventBingoModel>();
var blockViewDataList = model.GetBoardInitiationData();
float duration = 0;
numberRollerView.SetEmpty();
GContext.Publish(new EventUISound(EventBingoModel.SfxItemOut));
for (int i = 0; i < blockViews.Length; i++)
duration = blockViews[i].SetOut();
await Task.Delay(TimeSpan.FromSeconds(duration));
for (int i = 0; i < blockViews.Length; i++)
{
blockViews[i].Init(blockViewDataList[i],
new EventBingoNumberItemFlyData
{
StartPos = numberRollerView.StartPos,
FlyingNumberItem = flyingNumberItem
});
}
await Awaiters.NextFrame;
for (int i = 0; i < blockViews.Length; i++)
duration = blockViews[i].SetInto();
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
GContext.Publish(new EventUISound(EventBingoModel.SfxItemIn));
await Task.Delay(TimeSpan.FromSeconds(duration / 2));
}
private void PlayNearBingoLoopFx()
{
var model = GContext.container.Resolve<EventBingoModel>();
var nearBingoIndices = EventBingoSystem.CheckNearBingoIndices(model.StepState.BoardState);
for (int i = 0; i < nearBingoIndices.Length; i++)
{
var index = nearBingoIndices[i];
blockViews[index].SetNearBingo();
}
}
private float PlayBingoAnimation(int[] pickedIndices)
{
// Debug.Log("[EventBingo] Play Bingo.");
float res = 0;
foreach (var index in pickedIndices)
{
res = blockViews[index].SetBingo();
}
return res;
}
private void CancelNearBingoLoopFx()
{
Debug.Log("[EventBingo] Play cancel Bingo.");
foreach (var v in blockViews)
{
v.SetStandBy();
}
}
private void UpdateTicketCount()
{
var n = GContext.container.Resolve<EventBingoModel>().TicketCount;
textTicketCount.text = $"{n}";
textTicketCount.color = n > 0 ? Color.white : Color.red;
}
private async Task<bool> OnClickPack()
{
try
{
var chainPackData = GContext.container.Resolve<FishingEventData>().ChainPackWithProgressMigrationData;
if (chainPackData == null || chainPackData.IsChainPackDepleted)
{
Debug.Log("[EventBingo] No chain pack.");
return false;
}
var panel = (await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoChainPackPanel)).GetComponent<ThanksGivingPopupPanel>();
panel.Init(chainPackData);
return true;
}
catch (Exception e)
{
Debug.Log($"[EventBingo]Open Chain Pack Error:");
Debug.LogError(e);
return false;
}
}
private async void OnClickInfo()
{
try
{
await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoInfoPanel);
}
catch (Exception e)
{
Debug.LogError(e);
}
}
private void CreateRewardFlyObjectPool()
{
_objectPoolService = GContext.container.Resolve<IObjectPoolService>();
_objectPoolService.CreatePool(rewardFlyPrefab, 0, 10);
}
private void ReleaseRewardFlyObjectPool()
{
_objectPoolService?.DestroyPool(typeof(RewardFly));
}
private void BlockInput()
{
// Debug.Log("[EventBingo] Block.");
goClickMask.SetActive(true);
}
private void UnblockInput()
{
// Debug.Log("[EventBingo] Unblock.");
goClickMask.SetActive(false);
}
}