using asap.core; using cfg; using DG.Tweening; using EnhancedUI.EnhancedScroller; using GameCore; using System; using System.Collections; using System.Collections.Generic; using TMPro; using UniRx; using UnityEngine; using UnityEngine.UI; namespace game { public class EventPotionPanel : BasePanel { public RawImage ScenePotionRawImage; public GameObject TopMouth; public float show_base_waiting_time = 0.5f; public float show_gap_time = 0.2f; public float show_waitfor_spine_shake_time = 0.6f; public string show_spine_shake_anim = "potion_shake_01_2"; public float show_spine_shake_duration_time = 1.433f; public float jump_move_duration_time = 0.6f; public float jump_waitfor_spine_shake_time = 0.6f; public string jump_spine_shake_anim = "potion_shake_01_1"; public float jump_spine_shake_duration_time = 2.333f; public float jumpdown_move_duration_time = 0.6f; public float jumpdown_waitfor_spine_shake_time = 0.6f; public string jumpdown_spine_shake_anim = "potion_shake_01_1"; public float jumpdown_spine_shake_duration_time = 2.333f; public float check_base_waiting_time = 0.8f; public float check_gap_time = 0.2f; public string check_spine_shake1_anim = "potion_shake_02"; public float check_waitfor_spine_shake2_time = 0.2f; public string check_spine_shake2_anim = "potion_shake_03"; public float check_spine_shake2_duration_time = 2.333f; public float dock_base_waiting_time = 0.6f; public float dock_gap_time = 0f; public float dock_move_duration_time = 0.6f; public float dock_scale = 1.8f; public float dock_waitfor_final_time = 0.1f; public float dock_animation_gap_duration_time = 0.5f; public float final_gap_time = 0f; public float final_move_duration_time = 0.5f; public float final_scale = 0.7f; public float final_pour_duration_time = 1.467f; public float final_ui_fx_duration_time = 1f; public float Lock_Time = 1.0f; public float Changing_Fountain_Effect_Waiting_Time = 0.5f; public RectTransform m_DockPoint; public GameObject fx_eventpoison_ui_reward; [NonSerialized] public List operatingPointTransformList = new List(); [NonSerialized] public Vector3 centerPointPosition; [NonSerialized] public Vector3 centerOfTopMouth = new Vector3(float.MinValue, float.MinValue); private EventPotionDataManager m_DataManager; //由于界面刷新是在奖励界面关闭的时候进行的,所以这里需要一个临时变量来存储奖励数据,判断是不是升级奖励 List itemDataList; #region 音效相关 public List m_AudioPouringList = new List(); public void CloseAudioPouring() { foreach (var gameObject in m_AudioPouringList) { gameObject.SetActive(false); } } public void OpenAudioPouring() { foreach (var gameObject in m_AudioPouringList) { gameObject.SetActive(true); } } #endregion #region EventPotionController private EventPotionController m_EventPotionController; public void SetEventPotionController(EventPotionController eventPotionController) { m_EventPotionController = eventPotionController; } #endregion #region 功能锁定相关 public float m_LockScrollViewMaxTime = 2.0f; private float m_LockScrollViewCumulativeTime = 0.0f; private int m_ScrollViewMinimumQuantity = 0; public int ScrollViewMinimumQuantity { get => m_ScrollViewMinimumQuantity; } public bool IsScrollViewLocked { get { return m_LockScrollViewCumulativeTime > 0f; } } public void StartLockScrollView() { m_LockScrollViewCumulativeTime = m_LockScrollViewMaxTime; if (m_LockScrollViewCumulativeTime > 0f) { LockScrollView(); } } public void StopLockScrollView() { m_LockScrollViewCumulativeTime = 0f; } public void LockScrollView() { if (m_PotionScrollViewController == null) return; m_PotionScrollViewController.LockScrollView(); } public void UnlockScrollView() { if (m_PotionScrollViewController == null) return; if (m_DataManager == null || m_DataManager.PotionData == null) return; int processedCount = m_DataManager.PotionData.LevelProcessedList.Count; if (processedCount >= m_ScrollViewMinimumQuantity) { m_PotionScrollViewController.UnlockScrollView(); } else { m_PotionScrollViewController.LockScrollView(); } } private float m_LockClickOperationCumulativeTime = 0f; public bool IsClickOperationLocked { get { return m_LockClickOperationCumulativeTime > 0f || m_IsCheckingColorType; } } public bool IsClickOperationLockedPure { get { return m_LockClickOperationCumulativeTime > 0f; } } public void StartLockClickOperation() { m_LockClickOperationCumulativeTime = Lock_Time; } public void StopLockClickOperation() { m_LockClickOperationCumulativeTime = 0f; } bool m_IsCheckingColorType = false; public bool IsCheckingColorType { get { return m_IsCheckingColorType; } set { m_IsCheckingColorType = value; } } private void UpdateLockAction(float deltaTime) { if (m_LockScrollViewCumulativeTime > 0f) { m_LockScrollViewCumulativeTime -= deltaTime; if (m_LockScrollViewCumulativeTime > 0f) { LockScrollView(); } } if (m_LockScrollViewCumulativeTime <= 0f) { m_LockScrollViewCumulativeTime = 0f; if (!m_IsCheckingColorType) { UnlockScrollView(); } } if (m_LockClickOperationCumulativeTime > 0f) { m_LockClickOperationCumulativeTime -= deltaTime; } if (m_LockClickOperationCumulativeTime < 0f) { m_LockClickOperationCumulativeTime = 0f; } } #endregion #region 喷泉相关 //public bool IsFountainChanged() //{ // EventPotionStage stage = m_DataManager.GetEventPotionStage(0); // int fountainLevel = stage.FountainLevel; // return false; //} public void ChangeFountain() { EventPotionStage preLevel = m_DataManager.GetEventPotionStage(m_DataManager.PotionData.PreLevelID); EventPotionStage curLevel = m_DataManager.GetCurrentPotionLevel(); if (preLevel.FountainLevel != curLevel.FountainLevel) { m_EventPotionController.ChangeFountain(curLevel.FountainLevel, true, Changing_Fountain_Effect_Waiting_Time); } } public void InitFountain() { EventPotionStage curLevel = m_DataManager.GetCurrentPotionLevel(); m_EventPotionController.ChangeFountain(curLevel.FountainLevel, false, 0); } #endregion #region 倒水特效相关 public bool IsLocatedLeftOfCenterPoint(Vector3 point) { if (point.x > centerPointPosition.x) { return false; } return true; } public float fountain_ripple_effect_waiting_time = 0.3f; public List m_FountainRippleEffectList = new List(); public void StopFountainRippleEffect() { foreach (var gameObject in m_FountainRippleEffectList) { gameObject.SetActive(false); } } public IEnumerator StartFountainRippleEffect() { yield return new WaitForSeconds(fountain_ripple_effect_waiting_time); foreach (var gameObject in m_FountainRippleEffectList) { gameObject.SetActive(true); } } #endregion #region 飞行特效相关临时数据 [SerializeField] private List m_TemporaryItemList = new List(); public PotionGridUI GetIdleTemporaryGridUI() { foreach (var item in m_TemporaryItemList) { if (item.IsIdle == true) { return item; } } return null; } public void ClearTemporaryGridUIToIdle() { foreach (var item in m_TemporaryItemList) { item.IsIdle = true; } } public bool IsAllTemporaryIdle() { foreach (var item in m_TemporaryItemList) { if (item.IsIdle == false) { return false; } } return true; } #endregion #region 操作处理 private void CheckForPreLevelOperation() { if (m_DataManager == null || m_DataManager.PotionData == null) return; if (m_DataManager.PotionData.IsOver) { CheckForLevelReward(); } else { CheckForAddNewStepData(); } //StopLockClickOperation(); } private void CheckForAddNewStepData() { PotionItemData operationItemData = m_DataManager.GetOperationItemData(); if (operationItemData == null) return; int count = m_DataManager.PotionData.LevelDisplayData.GridStateList.Count; for (int i = 0; i < count; ++i) { if (m_DataManager.PotionData.LevelDisplayData.GridStateList[i] == EventPotionGridState.GridState_Over) continue; m_DataManager.PotionData.LevelDisplayData.GridStateList[i] = EventPotionGridState.GridState_Empty; } count = operationItemData.ColorTypeList.Count; int validColorNum = operationItemData.GetValidColorTypeNum(); if (validColorNum == count) { // 操作区全部上架 bool flag = true; m_CommitColorTypeList.Clear(); for (int i = 0; i < count; ++i) { EventPotionGridState gridState = operationItemData.GetGridState(i); if (gridState == EventPotionGridState.GridState_Over) continue; int operationColor = operationItemData.GetColorType(i) % 100; int targetColor = m_DataManager.PotionData.LevelTargetData.GetColorType(i); int fromDisplayAreaIndex = operationItemData.FromDisplayAreaIndexList[i]; m_CommitColorTypeList.Add(operationColor); if (operationColor == targetColor) { operationItemData.SetGridState(i, EventPotionGridState.GridState_Ok); if (fromDisplayAreaIndex >= 0 && fromDisplayAreaIndex < count) { m_DataManager.PotionData.LevelDisplayData.SetGridState(fromDisplayAreaIndex, EventPotionGridState.GridState_Over); } } else { flag = false; operationItemData.SetGridState(i, EventPotionGridState.GridState_Wrong); operationItemData.SetColorType(i, operationColor + 100); if (fromDisplayAreaIndex >= 0 && fromDisplayAreaIndex < count) { m_DataManager.PotionData.LevelDisplayData.SetGridState(fromDisplayAreaIndex, EventPotionGridState.GridState_Empty); } } } if (flag) { CheckForLevelReward(); } else { AddNewStepData(false); } } else { // 操作区未全部上架 for (int i = 0; i < count; ++i) { EventPotionGridState gridState = operationItemData.GetGridState(i); if (gridState == EventPotionGridState.GridState_Over) continue; int fromDisplayAreaIndex = operationItemData.FromDisplayAreaIndexList[i]; int operationColor = operationItemData.GetColorType(i); if (operationColor <= 0) { operationItemData.SetGridState(i, EventPotionGridState.GridState_Empty); if (fromDisplayAreaIndex >= 0 && fromDisplayAreaIndex < count) { m_DataManager.PotionData.LevelDisplayData.SetGridState(fromDisplayAreaIndex, EventPotionGridState.GridState_Empty); } continue; } if (operationColor > 100) { operationItemData.SetColorType(i, operationColor % 100); } operationItemData.SetGridState(i, EventPotionGridState.GridState_Occupied); if (fromDisplayAreaIndex >= 0 && fromDisplayAreaIndex < count) { m_DataManager.PotionData.LevelDisplayData.SetGridState(fromDisplayAreaIndex, EventPotionGridState.GridState_Occupied); } } } } private async void CheckForLevelReward() { m_IsCheckingColorType = true; StartLockScrollView(); // 未领取奖励,则执行领取奖励操作 int levelCount = m_DataManager.GetPreLevelCountInCurRound(); if (m_DataManager.PotionData.LevelIndex == levelCount - 1) { EventPotionStage lastLevel = m_DataManager.GetLastStageInCurRound(); var rewardList = GContext.container.Resolve()?.AddItemByDrop(lastLevel.Reward, false); if (rewardList == null || rewardList.Count < 1) return; var panelObj = await UIManager.Instance.ShowUI(UITypes.EventPotionRewardPopupPanel); if (panelObj == null) return; var rewardPopupPanel = panelObj.GetComponent(); rewardPopupPanel.Init(rewardList); m_DataManager.GetNextPotionLevel(); } else { // 展示奖励界面 EventPotionStage level = m_DataManager.GetCurrentPotionLevel(); itemDataList = GContext.container.Resolve().AddItemByDrop(level.Reward, true, RewardType.NormalOne); GContext.Publish(new ShowData()); m_DataManager.GetNextPotionLevel(); } StopLockClickOperation(); } private async void OnFinalOperationComplete() { AddDropStatisticalData(true); int levelCount = m_DataManager.GetLevelCountInCurRound(); if (m_DataManager.PotionData.LevelIndex == levelCount - 1) { EventPotionStage lastLevel = m_DataManager.GetLastStageInCurRound(); var rewardList = GContext.container.Resolve()?.AddItemByDrop(lastLevel.Reward, false); if (rewardList == null || rewardList.Count < 1) return; var panelObj = await UIManager.Instance.ShowUI(UITypes.EventPotionRewardPopupPanel); if (panelObj == null) return; var rewardPopupPanel = panelObj.GetComponent(); rewardPopupPanel.Init(rewardList); m_DataManager.GetNextPotionLevel(); } else { // 展示奖励界面 EventPotionStage level = m_DataManager.GetCurrentPotionLevel(); itemDataList = GContext.container.Resolve().AddItemByDrop(level.Reward, true, RewardType.NormalOne); GContext.Publish(new ShowData()); m_DataManager.GetNextPotionLevel(); } StopLockClickOperation(); } private void GoToNextLevel() { m_DataManager.InitScrollerDataList(); var position = 0f; m_PotionScrollViewController.ReloadData(); m_PotionWallScrollViewController.ReloadData(); m_PotionScrollViewController.ScrollPosition = position; m_PotionWallScrollViewController.ScrollPosition = position; int index = m_DataManager.WallBeforeCount + m_DataManager.PotionData.LevelProcessedList.Count; m_PotionScrollViewController.JumpToDataIndex(index); // 重置下方Item展示区域 ResetItemsDisplayArea(); UpdateReward(); UpdateProgress(); // 切换喷泉 ChangeFountain(); } private void AddNewStepData(bool isResetUI = true) { m_IsCheckingColorType = true; StartLockScrollView(); foreach (var item in m_DataManager.PotionData.LevelProcessedList) { item.isOver = true; item.DataType = EventPotionDataType.Data_Item; item.ResetFromDisplayAreaIndexList(-1); } PotionItemData newPotionItemData = new PotionItemData(); newPotionItemData.name = "AddNewStepData_" + DateTime.Now.Ticks; newPotionItemData.index = m_DataManager.PotionData.LevelProcessedList.Count; newPotionItemData.Clear(); newPotionItemData.isOver = false; newPotionItemData.DataType = EventPotionDataType.Data_ItemAndOperation; int count = m_DataManager.PotionData.LevelProcessedList.Count; PotionItemData lastProcessedItemData = m_DataManager.PotionData.LevelProcessedList[count - 1]; EventPotionStage potionLevel = m_DataManager.GetCurrentPotionLevel(); count = potionLevel.ResourceList.Count; for (int i = 0; i < count; i++) { int preColorType = lastProcessedItemData.ColorTypeList[i]; int preFromDisplayAreaIndex = lastProcessedItemData.FromDisplayAreaIndexList[i]; if (preColorType > 0 && preColorType < 100) { newPotionItemData.ColorTypeList.Add(preColorType); newPotionItemData.ShelfTypeList.Add(EventPotionShelfType.Shelf_Success); newPotionItemData.GridStateList.Add(EventPotionGridState.GridState_Over); newPotionItemData.FromDisplayAreaIndexList.Add(preFromDisplayAreaIndex); } else { newPotionItemData.ColorTypeList.Add(-1); newPotionItemData.ShelfTypeList.Add(EventPotionShelfType.Shelf_Default); newPotionItemData.GridStateList.Add(EventPotionGridState.GridState_Empty); newPotionItemData.FromDisplayAreaIndexList.Add(-1); } } m_DataManager.PotionData.LevelProcessedList.Add(newPotionItemData); m_DataManager.InitScrollerDataList(); AddDropStatisticalData(false); if (isResetUI) { var position = m_PotionScrollViewController.ScrollPosition; m_PotionScrollViewController.ReloadData(); m_PotionWallScrollViewController.ReloadData(); m_PotionScrollViewController.ScrollPosition = position; m_PotionWallScrollViewController.ScrollPosition = position; count = m_DataManager.WallBeforeCount + m_DataManager.PotionData.LevelProcessedList.Count; m_PotionScrollViewController.JumpToDataIndex(count, 0, 0f, true, EnhancedScroller.TweenType.linear, 0.3f); // 重置下方Item展示区域 ResetItemsDisplayArea(); } } private void OnGridItemBtnClickCallback(PotionGridUI gridUI) { if (IsClickOperationLocked) return; StartLockClickOperation(); StartLockScrollView(); int index = m_DataManager.WallBeforeCount + m_DataManager.PotionData.LevelProcessedList.Count; m_PotionScrollViewController.JumpToDataIndex(index, 0, 0, true, EnhancedScroller.TweenType.immediate, 0, () => { this.StartCoroutine(OnScrollViewJumpCompleteCallback(gridUI)); }); } public IEnumerator OnScrollViewJumpCompleteCallback(PotionGridUI gridUI) { yield return null; PotionItem operationItem = GetOperationItem(); if (operationItem == null) yield break; // 找到停靠点 PotionGridUI target = FindFirstEmptyPotionGridUI(); if (target == null) yield break; target.Copy(gridUI, false, false); target.HideUpperUI(); // 找到用于显示飞行轨迹的临时PotionGridUI并初始化和播放初始动画 PotionGridUI temporary = GetIdleTemporaryGridUI(); if (temporary == null) yield break; temporary.SetTemporaryData(gridUI); // 消耗代币 if (!ConsumeTokens(EventPotionConfig.Token_Consume_Num)) { temporary.IsIdle = true; temporary.gameObject.SetActive(false); yield break; } // 更新目标数据 target.SetColorType(gridUI.GetColorType()); target.SetGridState(EventPotionGridState.GridState_Occupied); target.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, true); target.SetFromGridUI(gridUI); // 隐藏当前瓶子 gridUI.SetGridState(EventPotionGridState.GridState_Occupied); gridUI.gameObject.SetActive(false); temporary.PlaySpinAnimation(0, EventPotionConfig.spine_potion_fly, true); temporary.PlayAnimation(EventPotionConfig.anim_gild_jump); Vector3 targetPosition = target.transform.position; temporary.DOKill(); //temporary.transform.DOMove(targetPosition, jump_move_duration_time).SetEase(Ease.OutQuad); //this.StartCoroutine(HandleJumpStep(1, gridUI, target, temporary)); CheckFirstWrongGuide(target); // 锁定操作 //int validNum = operationItem.GetVaildNum(); int targetIndex = target.Index; int lastIndex = operationItem.GetLastValidIndex(); if (targetIndex == lastIndex) { temporary.transform.DOMove(targetPosition, jump_move_duration_time).SetEase(Ease.OutQuad).OnComplete(() => { target.ShowIcon(); target.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, true); temporary.IsIdle = true; temporary.gameObject.SetActive(false); //CheckFirstWrongGuide(target); //UnlockScrollView(); }); } else { temporary.transform.DOMove(targetPosition, jump_move_duration_time).SetEase(Ease.OutQuad); this.StartCoroutine(HandleJumpStep(1, gridUI, target, temporary)); } if (m_DataManager != null) { m_DataManager.SyncData(); } } public IEnumerator HandleJumpStep(int type, PotionGridUI src, PotionGridUI target, PotionGridUI temporary) { yield return new WaitForSeconds(jump_waitfor_spine_shake_time); target.ShowIcon(); target.PlaySpinAnimation(0, jump_spine_shake_anim, true); temporary.IsIdle = true; temporary.gameObject.SetActive(false); yield return new WaitForSeconds(jump_spine_shake_duration_time); target.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, true); //CheckFirstWrongGuide(target); //UnlockScrollView(); } public void CheckForUpdate() { if (m_IsCheckingColorType == true) return; // 检查操作区是否全部上架 PotionItem operationItem = GetOperationItem(); if (operationItem == null) return; bool isOperationAllOnline = operationItem.CheckOperationAreaIsAllOnline(); if (!isOperationAllOnline) { //Debug.LogWarning("----- CheckForUpdate 操作区没有完全上架"); return; } // 检查展示区是否全部上架 bool isAllDisplayAreaOnline = CheckAllDisplayAreaIsOnline(); if (!isAllDisplayAreaOnline) { //Debug.LogWarning("----- CheckForUpdate 显示区没有完全上架"); return; } // 检查临时区是否完全恢复为Idle状态 bool isAllTemporaryIdle = IsAllTemporaryIdle(); if (!isAllTemporaryIdle) { //Debug.LogWarning("----- CheckForUpdate 临时区没有完全恢复为Idle状态"); return; } //Debug.LogWarning("===== Check 所有瓶子都移至上方格子"); StartLockScrollView(); if (CheckForWrongAsPreviously(operationItem) == true) return; m_IsCheckingColorType = true; m_DataManager.PotionData.CorrectNum = 0; if (operationItem.CheckGridListIsOk(PrepareGoToNextLevel, PrepareAddNewStepData)) { m_DataManager.PotionData.IsOver = true; //Debug.LogWarning("===== Check 所有瓶子颜色都对齐了"); } else { m_DataManager.PotionData.IsOver = false; //Debug.LogWarning("===== Check 瓶子颜色没有完全对齐"); } operationItem.Reset_FromPotionGridUI_GridState(); //m_DataManager.ResetDisplayAreaGridState(EventPotionGridState.GridState_Empty); } public PotionItem GetOperationItem() { if (m_PotionScrollViewController == null) return null; return m_PotionScrollViewController.GetOperationPotionItem(); } private List m_CommitColorTypeList = new List(); public List CommitColorTypeList { get { return m_CommitColorTypeList; } } public void AddDropStatisticalData(bool isAllOk) { if (m_DataManager == null || m_DataManager.PotionData == null) return; PotionItemData operationItemData = m_DataManager.GetOperationItemData(); if (operationItemData == null) { return; } string color_submit = Newtonsoft.Json.JsonConvert.SerializeObject(m_CommitColorTypeList); int combine_id = m_DataManager.PotionData.Round * 100 + m_DataManager.PotionData.LevelIndex + 1; var potionLevel = m_DataManager.GetCurrentPotionLevel(); if (potionLevel == null) return; int is_correct = isAllOk ? 1 : 0; m_DataManager.PotionData.SubmitNum++; #if AGG using (var e = GEvent.GameEvent("event_color_potion")) { e.AddContent("round", m_DataManager.PotionData.StageID) .AddContent("stage", m_DataManager.PotionData.LevelIndex) .AddContent("color_count", m_DataManager.PotionData.LevelDisplayData.ColorTypeList.Count) .AddContent("correct_color", Newtonsoft.Json.JsonConvert.SerializeObject(m_DataManager.PotionData.LevelTargetData.ColorTypeList)) .AddContent("color_show", Newtonsoft.Json.JsonConvert.SerializeObject(m_DataManager.PotionData.LevelDisplayData.ColorTypeList)) .AddContent("color_submit", color_submit) .AddContent("is_correct", is_correct) .AddContent("item_count", m_DataManager.PotionData.ConsumedToken) .AddContent("rule", m_DataManager.PotionData.Rule) .AddContent("submit_count", m_DataManager.PotionData.SubmitNum) .AddContent("drop_list", potionLevel.Reward) .AddContent("combine_id", combine_id); var itemDataList = GContext.container.Resolve()?.GetItemDataByDropId(potionLevel.Reward); if (itemDataList != null) { for (int i = 0; i < itemDataList.Count; i++) { if (itemDataList[i].id == 1001) { e.AddContent("reward_hook", itemDataList[i].count); } //else if (itemDataList[i].id == 1002) //{ // e.AddContent("reward_cash", itemDataList[i].count); //} } } } #endif } public void PrepareGoToNextLevel(int type, PotionGridUI gridUI) { // 进入下一关 this.StartCoroutine(HandleDockStep(gridUI)); } public IEnumerator HandleDockStep(PotionGridUI gridUI) { yield return new WaitForSeconds(dock_base_waiting_time); // 找到停靠点 Vector3 dockPoint = m_DockPoint.position; var potionItem = gridUI.PotionItem; int count = potionItem.GetVaildNum(); List tmpIndexList = new List(); for (int i = 0; i < count; ++i) { tmpIndexList.Add(i); } m_DataManager.ShuffleList(tmpIndexList, false); List temporaryList = new List(); float scale = dock_scale; float duration = dock_move_duration_time; float gapTime = dock_gap_time; int lastIndex = count - 1; for (int i = 0; i < count; i++) { int tmpIndex = tmpIndexList[i]; PotionGridUI itemGridUI = potionItem.GetGridUI(tmpIndex); itemGridUI.HideUpperUI(); PotionGridUI temporary = GetIdleTemporaryGridUI(); //if (temporary == null) return; temporary.SetTemporaryData(itemGridUI); temporary.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, true); temporaryList.Add(temporary); Vector3 dockPosition = new Vector3(itemGridUI.transform.position.x, dockPoint.y, dockPoint.z); temporary.transform.DOKill(); int index = tmpIndex; bool isLast = i == lastIndex; temporary.OpenAudioFly(); temporary.transform.DOMove(dockPosition, duration).SetEase(Ease.OutQuad).OnComplete(() => { temporary.CloseAudioFly(); this.StartCoroutine(HandleFinalStepByGridUI(temporaryList, temporary, index, count, isLast)); }); temporary.transform.DOScale(scale, duration).SetEase(Ease.Linear); if (gapTime > 0 && !isLast) { yield return new WaitForSeconds(gapTime); } } } public IEnumerator HandleFinalStep(List temporaryList) { yield return new WaitForSeconds(dock_waitfor_final_time); int count = temporaryList.Count; List finalPositionList = GetFinalPositionList(count); float scale = final_scale; float duration = final_move_duration_time; //float baseDelayTime = final_base_waiting_time; float gapTime = final_gap_time; int lastIndex = count - 1; for (int i = 0; i < count; i++) { PotionGridUI temporary = temporaryList[i]; Vector3 finalPosition = finalPositionList[i]; temporary.transform.DOKill(); if (i == lastIndex) { temporary.transform.DOLocalMove(finalPosition, duration).SetEase(Ease.OutQuad).OnComplete(() => { this.StartCoroutine(HandleFountainStep(temporaryList)); }); } else { temporary.transform.DOLocalMove(finalPosition, duration).SetEase(Ease.OutQuad); } temporary.transform.DOScale(scale, duration).SetEase(Ease.Linear); if (gapTime > 0) { yield return new WaitForSeconds(gapTime); } } } public IEnumerator HandleFountainStep(List temporaryList) { int count = temporaryList.Count; float scale = final_scale; float duration = final_move_duration_time; //float baseDelayTime = final_base_waiting_time; float gapTime = final_gap_time; int lastIndex = count - 1; for (int i = 0; i < count; i++) { PotionGridUI temporary = temporaryList[i]; temporary.PlayAnimation(EventPotionConfig.anim_gild_settlement); if (temporary.transform.position.x < centerPointPosition.x) { temporary.PlaySpinAnimation(0, EventPotionConfig.spine_potion_pour_R, false); temporary.SetPourWaterRight(); } else { temporary.PlaySpinAnimation(0, EventPotionConfig.spine_potion_pour_L, false); temporary.SetPourWaterLeft(); } if (gapTime > 0) { yield return new WaitForSeconds(gapTime); } } yield return new WaitForSeconds(final_pour_duration_time); for (int i = 0; i < count; i++) { PotionGridUI temporary = temporaryList[i]; temporary.IsIdle = true; temporary.gameObject.SetActive(false); } if (fx_eventpoison_ui_reward != null) { fx_eventpoison_ui_reward.SetActive(true); } yield return new WaitForSeconds(final_ui_fx_duration_time); OnFinalOperationComplete(); if (fx_eventpoison_ui_reward != null) { fx_eventpoison_ui_reward.SetActive(false); } yield return new WaitForSeconds(0.2f); StartCoroutine(ResetTemporary()); } public IEnumerator HandleFinalStepByGridUI(List temporaryList, PotionGridUI temporary, int index, int count, bool isLast) { //yield return new WaitForSeconds(dock_waitfor_final_time); temporary.PlayAnimation(EventPotionConfig.anim_gild_gap); yield return new WaitForSeconds(dock_animation_gap_duration_time); List finalPositionList = GetFinalPositionList(count); float scale = final_scale; float duration = final_move_duration_time; float gapTime = final_gap_time; Vector3 finalPosition = finalPositionList[index]; temporary.transform.DOKill(); if (isLast) { temporary.transform.DOLocalMove(finalPosition, duration).SetEase(Ease.OutQuad).OnComplete(() => { this.StartCoroutine(HandleFountainStepByGridUI(temporaryList, temporary, index, count, isLast)); }); } else { temporary.transform.DOLocalMove(finalPosition, duration).SetEase(Ease.OutQuad); } temporary.transform.DOScale(scale, duration).SetEase(Ease.Linear); } public IEnumerator HandleFountainStepByGridUI(List temporaryList, PotionGridUI temporary, int index, int count, bool isLast) { float scale = final_scale; float duration = final_move_duration_time; float gapTime = final_gap_time; //int num = m_Data.ColorTypeList.Count; int num = temporaryList.Count; for (int i = 0; i < num; ++i) { PotionGridUI item = temporaryList[i]; EventPotionGridState gridState = item.GetGridState(); if (gridState == EventPotionGridState.GridState_Over) { continue; } item.PlayAnimation(EventPotionConfig.anim_gild_settlement); if (item.transform.position.x < centerPointPosition.x) { item.PlaySpinAnimation(0, EventPotionConfig.spine_potion_pour_R, false); item.SetPourWaterRight(); } else { item.PlaySpinAnimation(0, EventPotionConfig.spine_potion_pour_L, false); item.SetPourWaterLeft(); } } //temporary.PotionItem. //temporary.PlayAnimation(EventPotionConfig.anim_gild_settlement); OpenAudioPouring(); if (TopMouth != null) { TopMouth.SetActive(true); } //if (temporary.transform.position.x < centerPointPosition.x) //{ // temporary.PlaySpinAnimation(0, EventPotionConfig.spine_potion_pour_R, false); // temporary.SetPourWaterRight(); //} //else //{ // temporary.PlaySpinAnimation(0, EventPotionConfig.spine_potion_pour_L, false); // temporary.SetPourWaterLeft(); //} //if (index == 0) //{ // this.StartCoroutine(StartFountainRippleEffect()); //} this.StartCoroutine(StartFountainRippleEffect()); yield return new WaitForSeconds(final_pour_duration_time); for (int i = 0; i < num; ++i) { PotionGridUI item = temporaryList[i]; EventPotionGridState gridState = item.GetGridState(); if (gridState == EventPotionGridState.GridState_Over) { continue; } item.IsIdle = true; item.gameObject.SetActive(false); } //temporary.IsIdle = true; //temporary.gameObject.SetActive(false); if (TopMouth != null) { TopMouth.SetActive(false); } if (isLast) { CloseAudioPouring(); StopFountainRippleEffect(); if (fx_eventpoison_ui_reward != null) { fx_eventpoison_ui_reward.SetActive(true); } yield return new WaitForSeconds(final_ui_fx_duration_time); OnFinalOperationComplete(); if (fx_eventpoison_ui_reward != null) { fx_eventpoison_ui_reward.SetActive(false); } yield return new WaitForSeconds(0.1f); StartCoroutine(ResetTemporary()); } } public void PrepareAddNewStepData(int type, PotionGridUI gridUI) { // 添加新的数据 AddNewStepData(true); } public IEnumerator HandleShowStep(PotionGridUI gridUI, int index, float delayTime, EventPotionGridState gridState) { yield return new WaitForSeconds(delayTime); // 找到用于显示飞行轨迹的临时PotionGridUI并初始化和播放初始动画 PotionGridUI temporary = GetIdleTemporaryGridUI(); if (temporary != null) { temporary.SetTemporaryData(gridUI); temporary.PlayAnimation(EventPotionConfig.anim_gild_show); temporary.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, true); gridUI.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, true); yield return new WaitForSeconds(show_waitfor_spine_shake_time); temporary.PlaySpinAnimation(0, show_spine_shake_anim, true); yield return new WaitForSeconds(show_spine_shake_duration_time); temporary.IsIdle = true; temporary.gameObject.SetActive(false); gridUI.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, true); gridUI.gameObject.SetActive(true); } } private IEnumerator ResetTemporary() { foreach (var item in m_TemporaryItemList) { Vector3 position = item.transform.localPosition; position.y = -2000; item.gameObject.SetActive(true); item.transform.localPosition = position; item.PlaySpinAnimation(0, EventPotionConfig.spine_potion_idle, false); } yield return new WaitForSeconds(0.2f); foreach (var item in m_TemporaryItemList) { item.gameObject.SetActive(false); } } public PotionGridUI FindFirstEmptyPotionGridUI() { PotionItem potionItem = GetOperationItem(); if (potionItem == null) return null; int count = potionItem.GetVaildNum(); for (int i = 0; i < count; ++i) { var gridUI = potionItem.GetGridUI(i); if (gridUI.GetGridState() == EventPotionGridState.GridState_Empty) return gridUI; } return null; } private LinkedList m_ActionChain = new LinkedList(); private void UpdateActionChain() { float deltaTime = Time.deltaTime; LinkedListNode currentNode = m_ActionChain.First; while (currentNode != null) { LinkedListNode nextNode = currentNode.Next; currentNode.Value.Update(deltaTime); if (currentNode.Value.IsValid() == false) { currentNode.Value.Action(); m_ActionChain.Remove(currentNode); } currentNode = nextNode; } } public void AddAction(PotionAction action) { m_ActionChain.AddLast(action); } #endregion #region 新手引导 public IEnumerator InitGuidance(float waitTime) { yield return new WaitForSeconds(waitTime); m_FirstWrongGridUI = null; GContext.container.Resolve().InspectTriggerGuide("EventPotionPanel", curPanelName: gameObject.name); } PotionGridUI m_FirstWrongGridUI = null; public void CheckFirstWrongGuide(PotionGridUI gridUI) { if (gridUI == null) return; EventPotionGridState gridState = gridUI.GetGridState(); if (gridState == EventPotionGridState.GridState_Over) return; int count = m_DataManager.PotionData.LevelProcessedList.Count; if (count < 0) return; var potionItem = gridUI.PotionItem; if (potionItem == null) return; PotionItemData curData = potionItem.Data; int curIndex = m_DataManager.PotionData.LevelProcessedList.IndexOf(curData); if (curIndex < 1) return; int preIndex = curIndex - 1; PotionItemData preData = m_DataManager.PotionData.LevelProcessedList[preIndex]; if (preData == null) return; int index = gridUI.Index; int curColorType = gridUI.GetColorType(); int preColorType = preData.GetColorType(index); if (preColorType < 100) return; int colorType = preColorType % 100; if (curColorType != colorType) return; //if (curColorType == m_DataManager.PotionData.LevelTargetData.ColorTypeList[index]) return; if (m_DataManager.HasPotionIDSaveKey(EventPotionConfig.key_first_check_wrong)) return; StartLockClickOperation(); StartLockScrollView(); StartCoroutine(ShowFirstWrongGuide(gridUI)); } public IEnumerator ShowFirstWrongGuide(PotionGridUI gridUI) { yield return new WaitForSeconds(jump_move_duration_time); isLockMask = true; mask.gameObject.SetActive(true); PotionFirstWrongGuideTips.SetActive(true); Vector3 position = gridUI.transform.position; position.x = PotionFirstWrongGuideTips.transform.position.x; position.y += 50; PotionFirstWrongGuideTips.transform.position = position; gridUI.FirstWrongGuide(); m_FirstWrongGridUI = gridUI; //StartCoroutine(AutoReleaseUnclockMaskOperation()); yield return new WaitForSeconds(lock_mask_operation_time); isLockMask = false; StopLockClickOperation(); } //public IEnumerator AutoReleaseUnclockMaskOperation() //{ // yield return new WaitForSeconds(lock_mask_operation_time); // isLockMask = false; //} public bool CheckForWrongAsPreviously(PotionItem potionItem) { if (potionItem == null || potionItem.Data == null) return false; int count = m_DataManager.PotionData.LevelProcessedList.Count; if (count < 0) return false; PotionItemData curData = potionItem.Data; int index = m_DataManager.PotionData.LevelProcessedList.IndexOf(curData); if (index < 1) return false; int preIndex = index - 1; PotionItemData preData = m_DataManager.PotionData.LevelProcessedList[preIndex]; if (preData == null) return false; if (m_DataManager.HasPotionIDSaveKey(EventPotionConfig.key_first_check_combination_wrong)) return false; bool flag = true; count = curData.ColorTypeList.Count; for (int i = 0; i < count; ++i) { var curState = curData.GetGridState(i); if (curState == EventPotionGridState.GridState_Over) { continue; } var curColorType = curData.GetColorType(i) % 100; var preColorType = preData.GetColorType(i) % 100; if (curColorType != preColorType) { flag = false; } } if (flag == true) { ToastPanel.Show(LocalizationMgr.GetText("UI_ToastPanel_96")); potionItem.ReturnAllUncertainGridUI(); //if (potionItem.ReturnAllUncertainGridUI()) //{ // m_IsCheckingColorType = false; //} } m_DataManager.SavePotionIDData(EventPotionConfig.key_first_check_combination_wrong, "ok"); return flag; } #endregion #region 生命周期 public void OpenUI() { CloseAudioPouring(); InitEvent(); InitUIData(); // 判断是否存在前一关未完成操作 CheckForPreLevelOperation(); ShowUI(); FishingPotionAct.IsInitPanelComplete = true; } private void ProcessAdaptation() { InitUI(); RectTransform scrollViewRectTransform = m_PotionScrollViewController.transform.GetComponent(); float scrollViewHeight = scrollViewRectTransform.rect.height; float itemHeight = m_PotionScrollViewController.GetCellViewSize(null, 0); int times = (int)Mathf.Ceil(scrollViewHeight / itemHeight); m_ScrollViewMinimumQuantity = times - 1; m_DataManager.InitWalls(times); m_DataManager.InitScrollerDataList(); } protected override void Start() { base.Start(); m_DataManager = GContext.container.Resolve(); ProcessAdaptation(); OpenUI(); UnlockScrollView(); } private void Update() { if (m_PotionScrollViewController != null && m_PotionWallScrollViewController != null) { m_PotionWallScrollViewController.ScrollPosition = m_PotionScrollViewController.ScrollPosition; } CheckForUpdate(); UpdateLockAction(Time.deltaTime); //UpdateActionChain(); } #endregion #region 数据处理 private void InitUIData() { isLockMask = false; m_IsCheckingColorType = false; StopLockClickOperation(); ClearTemporaryGridUIToIdle(); UpdateToken(null); UpdateReward(); UpdateProgress(); } private void UpdateReward() { var level = m_DataManager.GetCurrentPotionLevel(); if (level == null) return; var rewardList = GContext.container.Resolve()?.GetItemDataByDropId(level.Reward); if (rewardList == null || rewardList.Count < 1) return; int count = m_RewardRootList.Count; int num = rewardList.Count; for (int i = 0; i < count; i++) { if (i < num) { m_RewardRootList[i].SetActive(true); m_RewardItemNewList[i].SetData(rewardList[i]); } else { m_RewardRootList[i].SetActive(false); } } } private void UpdateProgress() { if (m_DataManager == null || m_DataManager.PotionData == null) return; // 获取当前轮次等级总数 int levelCount = 0; if (m_DataManager.PotionData.StageID == 1) levelCount = m_DataManager.PotionData.Stage1TotalLevel; else levelCount = m_DataManager.PotionData.Stage2TotalLevel; // 计算坐标相关数据 RectTransform rectTransform = layout_line.GetComponent(); Vector2 tmp = rectTransform.sizeDelta; float totalWidth = layout_line.GetComponent().sizeDelta.x; float gapW = totalWidth / levelCount; float baseX = (-totalWidth / 2) + gapW; float y = img_progress_line.transform.localPosition.y; float z = img_progress_line.transform.localPosition.z; // 增加Image int num = img_progress_line_list.Count; Vector2 size = img_progress_line.GetComponent().sizeDelta; int lineCount = levelCount - 1; for (int i = num; i < lineCount; i++) { GameObject gameObject = new GameObject("line_" + i); gameObject.transform.SetParent(layout_line); Image image = gameObject.AddComponent(); image.sprite = img_progress_line.sprite; gameObject.transform.GetComponent().sizeDelta = size; gameObject.transform.localScale = img_progress_line.transform.localScale; gameObject.transform.localPosition = img_progress_line.transform.localPosition; img_progress_line_list.Add(image); } // 调整间隔坐标 num = img_progress_line_list.Count; for (int i = 0; i < num; i++) { Image image = img_progress_line_list[i]; if (i < lineCount) { image.gameObject.SetActive(true); image.transform.localPosition = new Vector3(baseX + i * gapW, y, z); } else { image.gameObject.SetActive(false); } } // 更新process bar int index = 0; if (m_DataManager.PotionData.IsOver == true) { index = m_DataManager.PotionData.LevelIndex + 1; } else { index = m_DataManager.PotionData.LevelIndex; } bar.fillAmount = ((float)index) / levelCount; text_progress.text = index + "/" + levelCount; } private List GetFinalPositionList(int num) { EventPotionBottle eventPotionBottle = m_DataManager.GetEventPotionBottle(num); int count = eventPotionBottle.BottleLsit.Count; List list = new List(); for (int i = 0; i < count; ++i) { int index = eventPotionBottle.BottleLsit[i]; list.Add(operatingPointTransformList[index]); } return list; //System.Random random = new System.Random(); //return operatingPointTransformList.OrderBy(x => random.Next()).Take(num).ToList(); } public List FindValidDisplayGridUIRefList() { List list = new List(); int count = m_DisplayGridItemList.Count; for (int i = 0; i < count; ++i) { PotionGridUI item = m_DisplayGridItemList[i]; if (item.GetGridState() == EventPotionGridState.GridState_Empty && item.ItemData.GetColorType(item.Index) > EventPotionConfig.PotionItemType_Empty) { list.Add(i); } } return list; } public bool CheckAllDisplayAreaIsOnline() { int count = m_DisplayGridItemList.Count; int validNum = m_DataManager.PotionData.LevelDisplayData.ColorTypeList.Count; for (int i = 0; i < count; ++i) { var gridUI = m_DisplayGridItemList[i]; if (gridUI.IsActive()) return false; if (i < validNum) { if (gridUI.ItemData == null) continue; var gridState = gridUI.GetGridState(); if (gridState != EventPotionGridState.GridState_Occupied && gridState != EventPotionGridState.GridState_Over) { return false; } } } return true; } private float ResetItemsDisplayArea() { m_IsCheckingColorType = false; UnlockScrollView(); // 处理item_group List displayIndexRefList = m_DataManager.GetValidDisplayDataList(); int num = displayIndexRefList.Count; RectTransform itemRectTransform = m_DisplayGridItemList[0].GetComponent(); Vector2 itemAnchorPosition = itemRectTransform.pivot; float itemWidth = itemRectTransform.sizeDelta.x; float totalWidth = num * itemWidth; float baseX = totalWidth / 2; baseX = -baseX + itemWidth * itemAnchorPosition.x; float baseY = itemRectTransform.localPosition.y; float baseZ = itemRectTransform.localPosition.z; int indexForPosition = 0; int indexForTime = 0; int count = m_DisplayGridItemList.Count; float baseDelayTime = show_base_waiting_time; float gapTime = show_gap_time; float waitTime = 0f; num = m_DataManager.PotionData.LevelDisplayData.ColorTypeList.Count; for (int i = 0; i < count; ++i) { PotionGridUI item = m_DisplayGridItemList[i]; if (i < num) { EventPotionGridState gridState = m_DataManager.PotionData.LevelDisplayData.GridStateList[i]; if (gridState == EventPotionGridState.GridState_Over) { item.SetData(m_DataManager.PotionData.LevelDisplayData, i, null, false); continue; } item.SetRootPosition(new Vector3(baseX + indexForPosition * itemWidth, baseY, baseZ)); item.SetData(m_DataManager.PotionData.LevelDisplayData, i, null, true); item.gameObject.SetActive(false); indexForPosition++; if (gridState == EventPotionGridState.GridState_Empty) { int index = i; float delayTime = baseDelayTime + indexForTime * gapTime; this.StartCoroutine(HandleShowStep(item, index, delayTime, gridState)); indexForTime++; waitTime = delayTime; } } else { item.SetData(null, -1, null, false); } } StopLockClickOperation(); waitTime += show_waitfor_spine_shake_time; return waitTime; } public PotionGridUI GetDisplayPotionGridUI(int index) { if (m_DisplayGridItemList == null || m_DisplayGridItemList.Count < 1 || index >= m_DisplayGridItemList.Count) return null; return m_DisplayGridItemList[index]; } #endregion #region UI // questionmark private Button btn_questionmark; private async void OnBtnQuestionmarkClickListener() { if (IsClickOperationLockedPure) return; await UIManager.Instance.ShowUI(m_DataManager.GetInfoPanel()); } // progress bar private Image bar; private TMP_Text text_progress; private Transform layout_line; private Image img_progress_line; private List img_progress_line_list = new List(); private Button btn_reward; private async void OnBtnRewardClickListener() { if (IsClickOperationLockedPure) return; var panel = await UIManager.Instance.ShowUI(UITypes.EventPotionRewardTips); if (panel == null) return; var rewardList = GContext.container.Resolve().GetItemDataByDropId(m_DataManager.GetLastStageInCurRound().Reward); panel.GetComponent().Init(rewardList, btn_reward.transform); } // Reward private List m_RewardRootList = new List(); private List m_RewardItemNewList = new List(); // item group private List m_DisplayGridItemList = new List(); // icon_ticket private TMP_Text text_num; private TicketTips ticket_tips; private Button icon_ticket; private void OnBtnIconTicketClickListener() { if (IsClickOperationLockedPure) return; ticket_tips.gameObject.SetActive(true); } // Guide private Button mask; private GameObject PotionFirstWrongGuideTips; public float lock_mask_operation_time = 1.0f; bool isLockMask = false; private void OnBtnMaskClickListener() { if (isLockMask == true) return; mask.gameObject.SetActive(false); PotionFirstWrongGuideTips.SetActive(false); //PotionItem operationItem = GetOperationItem(); //if (operationItem == null) return; //operationItem.ResumeFromGuide(); if (m_FirstWrongGridUI == null) return; m_FirstWrongGridUI.ResumeFromGuide(); m_FirstWrongGridUI.PotionItem.OnBtnClickCallback(m_FirstWrongGridUI); m_FirstWrongGridUI = null; m_DataManager.SavePotionIDData(EventPotionConfig.key_first_check_wrong, "ok"); } private void InitUI() { int num = 0; // btn_questionmark btn_questionmark = transform.Find("root_main/title/btn_questionmark").GetComponent