| using System; | 
| using System.Collections; | 
| using System.Collections.Generic; | 
| using System.Linq; | 
| using Jace.Operations; | 
| using LitJson; | 
|   | 
| using UnityEngine; | 
|   | 
| //武将相关界面的操作数据管理 | 
| public partial class HeroUIManager : GameSystemManager<HeroUIManager> | 
| { | 
|     #region 武将列表界面 | 
|     public List<string> heroSortList { get; private set; } = new List<string>();  //上阵为主线的 GUID列表  | 
|     public int selectHeroListJob = 0;    //武将列表界面 筛选职业 | 
|     public int selectHeroListCountry = 0;    //武将列表界面筛选国家 | 
|     public string selectHeroGuid; //选中的武将id | 
|     public int[] heroRedpointItemList;  //有影响红点的道具 | 
|     #endregion | 
|   | 
|     public WaitHeroFuncResponse waitResponse;    //请求武将功能,与服务端交互 | 
|   | 
|     //用于非上阵武将战力变化时 武将ID:上次战力 | 
|     //使用方法:其他功能界面设置该值即可 | 
|     public KeyValuePair<string, long> lastFightPower = new KeyValuePair<string, long>(); | 
|   | 
|     public bool isCustonHeroFormation = false; | 
|     public List<TeamHero> custonTeamHeroes = new List<TeamHero>(); | 
|   | 
|   | 
|     public override void Init() | 
|     { | 
|         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += OnBeforePlayerDataInitialize; | 
|         DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnLoginLoadOK; | 
|         HeroManager.Instance.onHeroChangeEvent += OnHeroChangeEvent; | 
|         GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; | 
|         PackManager.Instance.RefreshItemEvent += RefreshItemEvent; | 
|         TeamManager.Instance.OnTeamChange += OnTeamChangeEvent; | 
|         QuickSetting.Instance.onQuickSettingUpdate += OnQuickSettingUpdate; | 
|         ParseConfig(); | 
|         InitHeroOnTeamRedpointList(); | 
|         InitHeroBookRedpointList(); | 
|     } | 
|   | 
|     public override void Release() | 
|     { | 
|         DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent -= OnBeforePlayerDataInitialize; | 
|         DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnLoginLoadOK; | 
|         HeroManager.Instance.onHeroChangeEvent -= OnHeroChangeEvent; | 
|         GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; | 
|         PackManager.Instance.RefreshItemEvent -= RefreshItemEvent; | 
|         TeamManager.Instance.OnTeamChange -= OnTeamChangeEvent; | 
|         QuickSetting.Instance.onQuickSettingUpdate -= OnQuickSettingUpdate; | 
|     } | 
|   | 
|     void ParseConfig() | 
|     { | 
|         var config = FuncConfigConfig.Get("HeroRebirth"); | 
|         payBackMoneyType = int.Parse(config.Numerical1); | 
|         rebornAwakeHeroMaxCount = int.Parse(config.Numerical2); | 
|         rebornFormula = config.Numerical3; | 
|         rebornPayBackPer = int.Parse(config.Numerical4); | 
|         deletePayBackPer = int.Parse(config.Numerical5); | 
|   | 
|         ParseGiftConfig(); | 
|   | 
|         config = FuncConfigConfig.Get("HeroRedpoint"); | 
|         heroRedpointItemList = JsonMapper.ToObject<int[]>(config.Numerical1); | 
|   | 
|         config = FuncConfigConfig.Get("HeroOnTeam"); | 
|         lockHeroCountLimit = JsonMapper.ToObject<int[][]>(config.Numerical1); | 
|         teamSortByJob = JsonMapper.ToObject<int[]>(config.Numerical2); | 
|         onekeyGuideID = int.Parse(config.Numerical3); | 
|         onekeyGuidePosList = JsonMapper.ToObject<int[]>(config.Numerical4); | 
|          | 
|     } | 
|   | 
|     public void OnBeforePlayerDataInitialize() | 
|     { | 
|         heroSortList.Clear(); | 
|         heroOnTeamSortList.Clear(); | 
|         awakeRebirthCnt = 0; | 
|         waitResponse = default; | 
|         heroCollectInfoDic.Clear(); | 
|         newHeroIDList.Clear(); | 
|     } | 
|   | 
|   | 
|     void OnLoginLoadOK() | 
|     { | 
|         UpdateHeroCardRedpoint(); | 
|     } | 
|   | 
|     private void OnHeroChangeEvent(HeroInfo hero) | 
|     { | 
|         if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin) | 
|             return; | 
|   | 
|         WaitServerResponse(hero); | 
|   | 
|         refreshRedPoint = true; | 
|     } | 
|   | 
|     private void WaitServerResponse(HeroInfo hero) | 
|     { | 
|         if (waitResponse.Equals(default(WaitHeroFuncResponse))) | 
|         { | 
|             return; | 
|         } | 
|         // 等待超过5秒 不处理 | 
|         var nowTime = Time.time; | 
|         if (waitResponse.time > 0f && waitResponse.time + 5 < nowTime) | 
|         { | 
|             waitResponse = default; | 
|             return; | 
|         } | 
|   | 
|         if (hero.itemHero.guid != waitResponse.guid) | 
|         { | 
|             return; | 
|         } | 
|   | 
|         if (waitResponse.type == HeroFuncType.Break) | 
|         { | 
|             UIManager.Instance.OpenWindow<HeroLVBreakSuccessWin>(); | 
|         } | 
|         else if (waitResponse.type == HeroFuncType.Gift) | 
|         { | 
|             UIManager.Instance.OpenWindow<HeroGiftEatSuccessWin>(); | 
|         } | 
|         else if (waitResponse.type == HeroFuncType.Awake) | 
|         { | 
|             var config = HeroAwakeConfig.GetHeroAwakeConfig(hero.heroId, hero.awakeLevel); | 
|             if (hero.talentAwakeRandomIDList.Count > 0) | 
|             { | 
|                 UIManager.Instance.OpenWindow<HeroAwakeSelectGiftWin>(); | 
|             } | 
|             else if (config.SkillID != 0 || config.UnlockTalentSlot != 0) | 
|             { | 
|                 UIManager.Instance.OpenWindow<HeroAwakeSuccessWin>(); | 
|             } | 
|         } | 
|         waitResponse = default; | 
|   | 
|     } | 
|   | 
|     #region 武将UI常用接口 | 
|     public string GetCountryName(int index) | 
|     { | 
|         return RichTextMsgReplaceConfig.GetRichReplace("Country", index); | 
|     } | 
|   | 
|     public string GetJobName(int index) | 
|     { | 
|         return RichTextMsgReplaceConfig.GetRichReplace("Class", index); | 
|     } | 
|   | 
|     public string GetCountryIconName(int index) | 
|     { | 
|         return StringUtility.Contact("herocountry", index); | 
|     } | 
|   | 
|     public string GetJobIconName(int index) | 
|     { | 
|         return StringUtility.Contact("herojob", index); | 
|     } | 
|   | 
|     public int GetMaxLV(int quality) | 
|     { | 
|         return HeroQualityBreakConfig.maxlvDic[quality]; | 
|     } | 
|   | 
|     //是否达到最高级 | 
|     public bool IsLVMax(HeroInfo hero) | 
|     { | 
|         return hero.heroLevel >= GetMaxLV(hero.Quality); | 
|   | 
|     } | 
|     //突破限制的最高等级; 如果存在突破等级后不能再升级是策划配置问题 | 
|     public int GetMaxLVByBreakLV(int quality, int breakLevel) | 
|     { | 
|         // for (int i = breakLevel; i >= 0; i--) | 
|         // { | 
|         //     var config = HeroQualityBreakConfig.GetQualityBreakConfig(quality, i); | 
|         //     if (config == null) | 
|         //     { | 
|         //         continue; | 
|         //     } | 
|         //     return config.LVMax; | 
|         // } | 
|         return HeroQualityBreakConfig.GetQualityBreakConfig(quality, breakLevel).LVMax; | 
|     } | 
|   | 
|     //是否达到因突破限制的最高级 | 
|     public bool IsLVMaxByBreakLevel(HeroInfo hero) | 
|     { | 
|         return hero.heroLevel == GetMaxLVByBreakLV(hero.Quality, hero.breakLevel); | 
|     } | 
|   | 
|     #endregion | 
|   | 
|   | 
|     public void QueryUnLockHeroPack() | 
|     { | 
|         //解锁更多的武将背包 | 
|         int canBuyCnt = PackManager.Instance.GetCanBuyPackGirdCount(PackType.Hero); | 
|         if (canBuyCnt <= 0) | 
|         { | 
|             return; | 
|         } | 
|   | 
|         var buyInfo = PackManager.Instance.BuyPackGirdNeedData(PackType.Hero); | 
|         ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), | 
|         Language.Get("HeroPack1", UIHelper.GetIconNameWithMoneyType(buyInfo[0]), buyInfo[1], buyInfo[2]), | 
|             (bool isOK) => | 
|             { | 
|                 if (isOK) | 
|                 { | 
|                     if (UIHelper.GetMoneyCnt(buyInfo[0]) < buyInfo[1]) | 
|                     { | 
|                         SysNotifyMgr.Instance.ShowTip("LackMoney", buyInfo[0]); | 
|                         return; | 
|                     } | 
|                     PackManager.Instance.BuyPackGird(PackType.Hero); | 
|                 } | 
|             }); | 
|     } | 
|   | 
|     //刷新时机, 打开武将界面 或者 关闭功能界面 | 
|     public void SortHeroList() | 
|     { | 
|         heroSortList = HeroManager.Instance.GetHeroGuidList(selectHeroListJob, selectHeroListCountry); | 
|         heroSortList.Sort(CmpHero); | 
|     } | 
|   | 
|   | 
|     int CmpHero(string guidA, string guidB) | 
|     { | 
|         HeroInfo heroA = HeroManager.Instance.GetHero(guidA); | 
|         HeroInfo heroB = HeroManager.Instance.GetHero(guidB); | 
|         if (heroA == null || heroB == null) | 
|         { | 
|             return 0; | 
|         } | 
|   | 
|         // 排序规则:上阵>武将等级>突破等级>武将觉醒阶级>武将品质>武将吞噬星级>武将ID | 
|         bool isInTeamA = heroA.IsInTeamByTeamType(TeamType.Story); | 
|         bool isInTeamB = heroB.IsInTeamByTeamType(TeamType.Story); | 
|         if (isInTeamA != isInTeamB) | 
|         { | 
|             return isInTeamA ? -1 : 1; | 
|         } | 
|         if (heroA.heroLevel != heroB.heroLevel) | 
|         { | 
|             return heroA.heroLevel > heroB.heroLevel ? -1 : 1; | 
|         } | 
|         if (heroA.breakLevel != heroB.breakLevel) | 
|         { | 
|             return heroA.breakLevel > heroB.breakLevel ? -1 : 1; | 
|         } | 
|         if (heroA.awakeLevel != heroB.awakeLevel) | 
|         { | 
|             return heroA.awakeLevel > heroB.awakeLevel ? -1 : 1; | 
|         } | 
|         if (heroA.Quality != heroB.Quality) | 
|         { | 
|             return heroA.Quality > heroB.Quality ? -1 : 1; | 
|         } | 
|         if (heroA.heroStar != heroB.heroStar) | 
|         { | 
|             return heroA.heroStar > heroB.heroStar ? -1 : 1; | 
|         } | 
|   | 
|         return heroA.heroId.CompareTo(heroB.heroId); | 
|     } | 
|   | 
|   | 
|   | 
|     #region 招募 | 
|   | 
|     public HappXBTitle selectCallType;  //寻宝枚举类型 | 
|     public int selectCallIndex;//0:1抽 1:10抽 对应配置顺序 | 
|     public const string skipKey = "SkipHeroCall"; | 
|   | 
|     //积分招募预览 | 
|     public List<int> heroCallSortList { get; private set; } = new List<int>();  //积分招募列表  | 
|     public int selectHeroCallListJob = 0;    //筛选职业 | 
|     public int selectHeroCallListCountry = 0;    //筛选国家 | 
|   | 
|     public List<int> newHeroIDList = new List<int>();  //新武将列表 | 
|     public bool IsNewHero(int heroID) | 
|     { | 
|         HB122_tagSCHeroInfo.tagSCHero bookInfo; | 
|         if (TryGetHeroBookInfo(heroID, out bookInfo)) | 
|         { | 
|             if (bookInfo.BookInitState < 2) | 
|             { | 
|                 //更精准的 需要比较本次抽的同武将个数 和 背包里有的个数再比较 | 
|                 if (HappyXBModel.Instance.GetCountInResult(heroID) >= HeroManager.Instance.GetHeroCountByID(heroID)) | 
|                 { | 
|                     AddNewHero(heroID); | 
|                     return true; | 
|                 } | 
|                 else | 
|                 { | 
|                     return false; | 
|                 } | 
|             } | 
|             else | 
|             { | 
|                 return false; | 
|             } | 
|         } | 
|   | 
|         AddNewHero(heroID); | 
|         return true; | 
|     } | 
|   | 
|     public void AddNewHero(int heroID) | 
|     { | 
|         if (newHeroIDList.Contains(heroID)) | 
|         { | 
|             return; | 
|         } | 
|         newHeroIDList.Add(heroID); | 
|     } | 
|   | 
|     public void RemoveNewHero(int heroID) | 
|     { | 
|         if (!newHeroIDList.Contains(heroID)) | 
|         { | 
|             return; | 
|         } | 
|         newHeroIDList.Remove(heroID); | 
|         refreshRedPoint = true; | 
|     } | 
|   | 
|     List<int> allHeroCallScoreList = new List<int>();  //积分招募列表  | 
|     public void SortHeroCallList() | 
|     { | 
|         if (allHeroCallScoreList.IsNullOrEmpty()) | 
|         { | 
|             allHeroCallScoreList = HappyXBModel.Instance.GetAllGridLibItemIDByType((int)HappXBTitle.HeroCallScore); | 
|         } | 
|         heroCallSortList = new List<int>(); | 
|         if (selectHeroCallListJob == 0 && selectHeroCallListCountry == 0) | 
|         { | 
|             heroCallSortList = allHeroCallScoreList; | 
|         } | 
|         else | 
|         { | 
|             foreach (var item in allHeroCallScoreList) | 
|             { | 
|                 HeroConfig heroConfig = HeroConfig.Get(item); | 
|                 if (heroConfig == null) | 
|                 { | 
|                     continue; | 
|                 } | 
|                 if (selectHeroCallListJob != 0 && selectHeroCallListJob != heroConfig.Class) | 
|                 { | 
|                     continue; | 
|                 } | 
|                 if (selectHeroCallListCountry != 0 && selectHeroCallListCountry != heroConfig.Country) | 
|                 { | 
|                     continue; | 
|                 } | 
|                 heroCallSortList.Add(item); | 
|             } | 
|         } | 
|   | 
|         heroCallSortList.Sort(CmpHeroID); | 
|     } | 
|   | 
|     int CmpHeroID(int idA, int idB) | 
|     { | 
|         HeroConfig heroA = HeroConfig.Get(idA); | 
|         HeroConfig heroB = HeroConfig.Get(idB); | 
|   | 
|         // 排序规则:武将品质>武将ID | 
|         if (heroA.Quality != heroB.Quality) | 
|         { | 
|             return heroA.Quality > heroB.Quality ? -1 : 1; | 
|         } | 
|   | 
|         return heroA.HeroID.CompareTo(heroB.HeroID); | 
|     } | 
|   | 
|     #endregion | 
|   | 
|   | 
|     // 优先功能提醒类型:1觉醒 2升星 3突破 4升级 | 
|     // 主线上阵武将才需要提醒  觉醒>升星>突破>升级 | 
|     public int GetFuncState(HeroInfo hero) | 
|     { | 
|         if (!hero.IsInTeamByTeamType(TeamType.Story)) | 
|         { | 
|             return 0; | 
|         } | 
|   | 
|         var heroCnt = PackManager.Instance.GetItemCountByID(PackType.Hero, hero.heroId); | 
|         var itemPack = PackManager.Instance.GetSinglePack(PackType.Item); | 
|         //5星后才能觉醒 | 
|         if (hero.heroStar < starLevelCanAwake) | 
|         { | 
|             if (heroCnt > 1) return 2; | 
|         } | 
|         else | 
|         { | 
|             //判断觉醒材料是否足够 | 
|             var maxAwakeLV = HeroAwakeConfig.GetMaxAwakeLV(hero.heroId); | 
|             if (hero.awakeLevel < maxAwakeLV) | 
|             { | 
|                 var config = HeroQualityAwakeConfig.GetQualityAwakeConfig(hero.Quality, hero.awakeLevel); | 
|                 if (itemPack.GetCountById(config.UPCostItem[0]) >= config.UPCostItem[1]) | 
|                 { | 
|                     return 1; | 
|                 } | 
|             } | 
|         } | 
|   | 
|         if (heroCnt > 1) return 2; | 
|   | 
|         var maxBreakLV = HeroBreakConfig.GetMaxBreakLv(hero.heroId); | 
|         if (hero.breakLevel < maxBreakLV) | 
|         { | 
|             if (IsLVMaxByBreakLevel(hero)) | 
|             { | 
|                 var breakConfig = HeroQualityBreakConfig.GetQualityBreakConfig(hero.Quality, hero.breakLevel); | 
|                 if (itemPack.GetCountById(breakConfig.UPCostItem[0]) >= breakConfig.UPCostItem[1]) | 
|                 { | 
|                     return 3; | 
|                 } | 
|                 return 0; | 
|             } | 
|         } | 
|   | 
|         if (!IsLVMax(hero)) | 
|         { | 
|             var lvupConfig = HeroQualityLVConfig.GetQualityLVConfig(hero.Quality, hero.heroLevel); | 
|             if (itemPack.GetCountById(lvupConfig.UPCostItem[0]) >= lvupConfig.UPCostItem[1]) | 
|             { | 
|                 return 4; | 
|             } | 
|         } | 
|         return 0; | 
|     } | 
|   | 
|     #region 红点 | 
|   | 
|     public bool refreshRedPoint = false; | 
|     List<Redpoint> heroOnTeamRedpointList = new List<Redpoint>();   //上阵的武将红点 | 
|     List<Redpoint> heroBookRedpointList = new List<Redpoint>(); //图鉴所有武将红点 | 
|   | 
|     //新标识的红点 所有武将统一个 | 
|     Redpoint newMarkRedPoint = new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + 9); | 
|     void InitHeroOnTeamRedpointList() | 
|     { | 
|         heroOnTeamRedpointList.Clear(); | 
|         for (int i = 0; i < TeamConst.MaxTeamHeroCount; i++) | 
|         { | 
|             heroOnTeamRedpointList.Add(new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + i)); | 
|         } | 
|     } | 
|   | 
|   | 
|     //武将卡的红点:只给上阵武将刷红点(含新标识),非上阵武将的新图标按图片处理不归类为红点 | 
|     void UpdateHeroCardRedpoint() | 
|     { | 
|         if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Hero)) | 
|             return; | 
|   | 
|         var team = TeamManager.Instance.GetTeam(TeamType.Story); | 
|         for (int i = 0; i < heroOnTeamRedpointList.Count; i++) | 
|         { | 
|             var redpoint = heroOnTeamRedpointList[i]; | 
|             var teamHero = team.GetServerHeroByIndex(i); | 
|             if (teamHero != null) | 
|             { | 
|                 var hero = HeroManager.Instance.GetHero(teamHero.guid); | 
|                 if (hero != null) | 
|                 { | 
|                     if (GetFuncState(hero) > 0) | 
|                     { | 
|                         redpoint.state = RedPointState.Simple; | 
|                         continue; | 
|                     } | 
|                 } | 
|             } | 
|   | 
|             redpoint.state = RedPointState.None; | 
|         } | 
|   | 
|         newMarkRedPoint.state = newHeroIDList.Count > 0 ? RedPointState.New : RedPointState.None; | 
|     } | 
|   | 
|   | 
|     void InitHeroBookRedpointList() | 
|     { | 
|         heroBookRedpointList.Clear(); | 
|         foreach (var key in HeroConfig.GetKeys()) | 
|         { | 
|             var config = HeroConfig.Get(key); | 
|             if (config.PlayerCanUse == 0) | 
|                 continue; | 
|             heroBookRedpointList.Add(new Redpoint(MainRedDot.HeroCardCollectRedpoint, MainRedDot.HeroCardCollectRedpoint * 10000000 + key)); | 
|         } | 
|     } | 
|   | 
|     void UpdateHeroBookRedpoint() | 
|     { | 
|         if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.Hero)) | 
|             return; | 
|   | 
|         foreach (var redpoint in heroBookRedpointList) | 
|         { | 
|             var heroID = redpoint.id % 10000000; | 
|             var state = GetHeroBookState(heroID, HeroConfig.Get(heroID).Quality); | 
|             if (state == 1 || state == 3 || state == 4) | 
|             { | 
|                 redpoint.state = RedPointState.Simple; | 
|                 continue; | 
|             } | 
|             redpoint.state = RedPointState.None; | 
|         } | 
|     } | 
|   | 
|   | 
|     void OnSecondEvent() | 
|     { | 
|         if (refreshRedPoint) | 
|         { | 
|             UpdateHeroCardRedpoint(); | 
|             refreshRedPoint = false; | 
|         } | 
|     } | 
|   | 
|     void RefreshItemEvent(PackType packType, int index, int itemID) | 
|     { | 
|         if (packType != PackType.Item) | 
|             return; | 
|   | 
|         if (heroRedpointItemList.Contains(itemID)) | 
|         { | 
|             refreshRedPoint = true; | 
|         } | 
|     } | 
|   | 
|     void OnTeamChangeEvent(TeamType teamType) | 
|     { | 
|         if (teamType == TeamType.Story) | 
|         { | 
|             refreshRedPoint = true; | 
|         } | 
|     } | 
|     #endregion | 
| } | 
|   | 
| #region 等待服务端响应 | 
| public struct WaitHeroFuncResponse | 
| { | 
|     public HeroFuncType type; | 
|     public string guid; | 
|     public float time; | 
| } | 
|   | 
| //武将功能类型 | 
| public enum HeroFuncType | 
| { | 
|     None = 0,   //无功能 | 
|     Break = 1,  //突破 | 
|     Gift = 2,  //天赋吞噬 | 
|     Awake = 3,  //觉醒 | 
| } | 
| #endregion |