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(); 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() .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(); _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(); 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($"[EventBingo] -------------------Event Tracking---------------------"); // 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(), 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(); var tcs = new TaskCompletionSource(); 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(); 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(); 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().TicketCount; textTicketCount.text = $"{n}"; textTicketCount.color = n > 0 ? Color.white : Color.red; } private async Task OnClickPack() { try { var chainPackData = GContext.container.Resolve().ChainPackWithProgressMigrationData; if (chainPackData == null || chainPackData.IsChainPackDepleted) { Debug.Log("[EventBingo] No chain pack."); return false; } var panel = (await UIManager.Instance.ShowUINotLoading(UITypes.EventBingoChainPackPanel)).GetComponent(); 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(); _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); } }