using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; //图鉴和皮肤 public partial class HeroUIManager : GameSystemManager { public Dictionary> heroCollectDict { get; private set; } = new Dictionary>(); //武将图鉴按品质列表 public List heroCollectList = new List(); //武将图鉴列表 public List selectHeroCollectList = new List(); //武将列表界面 筛选 public int selectCollectHeroID; //选中的武将id 用于升级 public int selectForPreviewHeroID; //选中的武将id 用于预览 //图鉴和皮肤的激活情况 Dictionary heroCollectInfoDic = new Dictionary(); // public int allHeroBookPer; //全体武将的图鉴激活百分比 public event Action OnHeroCollectEvent; public event Action OnHeroSkinStateChanged;// 皮肤状态变化事件 (参数: HeroID, SkinID, 新的State) public void UpdateHeroCollectInfo(HB122_tagSCHeroInfo netPack) { for (int i = 0; i < netPack.HeroCnt; i++) { var newHeroData = netPack.HeroInfoList[i]; int heroID = (int)newHeroData.HeroID; // 1. 调用封装好的方法:检测并触发新皮肤事件 CheckAndTriggerNewSkinEvents(heroID, newHeroData); // 2. 更新字典为最新的网络包数据 heroCollectInfoDic[heroID] = newHeroData; } // allHeroBookPer = GetHeroCollectBookPer(); UpdateHeroBookRedpoint(); RefreshAllSkinAttr(); UpdateHeroCardSkinRedpoint(); UpdateHeroBookRedpoint(); OnHeroCollectEvent?.Invoke(); } public event Action OnNewSkinAcquired;// 当玩家获得新皮肤(激活皮肤)时触发的事件 HeroID SkinID /// /// 检查并触发获得新皮肤的事件 /// private void CheckAndTriggerNewSkinEvents(int heroID, HB122_tagSCHeroInfo.tagSCHero newHeroData) { // 如果新数据中没有皮肤信息,直接返回 if (newHeroData?.SkinList == null || newHeroData?.SkinCnt <= 0) return; // 尝试获取旧数据 bool isOldHeroExist = heroCollectInfoDic.TryGetValue(heroID, out var oldHeroData); for (int j = 0; j < newHeroData.SkinCnt; j++) { var newSkin = newHeroData.SkinList[j]; // 如果新皮肤未激活,直接跳过当前循环,检查下一个皮肤 if (newSkin.State <= 0) continue; bool isNewlyAcquired = false; if (!isOldHeroExist) { // 场景A:这是一个全新的武将,且自带了已激活的非默认皮肤 isNewlyAcquired = true; } else { // 场景B:已有的老武将,需要对比旧数据看这个皮肤是不是刚刚才获得的 bool foundOldSkin = false; if (oldHeroData.SkinList != null) { for (int k = 0; k < oldHeroData.SkinCnt; k++) { var oldSkin = oldHeroData.SkinList[k]; if (oldSkin.SkinID == newSkin.SkinID) { foundOldSkin = true; // 如果旧数据中该皮肤未激活 (State == 0),现在激活了,算作获得新皮肤 if (oldSkin.State == 0) { isNewlyAcquired = true; } break; } } } // 如果旧武将数据里压根没有这个皮肤的数据(现在是激活状态),也算作获得新皮肤 if (!foundOldSkin) { isNewlyAcquired = true; } } // 如果最终判定为“全新获得”的皮肤,则触发事件 if (isNewlyAcquired) { OnNewSkinAcquired?.Invoke(heroID, (int)newSkin.SkinID); } } } // public int GetHeroCollectBookPer() // { // int per = 0; // foreach (var kv in heroCollectInfoDic) // { // var config = HeroQualityConfig.Get(HeroConfig.Get(kv.Key).Quality); // if (kv.Value.BookInitState != 2) // continue; // per += config.BookInitAddPer; // per += kv.Value.BookStarLV * config.BookStarAddPer; // per += kv.Value.BookBreakLV * config.BookBreakLVAddPer; // } // return per; // } public bool TryGetHeroBookInfo(int heroID, out HB122_tagSCHeroInfo.tagSCHero heroData) { if (heroCollectInfoDic.ContainsKey(heroID)) { heroData = heroCollectInfoDic[heroID]; return true; } heroData = new HB122_tagSCHeroInfo.tagSCHero(); return false; } public void SortHeroCollectList() { var heroIDs = HeroConfig.GetKeys().ToList(); int job = 0; int country = 0; int hurtType = 0; int fightAttrType = 0; int specialAttrType = 0; if (!selectHeroCollectList.IsNullOrEmpty()) { job = selectHeroCollectList[0]; country = selectHeroCollectList[1]; hurtType = selectHeroCollectList[2]; fightAttrType = selectHeroCollectList[3]; specialAttrType = selectHeroCollectList[4]; } heroCollectDict.Clear(); foreach (var heroID in heroIDs) { HeroConfig heroConfig = HeroConfig.Get(heroID); if (heroConfig.PlayerCanUse == 0) continue; // 开服第x天显示图鉴,0表示不限制开服天 if (HasOpenCollectionDayLimit(heroID) && !IsOpenCollectionDayMet(heroID)) continue; if (!heroCollectDict.ContainsKey(heroConfig.Quality)) { heroCollectDict[heroConfig.Quality] = new List(); } //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; } heroCollectDict[heroConfig.Quality].Add(heroID); } heroCollectList.Clear(); //按品质倒序加入 var _list = heroCollectDict.Keys.ToList(); _list.Reverse(); foreach (var quality in _list) { // 排序逻辑:优先按阵营分组排序,同阵营中按开服天数降序排序,最后按武将ID排序 heroCollectDict[quality].Sort((a, b) => { var cfgA = HeroConfig.Get(a); var cfgB = HeroConfig.Get(b); // 1. 按阵营(国家)排序 if (cfgA.Country != cfgB.Country) { return cfgA.Country.CompareTo(cfgB.Country); } // 2. 同阵营中,开服天数越大的排序越靠前 (降序) if (cfgA.OpenCollectionDay != cfgB.OpenCollectionDay) { return cfgB.OpenCollectionDay.CompareTo(cfgA.OpenCollectionDay); } // 3. 其他条件一致时,默认按武将ID升序 return a.CompareTo(b); }); heroCollectList.AddRange(heroCollectDict[quality]); } } //分为0未获得、1可激活、2常规、(3突破升级、4、星升级、5已满级 废弃功能保留逻辑) public int GetHeroBookState(int heroID, int quality) { int funcState = 0; HB122_tagSCHeroInfo.tagSCHero colData; TryGetHeroBookInfo(heroID, out colData); if (colData.BookInitState == 0) { funcState = 0; } else if (colData.BookInitState == 1) { funcState = 1; } else { funcState = 2; } // else if (colData.BookInitState == 2) // { // if (GetHeroBookMaxLevel(heroID, quality) == colData.BookBreakLV + colData.BookStarLV) // { // funcState = 5; // } // else if (maxBreakLV + maxStarLV == colData.BookBreakLV + colData.BookStarLV) // { // funcState = 2; // } // else // { // //优先突破升级 // if (colData.BookBreakLV < colData.BookBreakLVH) // { // funcState = 3; // } // else // { // funcState = 4; // } // } // } return funcState; } //找到可以操作的图鉴武将 public int FindHeroIDCanAddCollectAttr(int excludeHeroID = 0) { foreach (var kv in heroCollectInfoDic) { if (kv.Key == excludeHeroID) continue; var state = GetHeroBookState(kv.Key, HeroConfig.Get(kv.Key).Quality); if (state == 1 || state == 3 || state == 4) { return kv.Key; } } return 0; } // public int GetHeroBookPer(int heroID) // { // var config = HeroQualityConfig.Get(HeroConfig.Get(heroID).Quality); // HB122_tagSCHeroInfo.tagSCHero heroData; // TryGetHeroBookInfo(heroID, out heroData); // if (heroData.BookInitState < 2) // { // return 0; // } // return config.BookInitAddPer + heroData.BookStarLV * config.BookStarAddPer + heroData.BookBreakLV * config.BookBreakLVAddPer; // } #region 皮肤 //策划去除了升星功能 //属性分穿戴(武将个体)和全体 public Dictionary allSkinAttrDic = new Dictionary(); int m_selectSkinIndex = -1; public event Action OnSkinIndexChanged; public int selectSkinIndex { get { return m_selectSkinIndex; } set { m_selectSkinIndex = value; OnSkinIndexChanged?.Invoke(); } } //全体属性 public void RefreshAllSkinAttr() { allSkinAttrDic.Clear(); foreach (var config in HeroSkinAttrConfig.GetValues()) { var heroID = HeroConfig.GetHeroIDBySkinID(config.SkinID); if (heroID == 0) { Debug.LogError("不存在的皮肤 皮肤属性表配置错误 :" + config.SkinID); continue; } if (!IsHeroSkinActive(heroID, config.SkinID)) { continue; } for (int i = 0; i < config.RoleAttrIDList.Length; i++) { if (!allSkinAttrDic.ContainsKey(config.RoleAttrIDList[i])) { allSkinAttrDic[config.RoleAttrIDList[i]] = 0; } allSkinAttrDic[config.RoleAttrIDList[i]] += config.RoleAttrValueList[i]; } } } public bool IsHeroSkinActive(int heroID, int skinID) { //默认皮肤返回true if (HeroConfig.Get(heroID).SkinIDList[0] == skinID) { return true; } HB122_tagSCHeroInfo.tagSCHero colData; TryGetHeroBookInfo(heroID, out colData); if (colData != null && colData.SkinList != null) { foreach (var data in colData.SkinList) { if (data.SkinID != skinID) { continue; } return data.State == 1; } } return false; } public long GetSkinAttrValue(int attrID) { allSkinAttrDic.TryGetValue(attrID, out long value); return value; } public int GetSkinAttrPer(int attrID) { if (PlayerPropertyConfig.baseAttr2perDict.ContainsKey(attrID)) { var pertype = PlayerPropertyConfig.baseAttr2perDict[attrID]; allSkinAttrDic.TryGetValue(pertype, out long value); return (int)(value); } return 0; } //操作 1-激活;2-选择形象;4-选择属性 public void SendSkinOP(int heroID, int skinID, int opType, int itemIndex = 0) { var pack = new CB236_tagCSHeroSkinOP(); pack.HeroID = (uint)heroID; pack.SkinID = (uint)skinID; pack.OPType = (byte)opType; pack.ItemIndex = (ushort)itemIndex; GameNetSystem.Instance.SendInfo(pack); } #region 开服天数相关方法 /// /// 检查武将是否配置了开服展示天数限制 /// /// 武将ID /// true: 有开服天限制; false: 无限制(OpenCollectionDay==0 或配置不存在) public static bool HasOpenCollectionDayLimit(int heroID) { HeroConfig heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return false; return heroConfig.OpenCollectionDay > 0; } /// /// 检查武将是否已满足开服展示天数要求(仅在有限制时调用有意义) /// /// 武将ID /// true: 已满足展示天数; false: 尚未满足 public static bool IsOpenCollectionDayMet(int heroID) { HeroConfig heroConfig = HeroConfig.Get(heroID); if (heroConfig == null) return false; // OpenCollectionDay==0 无限制,视为已满足 if (heroConfig.OpenCollectionDay <= 0) return true; return TimeUtility.OpenDay + 1 >= heroConfig.OpenCollectionDay; } /// /// 检查羁绊组合中所有武将是否都满足开服展示天数 /// 只有配置了开服天限制的武将才需要检查,未配置限制的武将视为满足 /// /// 羁绊配置 /// true: 所有武将都满足; false: 有武将不满足 public static bool IsFetterAllHeroOpen(HeroFetterConfig fetterConfig) { for (int i = 0; i < fetterConfig.HeroIDList.Length; i++) { int heroID = fetterConfig.HeroIDList[i]; // 有限制但未满足 -> 该羁绊不可显示 if (HasOpenCollectionDayLimit(heroID) && !IsOpenCollectionDayMet(heroID)) return false; } return true; } #endregion #endregion }