using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Jace.Operations; using LitJson; using UnityEngine; //武将相关界面的操作数据管理 public partial class HeroUIManager : GameSystemManager { #region 武将列表界面 public List heroSortList { get; private set; } = new List(); //上阵为主线的 GUID列表 public List selectHeroList = new List(); //武将列表界面 筛选职业 public string selectHeroGuid; //选中的武将id public int[] heroRedpointItemList; //有影响红点的道具 #endregion public WaitHeroFuncResponse waitResponse; //请求武将功能,与服务端交互 //用于非上阵武将战力变化时 武将ID:上次战力 //使用方法:其他功能界面设置该值即可 public KeyValuePair lastFightPower = new KeyValuePair(); public bool isCustonHeroFormation = false; public List custonTeamHeroes = new List(); public Dictionary heroStarGuideDic = new Dictionary(); public int firstHeroIDBookUpdate = 0; //图鉴中第一个可以升级或者升星的武将,引导用 public List heroSpecialAttrsForSelect = new List(); //筛选用的特殊属性汇总 public bool isOpenHeroTip = false; 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(); InitHerosData(); } 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(config.Numerical1); config = FuncConfigConfig.Get("HeroOnTeam"); lockHeroCountLimit = JsonMapper.ToObject(config.Numerical1); teamSortByJob = JsonMapper.ToObject(config.Numerical2); onekeyGuideID = int.Parse(config.Numerical3); onekeyGuidePosList = JsonMapper.ToObject(config.Numerical4); config = FuncConfigConfig.Get("Guide"); heroStarGuideDic = ConfigParse.ParseIntDict(config.Numerical1); config = FuncConfigConfig.Get("HeroDelete"); jumpDeleteHeroQuality = int.Parse(config.Numerical1); isJumpDeleteHero = int.Parse(config.Numerical2) == 1; } public void OnBeforePlayerDataInitialize() { heroSortList.Clear(); heroOnTeamSortList.Clear(); awakeRebirthCnt = 0; waitResponse = default; heroCollectInfoDic.Clear(); newHeroIDList.Clear(); firstHeroIDBookUpdate = 0; isOpenHeroTip = false; } 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(); } else if (waitResponse.type == HeroFuncType.Gift) { UIManager.Instance.OpenWindow(); } else if (waitResponse.type == HeroFuncType.Awake) { var config = HeroAwakeConfig.GetHeroAwakeConfig(hero.heroId, hero.awakeLevel); if (hero.talentAwakeRandomIDList.Count > 0) { UIManager.Instance.OpenWindow(); } else if (config.SkillID != 0 || config.UnlockTalentSlot != 0) { UIManager.Instance.OpenWindow(); } } 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.Concat("herocountry", index.ToString()); } public string GetJobIconName(int index) { return StringUtility.Concat("herojob", index.ToString()); } public int GetMaxLV(int quality) { return HeroQualityLVConfig.maxlvDic[quality]; } //是否达到最高级 public bool IsLVMax(HeroInfo hero) { return hero.heroLevel >= GetMaxLV(hero.Quality); } //突破所需等级 public int GetNeedLVByBreakLV(int quality, int breakLevel) { return HeroQualityBreakConfig.GetQualityBreakConfig(quality, breakLevel).UPLVNeed; } //是否达到可突破的条件 public bool IsCanBreak(HeroInfo hero, int showTip = 0) { if (hero.heroLevel < GetNeedLVByBreakLV(hero.Quality, hero.breakLevel)) { //等级未达标 if (showTip != 0) { SysNotifyMgr.Instance.ShowTip("HeroLVNotEnough"); } return false; } if (hero.breakLevel >= HeroBreakConfig.GetMaxBreakLv(hero.heroId)) { //突破等级已达最高级 return false; } //材料是否足够 var breakConfig = HeroQualityBreakConfig.GetQualityBreakConfig(hero.Quality, hero.breakLevel); for (int i = 0; i < breakConfig.UPCostItemList.Length; i++) { if (!ItemLogicUtility.CheckItemCount(PackType.Item, breakConfig.UPCostItemList[i][0], breakConfig.UPCostItemList[i][1], showTip)) { return false; } } return true; } public int GetAllHeroPer() { var list = HeroManager.Instance.GetHeroList(); int per = 0; foreach (var hero in list) { if (hero.isAttrActive) { per += hero.GetAddPer(); } } return per; } #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(selectHeroList); 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; } bool isActiveA = heroA.isAttrActive; bool isActiveB = heroB.isAttrActive; if (isActiveA != isActiveB) { return isActiveA ? -1 : 1; } // 排序规则:上阵>武将等级>突破等级>武将觉醒阶级>武将品质>武将吞噬星级>武将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 heroCallSortList { get; private set; } = new List(); //积分招募列表 public List selectHeroCallList = new List(); //筛选 public List newHeroIDList = new List(); //新武将列表 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); PhantasmPavilionManager.Instance.AddNewHero(heroID); } public void RemoveNewHero(int heroID) { if (!newHeroIDList.Contains(heroID)) { return; } newHeroIDList.Remove(heroID); refreshRedPoint = true; } List allHeroCallScoreList = new List(); //积分招募列表 public void SortHeroCallList() { if (allHeroCallScoreList.IsNullOrEmpty()) { allHeroCallScoreList = HappyXBModel.Instance.GetAllGridLibItemIDByType((int)HappXBTitle.HeroCallScore); } heroCallSortList = new List(); if (selectHeroCallList.IsNullOrEmpty()) { heroCallSortList = allHeroCallScoreList; } else { int job = 0; int country = 0; int hurtType = 0; int fightAttrType = 0; int specialAttrType = 0; if (!selectHeroCallList.IsNullOrEmpty()) { job = selectHeroCallList[0]; country = selectHeroCallList[1]; hurtType = selectHeroCallList[2]; fightAttrType = selectHeroCallList[3]; specialAttrType = selectHeroCallList[4]; } foreach (var item in allHeroCallScoreList) { HeroConfig heroConfig = HeroConfig.Get(item); if (heroConfig == null) { continue; } //0代表全部, 同级别是可复选,不同级别为且的关系 bool isMatch = true; if (job != 0) { isMatch = isMatch && (job & (1 << heroConfig.Class)) > 0; } if (country != 0) { isMatch = isMatch && (country & (1 << heroConfig.Country)) > 0; } if (hurtType != 0) { isMatch = isMatch && (hurtType & (1 << heroConfig.HurtType)) > 0; } if (fightAttrType != 0) { isMatch = isMatch && (fightAttrType & (1 << heroConfig.Specialty)) > 0; } if (specialAttrType != 0) { bool isMatch2 = false; for (int i = 0; i < heroConfig.Specialty2.Length; i++) { isMatch2 = (specialAttrType & (1 << heroConfig.Specialty2[i])) > 0; if (isMatch2) break; } isMatch = isMatch && isMatch2; } if (!isMatch) { 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.isAttrActive) return 0; var heroCnt = PackManager.Instance.GetItemCountByID(PackType.Hero, hero.heroId); if (!hero.IsInTeamByTeamType(TeamType.Story)) { if (hero.heroStar < hero.GetCurMaxStar() && heroCnt > 1) { return 2; } return 0; } 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 (hero.heroStar < hero.GetCurMaxStar() && heroCnt > 1) { return 2; } if (IsCanBreak(hero)) { return 3; } 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 heroOnTeamRedpointList = new List(); //上阵的武将红点 List heroBookRedpointList = new List(); //图鉴所有武将红点 //生效未上阵的 可吞噬的共用一个红点 Redpoint heroEatRedPoint = new Redpoint(MainRedDot.HeroCardRedpoint, MainRedDot.HeroCardRedpoint * 10 + 8); //新标识的红点 所有武将统一个 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; heroEatRedPoint.state = RedPointState.None; var _list = HeroManager.Instance.GetHeroList(); foreach (var hero in _list) { if (!hero.isAttrActive) { continue; } if (hero.heroStar >= hero.GetCurMaxStar()) { continue; } if (HeroManager.Instance.GetHeroCountByID(hero.heroId) > 1) { heroEatRedPoint.state = RedPointState.GetReward; break; } } } void InitHerosData() { heroBookRedpointList.Clear(); foreach (var key in HeroConfig.GetKeys()) { var config = HeroConfig.Get(key); //汇总特殊属性 if (!config.Specialty2.IsNullOrEmpty()) { foreach (var num in config.Specialty2) { if (!heroSpecialAttrsForSelect.Contains(num)) { heroSpecialAttrsForSelect.Add(num); } } } if (config.PlayerCanUse == 0) continue; //图鉴红点 heroBookRedpointList.Add(new Redpoint(MainRedDot.HeroCardCollectRedpoint, MainRedDot.HeroCardCollectRedpoint * 10000000 + key)); } heroSpecialAttrsForSelect.Sort(); } //某个武将图鉴中是否显示红点 public bool IsBookShowRedPoint(int heroID) { var state = GetHeroBookState(heroID, HeroConfig.Get(heroID).Quality); if (state == 1 || state == 3 || state == 4) { return true; } return false; } 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