using System; using UnityEngine; using TMPro; using UnityEngine.UI; using System.Collections.Generic; using GameCore; using cfg; using asap.core; using game; using DG.Tweening; using UniRx; using Unity.Mathematics; using Random = UnityEngine.Random; public class EventPartnerBuildPanel : MonoBehaviour { [SerializeField] private TMP_Text _textTitle, _textScoreSelf, _textScorePartner, _textScoreSelfAdd, _textScorePartnerAdd, _textProgress, _textTicketCount, _textPlayCost, textNameSelf, textNamePartner; [SerializeField] private Button _btnInfo, _btnPlay, btnTicket; [SerializeField] private Image _imageMe, _imagePartner, _bar, _iconTicket, iconButton; [SerializeField] [Tooltip("Last one is the grand prize.")] private List rewards; [SerializeField] private Transform _wheel, wheelShow; [SerializeField] private EventPartnerWheelPiece[] _wheelPieces; [SerializeField] private EventPartnerMultiplierController _btnMultiplier; [SerializeField] private GameObject turntableGo, iconTicketGo, finishedGo, fxFinishGo, fxTextGlowMe, fxTextGlowPartner, targetContentGo, maskGo; [SerializeField] private Animation _animationMe, _animationPartner, animationLight, animationPointer; [SerializeField] private Animator animatorBtnPlay, animatorBtnMultiplier; [SerializeField] private EventPartnerTips tips; private Tables _tables; private EventPartnerData _data; private IUserService _userService; // private EventPartnerData.Component _component; private PlayerItemData _playerItemData; private IEventAggregator _eventAggregator; private EventPartnerAct.Context _context; private EEventPartnerBuildPanelState _state; private IDisposable _targetUpdateLoopSubscription; private CompositeDisposable _disposables; private int _currentComponentIdx; private void Awake() { _tables = GContext.container.Resolve(); _data = GContext.container.Resolve(); // Debug.Log($"[EventPartner] Data in Build panel: {_data.GetHashCode()}"); _userService = GContext.container.Resolve(); _playerItemData = GContext.container.Resolve(); _btnInfo.onClick.AddListener(() => _ = UIManager.Instance.ShowUI(UITypes.EventPartnerInfoPopupPanel)); btnTicket.onClick.AddListener(() => tips.ShowBuildTip()); _btnPlay.onClick.AddListener(OnClickPlay); } #if UNITY_EDITOR private void Update() { if (Input.GetKeyDown(KeyCode.C)) { _debugFlag++; _debugFlag %= 9; } if (Input.GetKeyDown(KeyCode.R)) { Debug.Log("Data reset."); _data.ResetData(); } } #endif private void OnDestroy() { _targetUpdateLoopSubscription?.Dispose(); _targetUpdateLoopSubscription = null; } public async void Init() { try { _context = EventPartnerAct.Ctx; _disposables?.Dispose(); _disposables = new CompositeDisposable(); _currentComponentIdx = _context.CurrentComponentIdx; Debug.Log($"[EventPartner] _component hash: {_data.Components[_currentComponentIdx].GetHashCode()}"); _eventAggregator = _context.EventAggregator; // Debug.Log("Init:"); // Debug.Log(_eventAggregator.GetHashCode()); InitByState(_data.Components[_currentComponentIdx].IsBuilt); _state = EEventPartnerBuildPanelState.Standby; InitTitle(); InitTarget(_data.Components[_currentComponentIdx].ScoreDisplay); var iconTicket = _tables.TbItem[_tables.TbEventPartnerMain[_data.RedirectId].WheelTicket] .Icon; InitWheel(iconTicket); // await UpdateTarget(); _ = GContext.container.Resolve().SetImageSprite(_iconTicket, iconTicket); int cost = _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].SpinRequire * _btnMultiplier.Multiplier; _textTicketCount.color = _data.TicketCount < cost ? Color.red : Color.white; _textTicketCount.text = _data.TicketCount.ToString(); _targetUpdateLoopSubscription?.Dispose(); _targetUpdateLoopSubscription = null; _targetUpdateLoopSubscription = GContext.OnEvent().Subscribe(e => _ = UpdateTarget()); _eventAggregator.GetEvent().Subscribe(e => _ = HandlePartnerAddScore()).AddTo(_disposables); _eventAggregator.GetEvent().Subscribe(OnMultiplierChange).AddTo(_disposables); GContext.OnEvent().Subscribe(_ => UpdateTicketCount()).AddTo(_disposables); // _eventAggregator.Publish(new EventPartnerMultiplierChange()); await InitPartnerAddScore(); } catch (Exception e) { Debug.LogError(e); } } private void InitByState(bool isBuilt) { turntableGo.SetActive(!isBuilt); iconTicketGo.SetActive(!isBuilt); finishedGo.SetActive(isBuilt); fxFinishGo.SetActive(isBuilt); } private void InitTitle() { string nameSelf = _userService.DisplayName; string namePartner = _data.Components[_currentComponentIdx].PartnerDisplayName; textNameSelf.text = nameSelf; textNamePartner.text = namePartner; _textTitle.text = nameSelf + "&" + namePartner; // Debug.Log($"[EventPartner]BuildPanel: Set icon self: {_userService.AvatarUrl}"); GContext.container.Resolve().SetHeadImage(_imageMe, _userService.AvatarUrl); var partnerIconUrl = _data.Components[_currentComponentIdx].IsPartnerRobot ? _tables.TbRobot[_data.Components[_currentComponentIdx].BotIndex].Avatar : _data.Components[_currentComponentIdx].PartnerAvatarUrl; // Debug.Log($"[EventPartner]BuildPanel: Set icon partner: {partnerIconUrl} Robot: {_component.IsPartnerRobot}"); GContext.container.Resolve().SetHeadImage(_imagePartner, partnerIconUrl); // if (_component.IsPartnerRobot) // Debug.Log($"[EventPartner]{_component.PartnerDisplayName} robot avatar url: {_tables.TbRobot[_component.BotIndex].Avatar}"); // else // Debug.Log($"[EventPartner]{_component.PartnerDisplayName} avatar url: {_component.PartnerAvatarUrl}"); _textScoreSelf.text = _data.Components[_currentComponentIdx].ScoreSelfDisplay.ToString(); _textScorePartner.text = _data.Components[_currentComponentIdx].ScorePartnerDisplay.ToString(); _textScoreSelfAdd.gameObject.SetActive(true); _textScorePartnerAdd.gameObject.SetActive(true); _textScoreSelfAdd.transform.localScale = Vector3.zero; _textScorePartnerAdd.transform.localScale = Vector3.zero; } private void SetRewardItem(RewardItemNew item, int dropId = -1, int scoreTarget = -1, bool isReceived = false) { item.SetReceived(isReceived); if (dropId == -1) return; var rewardList = _playerItemData.GetItemDataByDropId(dropId); if (rewardList.Count > 1) //big reward { // item.SetIcon(_tables.TbEventPartnerMain[_component.RedirectID].RewardIcon); // item.text_num.gameObject.SetActive(true); } else //small reward { item.SetData(rewardList[0].id, ((int)rewardList[0].count).ToString()); item.text_num.gameObject.SetActive(true); item.text_num.text = ConvertTools.GetNumberString((int)rewardList[0].count); } // item.text_num.gameObject.SetActive(false); item.btn_click.onClick.RemoveAllListeners(); item.btn_click.onClick.AddListener(async () => { var panel = await UIManager.Instance.ShowUI(UITypes.EventPartnerTip); if (panel == null) return; int progress = _data.Components[_currentComponentIdx].GetProgressIdx(_data.Components[_currentComponentIdx].Score); if (progress >= 5) progress = 4; panel.GetComponent().Init(rewardList, _data.Components[_currentComponentIdx].Score, scoreTarget, item.btn_click.gameObject.transform); }); // item.transform.Find("text_num").gameObject.SetActive(false); } private readonly float[] _targetPositions = { 0, 0, -193, -386, -386, -386 }; private readonly int[,] _rewardVisibilityCheckList = { { 0, 1 }, { 0, 1 }, { 1, 2 }, { 2, 3 }, { 2, 3 }, { 2, 3 } }; private void InitTarget(int score) { int progress = _data.Components[_currentComponentIdx].GetProgressIdx(score); var rewardDrops = _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].StageReward; var scoreStage = _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].StagePoint; _bar.fillAmount = _data.Components[_currentComponentIdx].GetProgress(score); for (int i = 0; i < rewards.Count; i++) { var item = rewards[i]; SetRewardItem(item, rewardDrops[i], scoreStage[i], _data.Components[_currentComponentIdx].LastProgressReceived > i); item.gameObject.SetActive(i == rewards.Count - 1); } for (int i = 0; i < 2; i++) rewards[_rewardVisibilityCheckList[progress, i]].gameObject.SetActive(true); // SetRewardItem(rewards[^1].transform.Find("reward").GetComponent(), rewardDrops[4], scoreStage[4],progress >= 5); if (progress > 5) progress = 5; _textProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", $"{progress}/{rewardDrops.Count}"); var pos = targetContentGo.GetComponent().anchoredPosition; pos.y = _targetPositions[progress]; targetContentGo.GetComponent().anchoredPosition = pos; _scoreDisplayLocal = _data.Components[_currentComponentIdx].ScoreDisplay; } private void InitWheel(string iconTicket) { var _component = _data.Components[_currentComponentIdx]; var eventPartnerMain = _tables.TbEventPartnerMain[_component.RedirectID]; // Debug.Log("Before giving:"); // Debug.Log(_eventAggregator.GetHashCode()); _btnMultiplier.Init(_data.RedirectId, _eventAggregator); for (int i = 0; i < _wheelPieces.Length; i++) _wheelPieces[i].Init(eventPartnerMain.SpinBg[i], eventPartnerMain.SpinPoint[i] * _btnMultiplier.Multiplier, _context); _textPlayCost.text = (eventPartnerMain.SpinRequire * _btnMultiplier.Multiplier).ToString(); _wheel.rotation = Quaternion.AngleAxis(_data.LastWheelRotation, Vector3.forward); wheelShow.rotation = Quaternion.AngleAxis(_data.LastWheelRotation, Vector3.forward); spinWeightList = new List(eventPartnerMain.SpinWeight); for (int i = spinWeightList.Count - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { spinWeightList[i] += spinWeightList[j]; } } spinPointList = eventPartnerMain.SpinPoint; // Debug.Log($"{System.Threading.Thread.CurrentThread.ManagedThreadId}: InitWheel"); // _btnPlay.onClick.AddListener(OnClickPlay); animatorBtnPlay.Play("Normal"); animatorBtnMultiplier.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; _ = GContext.container.Resolve().SetImageSprite(iconButton, iconTicket); } private int _EvComponentId, _EvMultiplier, _EvPoints, _evItemCount, _evAvailableTicket; private string _evTeammateId, _evRobotId; private async void OnClickPlay() { maskGo.SetActive(true); // Debug.Log($"{System.Threading.Thread.CurrentThread.ManagedThreadId}: OnClickPlay"); if (_state != EEventPartnerBuildPanelState.Standby) { maskGo.SetActive(false); return; } _state = EEventPartnerBuildPanelState.Playing; _btnPlay.enabled = false; _btnMultiplier.ToggleMultiplierButtonFunction(false); var lastCost = await SpinWheel(); switch (lastCost) { // Debug.Log($"Spin res: {canPlay}."); case -1: // Debug.Log("Insufficient fund."); // ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_88")); tips.ShowBuildBtnTip(); _btnPlay.enabled = true; _btnMultiplier.ToggleMultiplierButtonFunction(true); animatorBtnPlay.Play("Normal"); animatorBtnMultiplier.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; maskGo.SetActive(false); return; case -2: _btnPlay.enabled = true; _btnMultiplier.ToggleMultiplierButtonFunction(true); animatorBtnPlay.Play("Normal"); animatorBtnMultiplier.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; maskGo.SetActive(false); return; } _EvMultiplier = _btnMultiplier.Multiplier; _evItemCount = lastCost; _evAvailableTicket = _data.TicketCount; if (lastCost > _data.TicketCount) { _btnMultiplier.SwitchToNextMax(); OnMultiplierChange(new EventPartnerMultiplierChange()); } var newCost = _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].SpinRequire * _btnMultiplier.Multiplier; _textTicketCount.color = _data.TicketCount < newCost ? Color.red : Color.white; // var doesGiveRewards = TryGiveRewards() == ERewardDistributeState.Given; // if (doesGiveRewards) // _component.ResetBotNextScoreTime(); await UpdateTitle(); if (_data.Components[_currentComponentIdx].GetProgressIdx(_data.Components[_currentComponentIdx].Score) <= _data.Components[_currentComponentIdx].GetProgressIdx(_data.Components[_currentComponentIdx].ScoreDisplay)) _context.PlayAddScoreFx(_data.Components[_currentComponentIdx].ComponentIndex); // Debug.Log($"SDL: {_component.ScoreDisplay}"); _scoreDisplayLocal = _data.Components[_currentComponentIdx].ScoreDisplay; await UpdateTarget(); GContext.container.Resolve().SaveTransitionData(_data.EventId, _data.TicketCount); // Debug.Log("Update Target Finished."); _data.Components[_currentComponentIdx].SyncDisplayScore(); _data.SavePlayerPreferenceData(); // await HandlePartnerAddScore(); _EvComponentId = _data.Components[_currentComponentIdx].ComponentId; if (_data.Components[_currentComponentIdx].IsPartnerRobot) { _evTeammateId = ""; _evRobotId = EventPartnerBot.Id2Idx(_data.Components[_currentComponentIdx].PartnerId).ToString(); } else { _evRobotId = ""; _evTeammateId = _data.Components[_currentComponentIdx].PartnerId; } #region EventTracking // Debug.Log($"_______________________________________________________________________________"); // Debug.Log($"component_id: {_EvComponentId}"); // Debug.Log($"teammate_id: {_evTeammateId}"); // Debug.Log($"robot_id: {_evRobotId}"); // Debug.Log($"multiple: {_EvMultiplier}"); // Debug.Log($"item_count: {_evItemCount}"); // Debug.Log($"available_ticket: {_evAvailableTicket}"); // Debug.Log($"points: {_EvPoints}"); // Debug.Log($"_______________________________________________________________________________"); #if AGG using (var e = GEvent.GameEvent("event_partners")) { e.AddContent("component_id", _EvComponentId) .AddContent("teammate_id", _evTeammateId) .AddContent("robot_id", _evRobotId) .AddContent("multiple", _EvMultiplier) .AddContent("item_count", _evItemCount) .AddContent("available_ticket", _evAvailableTicket) .AddContent("points", _EvPoints); } #endif #endregion maskGo.SetActive(false); } private async System.Threading.Tasks.Task InitPartnerAddScore() { maskGo.SetActive(true); // Debug.Log($"Handle Partner Add Score Detected."); bool needAddSelf = _data.Components[_currentComponentIdx].ScoreSelfDisplay < _data.Components[_currentComponentIdx].ScoreSelf; bool needAddPartner = _data.Components[_currentComponentIdx].ScorePartnerDisplay < _data.Components[_currentComponentIdx].ScorePartner; if (_state != EEventPartnerBuildPanelState.Standby || (!needAddSelf && !needAddPartner)) { // Debug.Log( $"Stash. {_state != EEventPartnerBuildPanelState.Standby} {_component.ScorePartnerDisplay >= _component.ScorePartner}") maskGo.SetActive(false); return; } // Debug.Log($"Pass."); _state = EEventPartnerBuildPanelState.Playing; _btnPlay.enabled = false; _btnMultiplier.ToggleMultiplierButtonFunction(false); animatorBtnMultiplier.Play("Pressed"); animatorBtnPlay.Play("Pressed"); if (!needAddSelf) _EvStageTrigger = 2; else { int selfAddOnly = _data.Components[_currentComponentIdx].ScoreSelf + _data.Components[_currentComponentIdx].ScorePartnerDisplay; _EvStageTrigger = _data.Components[_currentComponentIdx].GetProgressIdx(selfAddOnly) > _data.Components[_currentComponentIdx].LastProgressReceived ? 1 : 2; } TryGiveRewards(); // if (rewardRes != ERewardDistributeState.Given) // { // Debug.Log($"No reward given: {rewardRes}"); // // maskGo.SetActive(false); // // return; // } await UpdateTitle(); if (_data.Components[_currentComponentIdx].GetProgressIdx(_data.Components[_currentComponentIdx].Score) <= _data.Components[_currentComponentIdx].GetProgressIdx(_data.Components[_currentComponentIdx].ScoreDisplay)) _context.PlayAddScoreFx(_data.Components[_currentComponentIdx].ComponentIndex); // Debug.Log($"SDL: {_component.ScoreDisplay}"); _scoreDisplayLocal = _data.Components[_currentComponentIdx].ScoreDisplay; await UpdateTarget(); _data.Components[_currentComponentIdx].SyncDisplayScore(); _data.SavePlayerPreferenceData(); _btnPlay.enabled = true; _btnMultiplier.ToggleMultiplierButtonFunction(true); animatorBtnMultiplier.Play("Normal"); animatorBtnPlay.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; maskGo.SetActive(false); } public async System.Threading.Tasks.Task HandlePartnerAddScore() { await Awaiters.NextFrame; maskGo.SetActive(true); // Debug.Log($"Handle Partner Add Score Detected."); if (_state != EEventPartnerBuildPanelState.Standby || _data.Components[_currentComponentIdx].ScorePartnerDisplay >= _data.Components[_currentComponentIdx].ScorePartner) { // Debug.Log( $"Stash. {_state != EEventPartnerBuildPanelState.Standby} {_component.ScorePartnerDisplay >= _component.ScorePartner}") maskGo.SetActive(false); return; } // Debug.Log($"Pass."); _state = EEventPartnerBuildPanelState.Playing; _btnPlay.enabled = false; _btnMultiplier.ToggleMultiplierButtonFunction(false); animatorBtnMultiplier.Play("Pressed"); animatorBtnPlay.Play("Pressed"); _EvStageTrigger = 2; TryGiveRewards(); // if (doesGiveRewards) // _component.ResetBotNextScoreTime(); await UpdateTitle(); if (_data.Components[_currentComponentIdx].GetProgressIdx(_data.Components[_currentComponentIdx].Score) <= _data.Components[_currentComponentIdx].GetProgressIdx(_data.Components[_currentComponentIdx].ScoreDisplay)) _context.PlayAddScoreFx(_data.Components[_currentComponentIdx].ComponentIndex); // Debug.Log($"SDL: {_component.ScoreDisplay}"); _scoreDisplayLocal = _data.Components[_currentComponentIdx].ScoreDisplay; await UpdateTarget(); _data.Components[_currentComponentIdx].SyncDisplayScore(); _data.SavePlayerPreferenceData(); _btnPlay.enabled = true; _btnMultiplier.ToggleMultiplierButtonFunction(true); animatorBtnMultiplier.Play("Normal"); animatorBtnPlay.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; maskGo.SetActive(false); } private List spinWeightList, spinPointList; [SerializeField] private float _rotationTime, anticipationRotation, anticipationTime, followThroughRotation, followThroughTime, safeAngle; [SerializeField] private AnimationCurve easeOutCurve; private int _debugFlag = 0; /// /// Spin the wheel. /// /// -1 if insufficient fund, or the cost taken if success. private async System.Threading.Tasks.Task SpinWheel() { // Debug.Log($"Preparing to send build request."); var cost = _btnMultiplier.Multiplier * _tables.TbEventPartnerMain[_data.RedirectId].SpinRequire; var costRes = EventPartnerAct.Ctx.Data.HasEnoughTicket(cost); if (!costRes) { Debug.Log($"Insufficient fund."); return -1; } int r = Random.Range(0, spinWeightList[^1]), idx; for (idx = 0; idx < spinWeightList.Count - 1; idx++) if (r < spinWeightList[idx]) break; #if UNITY_EDITOR if (_debugFlag != 0) idx = _debugFlag - 1; #endif int scoreToAdd = spinPointList[idx] * _btnMultiplier.Multiplier; _EvPoints = scoreToAdd; var newScore = _data.Components[_currentComponentIdx].ScoreSelf + scoreToAdd; newScore = newScore <= _data.Components[_currentComponentIdx].MaxScore ? newScore : _data.Components[_currentComponentIdx].MaxScore; var partnerId = _data.Components[_currentComponentIdx].PartnerId; if (partnerId.EndsWith(EventPartnerBot.RobotIdentifier)) { // Do nothing. } else { var buildRequest = new EventPartnerData.EventBuildBuildRequest { PartnerId = _data.Components[_currentComponentIdx].PartnerId, NewScore = newScore, EventId = _data.EventId }; var buildRes = await GContext.container.Resolve() .EventPartnerRequest(EventPartnerData.BuildUrl, buildRequest); if (buildRes.State != EventPartnerData.EEventBuildBuildState.Success) { Debug.Log($"[EventPartner] BuildRequestFail({buildRes.State}): {buildRes.Message}"); return -2; } } var ticketRes = EventPartnerAct.Ctx.Data.AddTicket(-cost); if (!ticketRes) { Debug.Log($"Insufficient fund."); return -1; } animatorBtnPlay.Play("Pressed"); animatorBtnMultiplier.Play("Pressed"); animationLight.Play("light_loop"); // update local data _data.Components[_currentComponentIdx].AddSelfScore(scoreToAdd); if (partnerId.EndsWith(EventPartnerBot.RobotIdentifier)) { _data.Components[_currentComponentIdx].SyncRobotScore(); } // _data.AddPartnerTicket(-cost); _textTicketCount.text = _data.TicketCount.ToString(); _textTicketCount.color = _data.TicketCount < cost ? Color.red : Color.white; TryGiveRewards(); // Debug.Log($"Raw Score to add: {spinPointList[idx]}."); _EvPointsPlayer = _data.Components[_currentComponentIdx].ScoreSelf; _evPointsTeammate = _data.Components[_currentComponentIdx].ScorePartner; int i = _data.Components[_currentComponentIdx].LastProgressReceived; i = i >= _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].StagePoint.Count ? _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].StagePoint.Count - 1 : i; _EvPointsOverflow = _data.Components[_currentComponentIdx].Score - _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].StagePoint[i]; _EvStageTrigger = 1; if (_data.Components[_currentComponentIdx].Score > _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].StagePoint[i]) _EvPointsPlayer -= _data.Components[_currentComponentIdx].Score - _tables.TbEventPartnerMain[_data.Components[_currentComponentIdx].RedirectID].StagePoint[i]; int wheelCount = spinWeightList.Count; float deg = 360.0f / wheelCount; float targetAngle = Random.Range((wheelCount - idx) * deg + safeAngle, (wheelCount - idx) * deg + deg - safeAngle); _data.RecordWheelRotation(targetAngle); _data.SavePlayerPreferenceData(); float curAngle = _wheel.rotation.eulerAngles.z; float rotationAngle = curAngle - targetAngle; while (rotationAngle >= 360f * 3 + 180) rotationAngle -= 360f; while (rotationAngle < 360f * 2 + 180) rotationAngle += 360f; // rotationAngle += 360; // anticipationTime = anticipationRotation / rotationSpeed; animationPointer.Play("zhizhen_start"); wheelShow.DORotate(Vector3.back * -anticipationRotation, anticipationTime, RotateMode.WorldAxisAdd); await _wheel.DORotate(Vector3.back * -anticipationRotation, anticipationTime, RotateMode.WorldAxisAdd) .AsyncWaitForCompletion(); animationPointer.Play("zhizhen_loop"); wheelShow.DORotate( Vector3.back * (rotationAngle + anticipationRotation + followThroughRotation), _rotationTime, RotateMode.WorldAxisAdd).SetEase(easeOutCurve); await _wheel .DORotate(Vector3.back * (rotationAngle + anticipationRotation + followThroughRotation), _rotationTime, RotateMode.WorldAxisAdd).SetEase(easeOutCurve).AsyncWaitForCompletion(); animationPointer.Play("zhizhen_end"); wheelShow.DORotate(Vector3.back * -followThroughRotation, followThroughTime, RotateMode.WorldAxisAdd); await _wheel.DORotate(Vector3.back * -followThroughRotation, followThroughTime, RotateMode.WorldAxisAdd) .AsyncWaitForCompletion(); animationLight.Play("light_end"); await _wheelPieces[idx].PlayShow(); return cost; } [SerializeField] [Tooltip("Animation duration of score adding in build panel. In seconds.")] private float _animationScoreAddDuration = 1; [SerializeField] private float pointAddDelay = 0f, textScoreDelay = 1f, titleEnding = 0.5f; private async System.Threading.Tasks.Task UpdateTitle() { maskGo.SetActive(true); int score; if (_data.Components[_currentComponentIdx].ScoreDisplay >= _data.Components[_currentComponentIdx].Score) { maskGo.SetActive(false); return; } if (_data.Components[_currentComponentIdx].ScorePartnerDisplay < _data.Components[_currentComponentIdx].ScorePartner) { _textScorePartnerAdd.text = "+" + (_data.Components[_currentComponentIdx].ScorePartner - _data.Components[_currentComponentIdx].ScorePartnerDisplay); await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(pointAddDelay)); _animationPartner.Play("point_add"); await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(textScoreDelay - pointAddDelay)); score = _data.Components[_currentComponentIdx].ScorePartnerDisplay; DOTween.To(() => score, value => score = value, _data.Components[_currentComponentIdx].ScorePartner, _animationScoreAddDuration) .OnUpdate(() => _textScorePartner.text = score.ToString()); } if (_data.Components[_currentComponentIdx].ScoreSelfDisplay < _data.Components[_currentComponentIdx].ScoreSelf) { _textScoreSelfAdd.text = "+" + (_data.Components[_currentComponentIdx].ScoreSelf - _data.Components[_currentComponentIdx].ScoreSelfDisplay); await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(pointAddDelay)); _animationMe.Play("point_add"); await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(textScoreDelay - pointAddDelay)); score = _data.Components[_currentComponentIdx].ScoreSelfDisplay; DOTween.To(() => score, value => score = value, _data.Components[_currentComponentIdx].ScoreSelf, _animationScoreAddDuration) .OnUpdate(() => _textScoreSelf.text = score.ToString()); } await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(titleEnding)); } private int _EvStageId, _EvStagePoint, _EvPointsPlayer, _evPointsTeammate, _EvRewardList, _EvRewardHook, _EvRewardCash, _EvStageTrigger, _EvPointsOverflow; private void TryGiveRewards() { var _component = _data.Components[_currentComponentIdx]; int targetProgress = _component.GetProgressIdx(_component.Score); int len = targetProgress - _component.LastProgressReceived; if (len <= 0) return; var slicedDropList = _tables.TbEventPartnerMain[_component.RedirectID].StageReward.GetRange(_component.LastProgressReceived, len); _component.LastProgressReceived = targetProgress; _playerItemData.AddItemByDropList(slicedDropList, false); _data.ToPlayfabData().Save(); // _data.SaveData(); // var request = new EventPartnerData.EventBuildUpdateProgressRequest // { // SlotId = _component.ComponentIndex, // NewProgress = targetProgress // }; // _component.GetProgress // return ERewardDistributeState.Given; } public enum ERewardDistributeState { Given, NoNeed, Fail } private const float TargetSlideTime = 0.5f; /// /// The auxiliary score for animation usage that starts at old Display Score /// and ends at target actual Score. The component display score is a property /// consists of two parts, and is way too messy to deal with. /// private int _scoreDisplayLocal; private async System.Threading.Tasks.Task UpdateTarget() { var _component = _data.Components[_currentComponentIdx]; maskGo.SetActive(true); float newBarFillAmount; var rewardList = _tables.TbEventPartnerMain[_component.RedirectID].StageReward; var stagePoints = _tables.TbEventPartnerMain[_component.RedirectID].StagePoint; int displayProgress = _component.GetProgressIdx(_scoreDisplayLocal), targetProgress = _component.GetProgressIdx(_component.Score); // Debug.Log($"Start -> Progress: {displayProgress}, ScoreDisplayLocal: {_scoreDisplayLocal}"); //Target reached. End Target update loop. if (_scoreDisplayLocal >= stagePoints[^1] || _component.Score <= _scoreDisplayLocal) { // Debug.Log("Reached Score."); _btnPlay.enabled = true; _btnMultiplier.ToggleMultiplierButtonFunction(true); animatorBtnPlay.Play("Normal"); animatorBtnMultiplier.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; maskGo.SetActive(false); return; } int nextProgressScore = stagePoints[displayProgress]; if (nextProgressScore > _component.Score) //Next progress target is the score, which is below the max score. { // Debug.Log("Reach Target, and no reward get."); newBarFillAmount = _component.GetProgress(_component.Score); await _bar.DOFillAmount(newBarFillAmount, _animationScoreAddDuration) .AsyncWaitForCompletion(); _scoreDisplayLocal = _component.Score; _btnPlay.enabled = true; _btnMultiplier.ToggleMultiplierButtonFunction(true); animatorBtnPlay.Play("Normal"); animatorBtnMultiplier.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; maskGo.SetActive(false); return; } int rewardIdx; //...unless next update is reaching the max score. if (nextProgressScore == _component.Score && _component.Score >= _component.MaxScore) { // Debug.Log("End line reached!"); _targetUpdateLoopSubscription?.Dispose(); _targetUpdateLoopSubscription = null; rewardIdx = 4; _scoreDisplayLocal = nextProgressScore; newBarFillAmount = 1; await _bar.DOFillAmount(newBarFillAmount, _animationScoreAddDuration).AsyncWaitForCompletion(); await PlayRewardShineAnimation(rewardIdx); _textProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", $"{rewardList.Count}/{rewardList.Count}"); await SlideTarget(_component.GetProgressIdx(_component.Score)); _EvComponentId = _component.ComponentId; _EvStageId = targetProgress; _EvStagePoint = nextProgressScore; _EvPointsOverflow = 0; _EvPointsPlayer = _component.ScoreSelf; _evPointsTeammate = _component.ScorePartner; _EvRewardList = rewardList[^1]; if (_component.IsPartnerRobot) { _evTeammateId = ""; _evRobotId = EventPartnerBot.Id2Idx(_component.PartnerId).ToString(); } else { _evRobotId = ""; _evTeammateId = _component.PartnerId; } // Debug.Log($"Progress: {rewardList.Count}, ScoreDisplayLocal: {_scoreDisplayLocal}"); ShowRewardPopupPanel(rewardList, rewardList.Count); //Will not loop back to this method when PopupPanel is closed... Debug.Log($"_______________________________________________________________________________"); Debug.Log($"component_id: {_EvComponentId}"); Debug.Log($"teammate_id: {_evTeammateId}"); Debug.Log($"robot_id: {_evRobotId}"); Debug.Log($"stage_id: {_EvStageId}"); Debug.Log($"stage_points: {_EvStagePoint}"); Debug.Log($"stage_trigger: {_EvStageTrigger}"); Debug.Log($"points_overflow: {_EvPointsOverflow}"); Debug.Log($"points_player: {_EvPointsPlayer}"); Debug.Log($"points_teammate: {_evPointsTeammate}"); Debug.Log($"reward_list: {_EvRewardList}"); Debug.Log($"reward_hook: {_EvRewardHook}"); Debug.Log($"reward_cash: {_EvRewardCash}"); Debug.Log($"_______________________________________________________________________________"); #if AGG using (var e = GEvent.GameEvent("event_partners_reward")) { e.AddContent("component_id", _EvComponentId) .AddContent("teammate_id", _evTeammateId) .AddContent("robot_id", _evRobotId) .AddContent("stage_id", _EvStageId) .AddContent("stage_points", _EvStagePoint) .AddContent("stage_trigger", _EvStageTrigger) .AddContent("points_overflow", _EvPointsOverflow) .AddContent("points_player", _EvPointsPlayer) .AddContent("points_teammate", _evPointsTeammate) .AddContent("reward_list", _EvRewardList) .AddContent("reward_hook", _EvRewardHook) .AddContent("reward_cash", _EvRewardCash); } #endif InitByState(true); _btnPlay.enabled = true; _btnMultiplier.ToggleMultiplierButtonFunction(true); animatorBtnPlay.Play("Normal"); animatorBtnMultiplier.Play("Normal"); _state = EEventPartnerBuildPanelState.Standby; maskGo.SetActive(false); return; } //Next progress is a stage mark point. rewardIdx = (int)math.floor(_bar.fillAmount / 0.2f); _scoreDisplayLocal = nextProgressScore; displayProgress = _component.GetProgressIdx(_scoreDisplayLocal); newBarFillAmount = _component.GetProgress(nextProgressScore); await _bar.DOFillAmount(newBarFillAmount, _animationScoreAddDuration).AsyncWaitForCompletion(); await PlayRewardShineAnimation(rewardIdx); await SlideTarget(_component.GetProgressIdx(nextProgressScore)); // Debug.Log( $"Progress: {displayProgress}, ScoreDisplayLocal: {_scoreDisplayLocal}"); ShowRewardPopupPanel(rewardList, displayProgress); //Will loop back to this method when PopupPanel is closed... _EvComponentId = _component.ComponentId; _EvStageId = targetProgress; _EvStagePoint = nextProgressScore; _EvPointsOverflow = _component.Score - nextProgressScore; _EvPointsPlayer = _component.ScoreSelf; _evPointsTeammate = _component.ScorePartner; if (_EvStageTrigger == 1) _EvPointsPlayer -= _EvPointsOverflow; else _evPointsTeammate -= _EvPointsOverflow; if (displayProgress >= rewardList.Count) { Debug.Log($"Unexpected score add. return"); return; } _EvRewardList = rewardList[displayProgress]; if (_component.IsPartnerRobot) { _evTeammateId = ""; _evRobotId = EventPartnerBot.Id2Idx(_component.PartnerId).ToString(); } else { _evRobotId = ""; _evTeammateId = _component.PartnerId; } Debug.Log($"_______________________________________________________________________________"); Debug.Log($"component_id: {_EvComponentId}"); Debug.Log($"teammate_id: {_evTeammateId}"); Debug.Log($"robot_id: {_evRobotId}"); Debug.Log($"stage_id: {_EvStageId}"); Debug.Log($"stage_points: {_EvStagePoint}"); Debug.Log($"stage_trigger: {_EvStageTrigger}"); Debug.Log($"points_overflow: {_EvPointsOverflow}"); Debug.Log($"points_player: {_EvPointsPlayer}"); Debug.Log($"points_teammate: {_evPointsTeammate}"); Debug.Log($"reward_list: {_EvRewardList}"); Debug.Log($"reward_hook: {_EvRewardHook}"); Debug.Log($"reward_cash: {_EvRewardCash}"); Debug.Log($"_______________________________________________________________________________"); #if AGG using (var e = GEvent.GameEvent("event_partners_reward")) { e.AddContent("component_id", _EvComponentId) .AddContent("teammate_id", _evTeammateId) .AddContent("robot_id", _evRobotId) .AddContent("stage_id", _EvStageId) .AddContent("stage_points", _EvStagePoint) .AddContent("stage_trigger", _EvStageTrigger) .AddContent("points_overflow", _EvPointsOverflow) .AddContent("points_player", _EvPointsPlayer) .AddContent("points_teammate", _evPointsTeammate) .AddContent("reward_list", _EvRewardList) .AddContent("reward_hook", _EvRewardHook) .AddContent("reward_cash", _EvRewardCash); } #endif _textProgress.text = LocalizationMgr.GetFormatTextValue("UI_CampPanel_9", $"{displayProgress}/{rewardList.Count}"); if (_component.IsPartnerRobot) _component.ScheduleBotScoreAction(); // _component.UpdateBotScoreGap(); // Debug.Log("End of method, move on to next loop."); maskGo.SetActive(false); } [Tooltip("弹出奖励面板的延迟,从侧边奖励响应与组件升级动画开始播放开始算起,默认值为-1,其效果为紧接着侧边奖励响应动画结束")] [SerializeField] private float jiandaRewardPanelPopupDelay = -1f; private async System.Threading.Tasks.Task PlayRewardShineAnimation(int rewardIdx) { var _component = _data.Components[_currentComponentIdx]; // Debug.Log($"{System.Threading.Thread.CurrentThread.ManagedThreadId}: Playing reward shine"); Animation ani; float clipLength; int componentGrade; if (rewardIdx == rewards.Count - 1) { ani = rewards[rewardIdx].transform.parent.GetComponent(); ani.Play("campskyscraper_target"); clipLength = ani.GetClip("campskyscraper_target").length; componentGrade = _component.GetProgressIdx(_scoreDisplayLocal); _context.UpgradeComponent(_component.ComponentIndex, componentGrade); await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(jiandaRewardPanelPopupDelay < 0 ? clipLength : jiandaRewardPanelPopupDelay)); rewards[rewardIdx].SetReceived(true); return; } rewards[rewardIdx].SetReceived(true); ani = rewards[rewardIdx].gameObject.GetComponent(); ani.Play("reward_claim"); componentGrade = _component.GetProgressIdx(_scoreDisplayLocal); _context.UpgradeComponent(_component.ComponentIndex, componentGrade); clipLength = ani.GetClip("reward_claim").length; await System.Threading.Tasks.Task.Delay(TimeSpan.FromSeconds(jiandaRewardPanelPopupDelay < 0 ? clipLength : jiandaRewardPanelPopupDelay)); } private async System.Threading.Tasks.Task SlideTarget(int idx) { /* foreach (var reward in rewards) reward.gameObject.SetActive(true); if (idx <= 2) rewards[3].gameObject.SetActive(false); if (idx <= 1) rewards[2].gameObject.SetActive(false); */ rewards[^1].gameObject.SetActive(true); var cap = idx <= 3 ? idx : 3; for (int i = 0; i < rewards.Count - 1; i++) { rewards[i].gameObject.SetActive(i == cap || i == cap - 1); } var rectTrans = targetContentGo.GetComponent(); float delta = _targetPositions[idx] - rectTrans.anchoredPosition.y; if (Mathf.Abs(delta) <= 0.1f) return; float newY = rectTrans.localPosition.y + delta; await rectTrans.DOAnchorPosY(newY, TargetSlideTime).AsyncWaitForCompletion(); } private void ShowRewardPopupPanel(List rewardList, int displayProgress) { var dropList = _tables.TbDrop[rewardList[displayProgress - 1]].DropList; _EvRewardHook = 0; _EvRewardCash = 0; var dropDataList = new List(); for (int i = 0; i < dropList.DropCountList.Count; i++) { var rewardId = dropList.DropIDList[i]; var count = dropList.DropCountList[i]; if (rewardId == 1001) { _EvRewardHook += count; var itemData = new ItemData(rewardId, count); itemData.curCount = (ulong)_playerItemData.GetItemCount(1001) - (ulong)count; dropDataList.Add(itemData); } else if (rewardId == 1002) { count = GContext.container.Resolve().GetExtraCoinMag(count); _EvRewardCash += count; var itemData = new ItemData(rewardId, count); itemData.curCount = (ulong)_playerItemData.GetItemCount(1002) - (ulong)count; dropDataList.Add(itemData); } } GContext.Publish(new ShowData(dropDataList)); GContext.Publish(new ShowData()); } public void SetStateInactive() { _state = EEventPartnerBuildPanelState.Inactive; } private void OnMultiplierChange(EventPartnerMultiplierChange e) { var _component = _data.Components[_currentComponentIdx]; var eventPartnerMain = _tables.TbEventPartnerMain[_component.RedirectID]; for (int i = 0; i < _wheelPieces.Length; i++) _wheelPieces[i].SetScore(eventPartnerMain.SpinPoint[i] * _btnMultiplier.Multiplier); int cost = eventPartnerMain.SpinRequire * _btnMultiplier.Multiplier; _textPlayCost.text = cost.ToString(); } private void OnDisable() { // Debug.Log("Dispose!!!!!!!!!!!!!!"); fxFinishGo.SetActive(false); _disposables?.Dispose(); } #if UNITY_EDITOR private void OnGUI() { var _component = _data.Components[_currentComponentIdx]; if (_component == null) return; GUI.Box(new Rect(20, 20, 200, 20), $"Component Index: {_component.ComponentIndex}"); GUI.Box(new Rect(20, 40, 400, 20), $"DisplayScore: self {_component.ScoreSelfDisplay}, partner {_component.ScorePartnerDisplay}"); GUI.Box(new Rect(20, 60, 400, 20), $"ActualScore: self {_component.ScoreSelf}, partner {_component.ScorePartner}"); GUI.Box(new Rect(20, 80, 400, 20), $"Progress: display {_component.GetProgressIdx(_scoreDisplayLocal)}, target {_component.GetProgressIdx(_component.Score)}"); GUI.Box(new Rect(20, 100, 400, 20), $"Cheat code: {_debugFlag}, score:" + (_debugFlag == 0 ? "None" : $"{spinPointList[_debugFlag - 1]}")); } #endif private enum EEventPartnerBuildPanelState { Playing, Standby, Finished, Inactive, } public void UpdateTicketCount() { var _component = _data.Components[_currentComponentIdx]; int cost = _tables.TbEventPartnerMain[_component.RedirectID].SpinRequire * _btnMultiplier.Multiplier; _textTicketCount.text = _data.TicketCount.ToString(); _textTicketCount.color = _data.TicketCount < cost ? Color.red : Color.white; } } public class EventPartnerPartnerAddScore { }