using asap.core; using GameCore; using TMPro; using UnityEngine; using UnityEngine.UI; using game; using UniRx; using System.Linq; using DG.Tweening; using System.Threading.Tasks; using asap.core.common; public class EventCanPanel : MonoBehaviour { [SerializeField] private Button btnClose, btnInfo, btnPack; [SerializeField] private TMP_Text textTimer, textTicketCount; [SerializeField] private EventCanGemTaskView[] gemTaskViews; [SerializeField] private EventCanProgressTaskView progressTaskView; [SerializeField] private EventCanCan[] canList; [SerializeField] private RewardFly rewardFly; [SerializeField] private Animation basketAside, basketPopup; [SerializeField] private GameObject goBasketIcon, goCanTrace; [SerializeField] private DeferredRewardStashButton stashBtn; [SerializeField] private RewardFlyBatchController rewardFlyBatchController; private EventCanEntranceBtnData _entranceData; private IObjectPoolService _objectPoolService; private int EmptyCanSlotCount => canList.Where(x => !x.isActiveAndEnabled).Count(); private void Start() { btnClose.onClick.AddListener(OnClickClose); btnInfo.onClick.AddListener(OnClickInfo); btnPack.onClick.AddListener(OnClickPack); var model = GContext.container.Resolve(); for (int i = 0; i < gemTaskViews.Length; i++) gemTaskViews[i].Init(model.GemTasks[(EEventCanRewardType)(i + 1)], EventCanAct.EventAggregator, rewardFlyBatchController); progressTaskView.Init(model.ProgressTaskInfo, EventCanAct.EventAggregator); for (int i = 0; i < canList.Length; i++) canList[i].Init(i, model.CanList[i]); EventCanAct.EventAggregator.GetEvent().Subscribe(OnCanOpen).AddTo(this); OnTicketCountChange(); basketAside.transform.parent.gameObject.SetActive(true); basketAside.Play(BASKET_IDLE); basketPopup.transform.parent.gameObject.SetActive(false); EventCanAct.EventAggregator.GetEvent().Subscribe(_ => OnTicketCountChange()).AddTo(this); EventCanAct.EventAggregator.GetEvent().Subscribe(_ => OnClickPack()).AddTo(this); _entranceData = GContext.container.Resolve().GetEntranceBtnData(); UpdateTimer(); Observable.Interval(System.TimeSpan.FromSeconds(1f)).Subscribe(UpdateTimer).AddTo(this); var chainPackData = GContext.container.Resolve(); RedPointManager.Instance.SetRedPointState(chainPackData.RedPointKey, chainPackData.DoNeedPackRedPoint); CreateRewardFlyObjectPool(); model.BlockState = EEventCanBlockState.Available; } private void UpdateTimer(long _ = 0L) { textTimer.text = ConvertTools.ConvertTime2(_entranceData.RemainingTime); if (!_entranceData.IsActive) Destroy(gameObject); } private void OnCanOpen(EventCanOpenEvent e) { OnTicketCountChange(); if (e.RewardInfo.RewardType == EEventCanRewardType.Supply) { PlayBasketAppear(e.CanPosition); PopCans(); } var model = GContext.container.Resolve(); model.ToPlayerPreferenceData().Save(); } private void OnTicketCountChange() { var model = GContext.container.Resolve(); textTicketCount.text = model.TicketCount.ToString(); textTicketCount.color = model.TicketCount > 0 ? Color.white : Color.red; } private void OnClickClose() { ReleaseRewardFlyObjectPool(); GContext.Publish(new UnloadActToNextAct()); } private async void OnClickInfo() { try { await UIManager.Instance.ShowUINotLoading(UITypes.EventCanInfoPanel); } catch (System.Exception e) { Debug.Log($"[EventCan]{e.Message}\n{e.StackTrace}"); } } private async void OnClickPack() { var chainPackData = GContext.container.Resolve(); try { // PlayBtnPressedAnimation(); GameObject go; if (chainPackData.ChainProgress >= chainPackData.ChainListCount) { go = await UIManager.Instance.ShowUINotLoading(UITypes.EventCanNormalPackPanel); var normalPanel = go.GetComponent(); normalPanel.Init(GContext.container.Resolve().GetNormalPackInfo()); return; } go = await UIManager.Instance.ShowUINotLoading(UITypes.EventCanChainPackPanel); var panel = go.GetComponent(); panel.Init(chainPackData); } catch (System.Exception e) { Debug.Log($"[EventCan]Pack Error: {e.Message}\n{e.StackTrace}"); } } private async void PlayBtnPressedAnimation() { btnPack.GetComponent().Play("Pressed"); await Task.Delay(System.TimeSpan.FromSeconds(0.5f)); btnPack.GetComponent().Play("Normal"); } private const string BASKET_IDLE = "basket_idle", BASKET_IN = "basket_in", BASKET_OUT = "basket_out"; private const string BASKET_FLY_IN = "basket_fly_in", BASKET_FLY_OUT = "basket_fly_out", BASKET_FLY_LOOP = "basket_fly_loop", BASKET_SHOW = "basket_show"; public void PlayBasketAppear(Vector3 pos) { ShowBasketIcoWithDelay(pos, EventCanAct.ParamsCtrl.BasketShowDelay); // PlayAnimationWithDelay(basketPopup, BASKET_SHOW); PlayAnimationWithDelay(basketAside, BASKET_OUT, EventCanAct.ParamsCtrl.BasketSlideOutDelay); PlayAnimationWithDelay(basketPopup, BASKET_FLY_IN, EventCanAct.ParamsCtrl.BasketFlyInDelay); PlayAnimationWithDelay(basketPopup, BASKET_FLY_LOOP, EventCanAct.ParamsCtrl.BasketFlyLoopDelay); var newCanCount = EmptyCanSlotCount; float loopTime = EventCanAct.ParamsCtrl.CanPopupInterval * newCanCount + EventCanAct.ParamsCtrl.CanPopupDuration; // Debug.Log($"[EventCan] {loopTime} = {newCanCount} * {EventCanAct.ParamsCtrl.CanPopupInterval}"); PlayAnimationWithDelay(basketPopup, BASKET_FLY_OUT, EventCanAct.ParamsCtrl.BasketFlyLoopDelay + loopTime); PlayAnimationWithDelay(basketAside, BASKET_IN, EventCanAct.ParamsCtrl.BasketFlyLoopDelay + loopTime + EventCanAct.ParamsCtrl.BasketSlideInDeltaDelay); } public async void PopCans() { try { await Task.Delay(System.TimeSpan.FromSeconds(EventCanAct.ParamsCtrl.BasketFlyLoopDelay)); var emptyIdxLst = canList .Select((c, i) => new { isActive = c.isActiveAndEnabled, idx = i }) .Where(x => x.isActive == false) .Select(x => x.idx) .OrderBy(x => Random.value); foreach (var idx in emptyIdxLst) { var fx = Instantiate(goCanTrace, goCanTrace.transform.parent); Vector2 startPos = basketPopup.transform.position; fx.transform.position = startPos; fx.SetActive(true); Vector2 endPos = canList[idx].transform.position; float dy = startPos.y - endPos.y, t = 0; Vector2 pivot = new Vector2(endPos.x, startPos.y - dy * 0.2f); DOTween.To(() => t, x => t = x, 1, EventCanAct.ParamsCtrl.CanPopupDuration) .OnUpdate(() => fx.transform.position = FtMathUtils.CalculateBezierCurve(t, startPos, pivot, endPos)) .OnComplete(() => { Destroy(fx); canList[idx].Init(idx, true); }); await Task.Delay(System.TimeSpan.FromSeconds(EventCanAct.ParamsCtrl.CanPopupInterval)); } // UIManager.UnblockInput(); var model = GContext.container.Resolve(); model.BlockState &= ~EEventCanBlockState.Supply; Debug.Log($"[EventCan] Supply Unblock: {model.BlockState}"); } catch (System.Exception e) { Debug.Log($"[EventCan]{e.Message}\n{e.StackTrace}"); } } private async void PlayAnimationWithDelay(Animation anim, string name, float delay = 0f) { try { await Task.Delay(System.TimeSpan.FromSeconds(delay)); anim.transform.parent.gameObject.SetActive(true); anim.Play(name); } catch (System.Exception e) { Debug.Log($"[EventCan]{e.Message}\n{e.StackTrace}"); } } private async void ShowBasketIcoWithDelay(Vector3 pos, float delay = 0f) { try { goBasketIcon.transform.position = pos; await Task.Delay(System.TimeSpan.FromSeconds(delay)); goBasketIcon.SetActive(false); goBasketIcon.SetActive(true); await Task.Delay(System.TimeSpan.FromSeconds(EventCanAct.ParamsCtrl.BasketShowDuration)); goBasketIcon.SetActive(false); } catch (System.Exception e) { Debug.Log($"[EventCan]{e.Message}\n{e.StackTrace}"); } } private void CreateRewardFlyObjectPool() { _objectPoolService = GContext.container.Resolve(); _objectPoolService.CreatePool(rewardFly, 0, 10); } private void ReleaseRewardFlyObjectPool() { _objectPoolService?.DestroyPool(typeof(RewardFly)); } } public class EventCanTicketUpdate { } public class EventCanInsufficientTicketEvent { }