| using System.Collections; | 
| using System.Collections.Generic; | 
| using UnityEngine; | 
| using UnityEngine.UI; | 
| using DG.Tweening; | 
| using Cysharp.Threading.Tasks; | 
| using System.Threading; | 
| using System; | 
|   | 
| /// <summary> | 
| /// 武将布阵界面 | 
| /// </summary> | 
| public class HeroPosWin : UIBase | 
| { | 
|     [SerializeField] Text[] attrOnList; //上阵属性加成 | 
|     [SerializeField] Button countryOnBtn; | 
|     [SerializeField] Image countryOnImg;    //上阵阵型激活国家 | 
|     [SerializeField] UIEffectPlayer countryEffect; | 
|     [SerializeField] List<Image> OnCountImgs;    //上阵数量激活 | 
|     [SerializeField] List<Image> scenePosImgs;  //场景布阵位置 | 
|     [SerializeField] HeroScenePosCell[] sceneHero; | 
|   | 
|     [SerializeField] GroupButtonEx attackTeamBtn; | 
|     [SerializeField] GroupButtonEx defendTeamBtn; | 
|   | 
|     [SerializeField] Text fightPowerText;   //由客户端自己预算的战力 | 
|     [SerializeField] ScrollerController heroListScroller; | 
|     [SerializeField] Transform heroListEmpty; | 
|     [SerializeField] Toggle showConnTipToggleBtn; | 
|   | 
|     [SerializeField] HeroSelectBehaviour fiterManager;  //武将筛选 | 
|   | 
|     [SerializeField] Button oneKeyOnBtn;     //一键上阵 | 
|     [SerializeField] Button saveBtn;        //保存阵型 | 
|     [SerializeField] Button backBtn;      //退出界面 | 
|     [SerializeField] GroupButtonEx jjcBtn;       //竞技场 | 
|     // [SerializeField] GroupButtonEx tttBtn;        //通天塔 | 
|     [SerializeField] GroupButtonEx mainFBBtn;     //主线副本 | 
|   | 
|     //羁绊 | 
|     [SerializeField] HeroConnectionCell connetionForm; | 
|     [SerializeField] HeroHeadBaseCell flyHead; | 
|     [SerializeField] CanvasGroup flyAlphaTween; | 
|   | 
|     Sequence sequence; | 
|     CancellationTokenSource _cts; | 
|     Queue<int> showConnectTipQueue = new Queue<int>(); | 
|   | 
|     private bool m_IsToggleOn = false; | 
|     private bool isToggleOn | 
|     { | 
|         get { return m_IsToggleOn; } | 
|         set | 
|         { | 
|             if (m_IsToggleOn != value) | 
|             { | 
|                 m_IsToggleOn = value; | 
|                 LocalSave.SetBool("ShowConn" + PlayerDatas.Instance.baseData.PlayerID, value); | 
|             } | 
|         } | 
|     } | 
|   | 
|     protected override void InitComponent() | 
|     { | 
|         attackTeamBtn.AddListener(() => | 
|         { | 
|             SelectTeamFunc((TeamType)HeroUIManager.Instance.GetSelectTeamTypeByAttackType(0)); | 
|         }); | 
|         defendTeamBtn.AddListener(() => | 
|         { | 
|             SelectTeamFunc((TeamType)HeroUIManager.Instance.GetSelectTeamTypeByAttackType(1)); | 
|         }); | 
|   | 
|         mainFBBtn.AddListener(() => | 
|         { | 
|             SelectTeamFunc(TeamType.Story); | 
|         }); | 
|   | 
|         jjcBtn.AddListener(() => | 
|         { | 
|             SelectTeamFunc(TeamType.Arena); | 
|         }); | 
|         // tttBtn.AddListener(() => | 
|         // { | 
|         //     SelectTeamFunc(TeamType.Tower); | 
|         // }); | 
|   | 
|         showConnTipToggleBtn.AddListener((value) => | 
|         { | 
|             isToggleOn = showConnTipToggleBtn.isOn; | 
|             if (isToggleOn == false) | 
|             { | 
|                 CancelCurrentTask(); | 
|             } | 
|         }); | 
|         oneKeyOnBtn.AddListener(OneKeyOnPos); | 
|         saveBtn.AddListener(SaveTeam); | 
|   | 
|         backBtn.AddListener(CloseWindow); | 
|   | 
|         countryOnBtn.AddListener(() => | 
|         { | 
|             HeroUIManager.Instance.isCustonHeroFormation = false; | 
|             UIManager.Instance.OpenWindow<HeroFormationWin>(); | 
|         }); | 
|   | 
|         m_IsToggleOn = LocalSave.GetBool("ShowConn" + PlayerDatas.Instance.baseData.PlayerID, false); | 
|     } | 
|   | 
|   | 
|     protected override void OnPreOpen() | 
|     { | 
|         HeroUIManager.Instance.selectTeamPosJob = 0; | 
|         HeroUIManager.Instance.selectTeamPosCountry = 0; | 
|         HeroUIManager.Instance.SortHeroOnTeamList(); | 
|         heroListScroller.OnRefreshCell += OnRefreshCell; | 
|         HeroUIManager.Instance.OnTeamPosChangeEvent += TeamChangeEvent; | 
|         TeamManager.Instance.OnTeamChange += OnTeamChange; | 
|         SelectTiltleBtn(); | 
|         CreateScroller(); | 
|         Display(); | 
|     } | 
|   | 
|     protected override void OnPreClose() | 
|     { | 
|         CancelCurrentTask(); | 
|         heroListScroller.OnRefreshCell -= OnRefreshCell; | 
|         HeroUIManager.Instance.OnTeamPosChangeEvent -= TeamChangeEvent; | 
|         TeamManager.Instance.OnTeamChange -= OnTeamChange; | 
|         TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType).RestoreTeam(); | 
|     } | 
|   | 
|   | 
|     void SelectTiltleBtn() | 
|     { | 
|         if (functionOrder == 0) | 
|         { | 
|             mainFBBtn.SelectBtn(); | 
|         } | 
|         else if (functionOrder == 1) | 
|         { | 
|             jjcBtn.SelectBtn(); | 
|         } | 
|     } | 
|   | 
|   | 
|     public void Display() | 
|     { | 
|         OnBattleTeamAttrPer(); | 
|         RefreshOnTeamCountry(); | 
|         RefreshOnTeamBtn(); | 
|         RefreshTeamHero(); | 
|         RefreshFlyHead(); | 
|         RefreshConn(); | 
|   | 
|         RefreshEmptyTip(); | 
|   | 
|         showConnTipToggleBtn.isOn = isToggleOn; | 
|   | 
|         fiterManager.Display(0, HeroUIManager.Instance.selectTeamPosJob, HeroUIManager.Instance.selectTeamPosCountry, SelectJobCountry); | 
|   | 
|   | 
|         fightPowerText.text = UIHelper.ReplaceLargeArtNum(FightPowerManager.Instance.GetTeamFightPower(HeroUIManager.Instance.selectTeamType, true)); | 
|   | 
|   | 
|     } | 
|   | 
|     void RefreshFlyHead() | 
|     { | 
|         var flyCanvas = flyAlphaTween.GetComponent<Canvas>(); | 
|         flyCanvas.sortingLayerID = canvas.sortingLayerID; | 
|         flyCanvas.sortingOrder = canvas.sortingOrder + 9; | 
|         flyAlphaTween.alpha = 0; | 
|         flyHead.transform.localScale = Vector3.zero; | 
|     } | 
|   | 
|     void RefreshConn() | 
|     { | 
|         connetionForm.SetActive(false); | 
|         var canvasConn = connetionForm.GetComponent<Canvas>(); | 
|         canvasConn.sortingLayerID = canvas.sortingLayerID; | 
|         canvasConn.sortingOrder = canvas.sortingOrder + 9; | 
|         CancelCurrentTask(); | 
|     } | 
|   | 
|     void SelectJobCountry(int job, int country) | 
|     { | 
|         HeroUIManager.Instance.selectTeamPosJob = job; | 
|         HeroUIManager.Instance.selectTeamPosCountry = country; | 
|         HeroUIManager.Instance.SortHeroOnTeamList(); | 
|         CreateScroller(); | 
|         RefreshEmptyTip(); | 
|     } | 
|   | 
|     void RefreshEmptyTip() | 
|     { | 
|         if (HeroUIManager.Instance.heroOnTeamSortList.Count <= 0) | 
|         { | 
|             heroListEmpty.SetActive(true); | 
|             heroListScroller.SetActive(false); | 
|         } | 
|         else | 
|         { | 
|             heroListEmpty.SetActive(false); | 
|             heroListScroller.SetActive(true); | 
|         } | 
|     } | 
|   | 
|     void OnRefreshCell(ScrollerDataType type, CellView cell) | 
|     { | 
|         var _cell = cell as HeroPosLineCell; | 
|         _cell.Display(cell.index); | 
|     } | 
|   | 
|     void CreateScroller() | 
|     { | 
|         heroListScroller.Refresh(); | 
|         for (int i = 0; i < HeroUIManager.Instance.heroOnTeamSortList.Count; i++) | 
|         { | 
|             if (i % 5 == 0) | 
|             { | 
|                 heroListScroller.AddCell(ScrollerDataType.Header, i); | 
|             } | 
|         } | 
|         heroListScroller.Restart(); | 
|     } | 
|   | 
|     //上阵加成 | 
|     void OnBattleTeamAttrPer() | 
|     { | 
|         var valuePer = 0; | 
|         var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType); | 
|         if (team != null) | 
|         { | 
|             for (int i = 0; i < team.tempHeroes.Length; i++) | 
|             { | 
|                 if (team.tempHeroes[i] == null) | 
|                     continue; | 
|                 var hero = HeroManager.Instance.GetHero(team.tempHeroes[i].guid); | 
|                 if (hero != null) | 
|                 { | 
|                     valuePer += hero.GetOnBattleAddPer(); | 
|                 } | 
|             } | 
|   | 
|         } | 
|         //上阵属性 | 
|         for (int i = 0; i < attrOnList.Length; i++) | 
|         { | 
|             string format = valuePer == 0 ? "{0}+{1}" : "{0}+" + UIHelper.AppendColor(TextColType.Green, "{1}", false); | 
|             attrOnList[i].text = PlayerPropertyConfig.GetFullDescription(PlayerPropertyConfig.basePerAttrs[i], valuePer, format); | 
|         } | 
|     } | 
|   | 
|     //上阵武将国家光环激活 | 
|     void RefreshOnTeamCountry(bool playEffect = false) | 
|     { | 
|         Int2 result = HeroUIManager.Instance.GetMaxCountHeroCountry(HeroUIManager.Instance.selectTeamType, true); | 
|   | 
|         var config = HeroLineupHaloConfig.GetConfig(result.x, result.y); | 
|         if (config == null) | 
|         { | 
|             countryOnImg.SetSprite("heroTeamCountry0"); | 
|             for (int i = 0; i < OnCountImgs.Count; i++) | 
|             { | 
|                 OnCountImgs[i].SetActive(false); | 
|             } | 
|         } | 
|         else | 
|         { | 
|             countryOnImg.SetSprite("heroTeamCountry" + result.x); | 
|             for (int i = 0; i < OnCountImgs.Count; i++) | 
|             { | 
|                 if (i < result.y) | 
|                 { | 
|                     OnCountImgs[i].SetActive(true); | 
|                     OnCountImgs[i].SetSprite("heroTeamCountryPoint" + result.x); | 
|                 } | 
|                 else | 
|                 { | 
|                     OnCountImgs[i].SetActive(false); | 
|                 } | 
|             } | 
|             if (playEffect) | 
|                 countryEffect.Play(); | 
|         } | 
|   | 
|     } | 
|   | 
|     //管理布阵入口按钮:如竞技场是否根据功能显隐,通天塔和主线只有进攻方布阵默认不显示 | 
|     void RefreshOnTeamBtn() | 
|     { | 
|         if (HeroUIManager.Instance.selectTeamType == TeamType.Arena || | 
|             HeroUIManager.Instance.selectTeamType == TeamType.ArenaDefense) | 
|         { | 
|             attackTeamBtn.SetActive(true); | 
|             defendTeamBtn.SetActive(true); | 
|             if (HeroUIManager.Instance.selectTeamType == TeamType.Arena) | 
|             { | 
|                 attackTeamBtn.SelectBtn(true); | 
|             } | 
|             else | 
|             { | 
|                 defendTeamBtn.SelectBtn(true); | 
|             } | 
|         } | 
|         else | 
|         { | 
|             attackTeamBtn.SetActive(false); | 
|             defendTeamBtn.SetActive(false); | 
|         } | 
|   | 
|     } | 
|   | 
|     void RefreshTeamHero() | 
|     { | 
|         var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType); | 
|         for (int i = 0; i < sceneHero.Length; i++) | 
|         { | 
|             var teamHero = team.tempHeroes[i]; | 
|             if (teamHero == null) | 
|             { | 
|                 sceneHero[i].SetActive(false); | 
|             } | 
|             else | 
|             { | 
|                 sceneHero[i].SetActive(true); | 
|                 sceneHero[i].Display(teamHero.guid, i); | 
|                 //按scenePosImgs 顺序排序对应位置 | 
|                 sceneHero[i].transform.position = scenePosImgs[i].transform.position; | 
|                 sceneHero[i].transform.localScale = Vector3.one; | 
|             } | 
|   | 
|         } | 
|         RefreshPosScale(); | 
|     } | 
|   | 
|     void RefreshPosScale() | 
|     { | 
|         for (int i = 0; i < scenePosImgs.Count; i++) | 
|         { | 
|             scenePosImgs[i].transform.localScale = Vector3.one; | 
|         } | 
|     } | 
|   | 
|     /// <summary> | 
|     /// 点击上阵,拖拉,一键等触发; | 
|     /// </summary> | 
|     /// <param name="posList">要刷新的布阵位置</param> | 
|     /// <param name="flyFrom">大于-1代表是点击上阵,需要表现飞行效果</param> | 
|     void TeamChangeEvent(List<int> posList, int flyFrom, Vector3 startPos) | 
|     { | 
|         var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType); | 
|         foreach (var i in posList) | 
|         { | 
|             var teamHero = team.tempHeroes[i]; | 
|             if (teamHero == null) | 
|             { | 
|                 sceneHero[i].SetActive(false); | 
|             } | 
|             else | 
|             { | 
|                 sceneHero[i].SetActive(true); | 
|                 sceneHero[i].Display(teamHero.guid, i, flyFrom >= 0, flyFrom != -2 ? true : false); | 
|                 //按scenePosImgs 顺序排序对应位置 | 
|                 sceneHero[i].transform.position = scenePosImgs[i].transform.position; | 
|                 sceneHero[i].transform.localScale = Vector3.one; | 
|   | 
|             } | 
|         } | 
|         RefreshPosScale(); | 
|         heroListScroller.m_Scorller.RefreshActiveCellViews(); | 
|         RefreshOnTeamCountry(true); | 
|         OnBattleTeamAttrPer(); | 
|   | 
|         //表现飞入,连续点击不同头像触发的话则重置 | 
|         if (flyFrom > -1) | 
|         { | 
|             var flyHero = HeroManager.Instance.GetHero(HeroUIManager.Instance.heroOnTeamSortList[flyFrom]); | 
|             if (flyHero == null) | 
|                 return; | 
|   | 
|             //先停止 sequence | 
|             if (sequence != null) | 
|             { | 
|                 sequence.Kill(); | 
|             } | 
|             sequence = DOTween.Sequence(); | 
|   | 
|   | 
|             flyAlphaTween.alpha = 1; | 
|             flyHead.Init(flyHero.heroId, flyHero.SkinID); | 
|             flyHead.transform.position = startPos; | 
|             var targetPos = scenePosImgs[posList[0]].transform.position; | 
|             flyHead.transform.localScale = Vector3.one; | 
|             sequence.Append(flyHead.transform.DOMove(targetPos, HeroUIManager.clickFlyPosTime).SetEase(Ease.OutQuad)) | 
|                 .Join(flyHead.transform.DOScale(new Vector3(0.5f, 0.5f, 0.5f), HeroUIManager.clickFlyPosTime).SetEase(Ease.OutQuad)) | 
|                 .Join(flyAlphaTween.DOFade(0f, HeroUIManager.clickFlyPosTime).SetEase(Ease.OutQuad)); | 
|             sequence.onComplete = () => { flyHead.transform.localScale = Vector3.zero; }; | 
|   | 
|             if (isToggleOn) | 
|             { | 
|                 ShowFetter(flyHero); | 
|             } | 
|         } | 
|         fightPowerText.text = UIHelper.ReplaceLargeArtNum(FightPowerManager.Instance.GetTeamFightPower(HeroUIManager.Instance.selectTeamType, true)); | 
|   | 
|     } | 
|   | 
|     void ShowFetter(HeroInfo hero) | 
|     { | 
|         var heroConfig = hero.heroConfig; | 
|         var fetterList = hero.GetActiveFetter(heroConfig, TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType)); | 
|         for (int i = 0; i < fetterList.Count; i++) | 
|         { | 
|             if (!showConnectTipQueue.Contains(fetterList[i])) | 
|                 showConnectTipQueue.Enqueue(fetterList[i]); | 
|         } | 
|   | 
|         if (_cts == null) | 
|         { | 
|             _cts = new CancellationTokenSource(); | 
|             RunTaskAsync(_cts.Token).Forget(); // Forget() 表示不等待此任务完成 | 
|         } | 
|   | 
|     } | 
|     async UniTask RunTaskAsync(CancellationToken token) | 
|     { | 
|         try | 
|         { | 
|             while (showConnectTipQueue.Count > 0) | 
|             { | 
|                 await UniTask.Delay(300, cancellationToken: token); | 
|                 showConnectTipQueue.TryDequeue(out int fetterID); | 
|                 if (fetterID == 0) | 
|                 { | 
|                     continue; | 
|                 } | 
|                 connetionForm.SetActive(true); | 
|                 connetionForm.Display(fetterID); | 
|                 //显示1.5秒后关闭 | 
|                 await UniTask.Delay(1500, cancellationToken: token); | 
|                 connetionForm.SetActive(false); | 
|             } | 
|   | 
|         } | 
|         catch (OperationCanceledException) | 
|         { | 
|             Debug.Log("羁绊 协程被取消"); | 
|             connetionForm.SetActive(false); | 
|         } | 
|         finally | 
|         { | 
|             _cts?.Dispose();     // 释放资源 | 
|             _cts = null;         // 置空避免重复取消 | 
|             showConnectTipQueue.Clear(); | 
|         } | 
|   | 
|     } | 
|   | 
|     // 取消当前正在运行的任务 | 
|     public void CancelCurrentTask() | 
|     { | 
|         _cts?.Cancel();      // 触发取消 | 
|         _cts?.Dispose();     // 释放资源 | 
|         _cts = null;         // 置空避免重复取消 | 
|         showConnectTipQueue.Clear(); | 
|     } | 
|   | 
|     void OneKeyOnPos() | 
|     { | 
|         var guidList = HeroUIManager.Instance.SelectRecommend(); | 
|         var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType); | 
|         team.RemoveAllHeroes(); | 
|         if (NewBieCenter.Instance.inGuiding && NewBieCenter.Instance.currentGuide == HeroUIManager.Instance.onekeyGuideID) | 
|         { | 
|             //第二个强制排在5号位 | 
|             if (guidList.Count > 1) | 
|             { | 
|                 team.AddHero(HeroManager.Instance.GetHero(guidList[1]), 4, true); | 
|                 guidList.RemoveAt(1); | 
|             } | 
|   | 
|             for (int i = 0; i < guidList.Count; i++) | 
|             { | 
|                 int index = i; | 
|                 if (i >= 4) | 
|                 { | 
|                     index = i + 1; | 
|                 } | 
|                 team.AddHero(HeroManager.Instance.GetHero(guidList[i]), index, true); | 
|             } | 
|   | 
|         } | 
|         else | 
|         { | 
|             for (int i = 0; i < guidList.Count; i++) | 
|             { | 
|                 team.AddHero(HeroManager.Instance.GetHero(guidList[i]), i, true); | 
|             } | 
|         }         | 
|   | 
|         TeamChangeEvent(new List<int>() { 0, 1, 2, 3, 4, 5 }, -1, Vector3.zero); | 
|   | 
|     } | 
|   | 
|     void SaveTeam() | 
|     { | 
|         var team = TeamManager.Instance.GetTeam(HeroUIManager.Instance.selectTeamType); | 
|         team.SaveTeam(); | 
|     } | 
|   | 
|     void SelectTeamFunc(TeamType type) | 
|     { | 
|         if (HeroUIManager.Instance.selectTeamType == type) | 
|         { | 
|             return; | 
|         } | 
|         HeroUIManager.Instance.selectTeamPosJob = 0; | 
|         HeroUIManager.Instance.selectTeamPosCountry = 0; | 
|         HeroUIManager.Instance.selectTeamType = type; | 
|         HeroUIManager.Instance.SortHeroOnTeamList(); | 
|         Display(); | 
|         heroListScroller.m_Scorller.RefreshActiveCellViews(); | 
|     } | 
|      | 
|     protected void OnTeamChange(TeamType teamType) | 
|     { | 
|         if (HeroUIManager.Instance.selectTeamType == teamType) | 
|         { | 
|             HeroUIManager.Instance.SortHeroOnTeamList(); | 
|             heroListScroller.m_Scorller.RefreshActiveCellViews(); | 
|         } | 
|     } | 
| } |