using System; using System.Collections.Generic; using UnityEngine; using Cysharp.Threading.Tasks; public partial class PhantasmPavilionManager : GameSystemManager { public event Action OnShowItemListChange; private PhantasmPavilionType m_nowType; public PhantasmPavilionType nowType { get { return m_nowType; } set { if (m_nowType == value) return; m_nowType = value; OnShowItemListChange?.Invoke(value); } } public event Action OnSelectItemIdChange; private int m_selectId; public int selectId { get { return m_selectId; } set { if (m_selectId == value) return; m_selectId = value; RemoveNewHero(nowType, value); OnSelectItemIdChange?.Invoke(value); } } //<类型,> public Dictionary> dataDict = new Dictionary>(); public event Action OnUpdateModelInfoEvent; public event Action OnUpdateFacePicInfo; public event Action OnUpdateChatBoxInfoEvent; public event Action OnUpdateTitleInfoEvent; public event Action OnUpdateFaceInfoEvent; public event Action OnTimeOut; public override void Init() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin += OnBeforePlayerDataInitializeEventOnRelogin; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent += OnPlayerLoginOk; PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefreshEvent; PackManager.Instance.RefreshItemEvent += OnRefreshItemEvent; GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; HeroUIManager.Instance.OnNewSkinAcquired += OnNewSkinAcquired; TimeMgr.Instance.OnDayEvent += OnDayEvent; InitTable(); InitTabRedPoint(); } public override void Release() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEventOnRelogin -= OnBeforePlayerDataInitializeEventOnRelogin; DTC0403_tagPlayerLoginLoadOK.playerLoginOkEvent -= OnPlayerLoginOk; PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefreshEvent; PackManager.Instance.RefreshItemEvent -= OnRefreshItemEvent; GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; HeroUIManager.Instance.OnNewSkinAcquired -= OnNewSkinAcquired; TimeMgr.Instance.OnDayEvent -= OnDayEvent; } private void OnDayEvent() { UpdateRedPoint(); } private void OnNewSkinAcquired(int arg1, int arg2) { AddNewSkin(arg2); UpdateRedPoint(); } private void OnFuncStateChangeEvent(int obj) { if (obj == funcId) { UpdateRedPoint(); } } private void OnSecondEvent() { CheckTimeOut(); } private void OnRefreshItemEvent(PackType type, int index, int itemID) { if (type != PackType.Item) return; var map = GetUpdateRedPointItemSet(); if (!map.Contains(itemID)) return; UpdateRedPoint(); } private void OnPlayerLoginOk() { InitNowIDDict(); LoadLocal(); RefreshAttr(); UpdateRedPoint(); } public void OnBeforePlayerDataInitializeEventOnRelogin() { dataDict.Clear(); nowIDDict.Clear(); } private void OnPlayerDataRefreshEvent(PlayerDataType type) { UpdateNowIDDict(type); } public int GetJumpIndex(PhantasmPavilionType type, int tabType = 0) { if (!TryGetRowCountMax(type, out int rowCountMax) || type != nowType) return 0; int id = selectId; List list = ShowItemList(type, tabType, isSort: true); if (list.IsNullOrEmpty() || !list.Contains(id)) return 0; int index = list.IndexOf(id); int rowCount = (int)Math.Ceiling((double)index / rowCountMax); return Mathf.Max(0, rowCount - 1); } public void SetSelectItemId(PhantasmPavilionType type, int tabType = 0) { List list = new List(); switch (type) { case PhantasmPavilionType.Model: list = ModelConfig.GetTabTypeTitles(tabType); break; case PhantasmPavilionType.Title: list = TitleConfig.GetTabTypeTitles(tabType); break; default: list = GetTableKeys(type); break; } if (list.IsNullOrEmpty() || !TryGetNowShowID(type, out int nowShowID)) return; int id = nowShowID; if (list.Contains(id)) { selectId = id; return; } foreach (var key in list) { bool isUnlock = IsUnlock(type, key); if (isUnlock) { selectId = key; return; } } selectId = list[0]; } // 检查是否满足“通过道具升级”的条件 public bool CheckCanUpByItem(PhantasmPavilionType type, int id) { bool isUnlock = IsUnlock(type, id); bool isCanStarAdd = HasStarAddAttr(type, id); bool isStarMax = IsStarMax(type, id); int unlockWay = GetUnlockWay(type, id); int unlockValue = GetUnlockValue(type, id); if (!isUnlock || !isCanStarAdd || isStarMax || unlockWay != 2) return false; int itemId = unlockValue; // 道具配置不存在 if (!ItemConfig.HasKey(itemId)) return false; ItemConfig itemConfig = ItemConfig.Get(itemId); // 玩家等级不足 if (itemConfig.UseLV > PlayerDatas.Instance.baseData.LV) return false; // 道具数量不足 var hasCnt = PackManager.Instance.GetItemCountByID(PackType.Item, itemId); int upNeedCnt = GetUpNeedCnt(type, id); if (hasCnt < upNeedCnt) return false; return true; } public async UniTask ShowFace(ImageEx imgFace, UIEffectPlayer spine, UIFrame uiFrame, EllipseMask ellipseMask, int id) { PhantasmPavilionType type = PhantasmPavilionType.Face; int UnlockWay = GetUnlockWay(type, id); int unlockValue = GetUnlockValue(type, id); int resourceType = GetResourceType(type, id); string resourceValue = GetResourceValue(type, id); if ((UnlockWay == 3 || UnlockWay == 4 || UnlockWay == 5) && resourceValue == "") { int skinID = 0; if (UnlockWay == 3) { int heroID = unlockValue; if (!HeroConfig.HasKey(heroID)) return; skinID = HeroConfig.Get(heroID).SkinIDList[0]; } else if (UnlockWay == 4) { skinID = unlockValue; // UnlockValue 直接就是 skinID } else if (UnlockWay == 5) { int modelID = unlockValue; // UnlockValue 是 ModelID if (!ModelConfig.HasKey(modelID)) return; skinID = ModelConfig.Get(modelID).SkinID; // 拿到形象对应的皮肤ID } if (!HeroSkinConfig.HasKey(skinID)) return; HeroSkinConfig skinConfig = HeroSkinConfig.Get(skinID); var sprite = await UILoader.LoadSpriteAsync("HeroHead", skinConfig.SquareIcon); if (sprite == null) { Show(type, imgFace, spine, uiFrame, resourceType, "herohead_default", null, ellipseMask); } else { Show(type, imgFace, spine, uiFrame, resourceType, string.Empty, sprite, ellipseMask); } } else { resourceValue = GetResourceValue(type, id); Show(type, imgFace, spine, uiFrame, resourceType, resourceValue, null, ellipseMask); } } public async UniTask ShowFaceAsync(ImageEx imgFace, UIEffectPlayer spine, UIFrame uiFrame, EllipseMask ellipseMask, int id) { PhantasmPavilionType type = PhantasmPavilionType.Face; int UnlockWay = GetUnlockWay(type, id); int unlockValue = GetUnlockValue(type, id); int resourceType = GetResourceType(type, id); string resourceValue = GetResourceValue(type, id); if (UnlockWay == 3 && resourceValue == "") { int heroID = unlockValue; if (!HeroConfig.HasKey(heroID)) return; HeroConfig heroConfig = HeroConfig.Get(heroID); int skinID = heroConfig.SkinIDList[0]; if (!HeroSkinConfig.HasKey(skinID)) return; HeroSkinConfig skinConfig = HeroSkinConfig.Get(skinID); var sprite = await UILoader.LoadSpriteAsync("HeroHead", skinConfig.SquareIcon); if (sprite == null) { Show(type, imgFace, spine, uiFrame, resourceType, "herohead_default", null, ellipseMask); } else { Show(type, imgFace, spine, uiFrame, resourceType, string.Empty, sprite, ellipseMask); } } else { resourceValue = GetResourceValue(type, id); Show(type, imgFace, spine, uiFrame, resourceType, resourceValue, null, ellipseMask); } } public void Show(PhantasmPavilionType type, ImageEx imgFace, UIEffectPlayer spine, UIFrame uiFrame, int resourceType, string resourceValue, Sprite sprite = null, EllipseMask ellipseMask = null) { spine.Stop(); switch (resourceType) { // 静态图 case 1: imgFace.enabled = true; spine.enabled = false; uiFrame.enabled = false; if (sprite == null) { if (!IconConfig.HasKey(resourceValue)) return; imgFace.SetSprite(resourceValue); } else { imgFace.overrideSprite = sprite; } if (type == PhantasmPavilionType.Title) { imgFace.SetNativeSize(); } break; case 2: // spine imgFace.enabled = false; uiFrame.enabled = false; spine.enabled = true; imgFace.sprite = null; imgFace.overrideSprite = null; spine.effectId = int.Parse(resourceValue); spine.isPlaySpineLoop = true; spine.Play(); break; // 序列帧 case 3: imgFace.enabled = true; spine.enabled = false; uiFrame.enabled = true; imgFace.sprite = null; imgFace.overrideSprite = null; if (type == PhantasmPavilionType.Title) { if (!UIFrameMgr.Inst.ContainsDynamicImage(resourceValue)) break; List spriteList = UIFrameMgr.Inst.GetDynamicImage(resourceValue); if (!spriteList.IsNullOrEmpty()) { imgFace.rectTransform.sizeDelta = new Vector2(spriteList[0].rect.width, spriteList[0].rect.height); } } uiFrame.ResetFrame(resourceValue); uiFrame.enabled = true; break; } if (ellipseMask != null) { ellipseMask.UpdateChildrenStencil(); } } public void ShowChatBox(ImageEx imgFace, UIFrame uiFrame, int resourceType, string resourceValue) { switch (resourceType) { // 静态图 case 1: imgFace.enabled = true; uiFrame.enabled = false; if (!IconConfig.HasKey(resourceValue)) return; imgFace.SetSprite(resourceValue); break; // 序列帧 case 3: imgFace.enabled = true; uiFrame.enabled = true; imgFace.sprite = null; imgFace.overrideSprite = null; if (!UIFrameMgr.Inst.ContainsDynamicImage(resourceValue)) break; uiFrame.ResetFrame(resourceValue); uiFrame.enabled = true; break; } } public bool TryGetInfo(PhantasmPavilionType type, int id, out PhantasmPavilionData info) { info = null; return dataDict.TryGetValue(type, out var dict) && dict.TryGetValue(id, out info); } // 有没有属性 public bool HasInitAttr(PhantasmPavilionType type, int id) { if (type == PhantasmPavilionType.Title) { //称号有特殊天赋效果 var cfg = TitleConfig.Get(id); if (cfg == null) { Debug.LogError($"TitleConfig.Get(id) is null, id: {id}"); return false; } if (cfg.EffType > 0) return true; } if (!Has(type, id)) return false; int[] attrIDList = GetAttrIDList(type, id); int[] initAttrValueList = GetInitAttrValueList(type, id); if (attrIDList.IsNullOrEmpty() || initAttrValueList.IsNullOrEmpty() || attrIDList.Length != initAttrValueList.Length) return false; return true; } //是否已经升满星 public bool IsStarMax(PhantasmPavilionType type, int id) { if (!HasStarAddAttr(type, id)) return false; if (!TryGetInfo(type, id, out PhantasmPavilionData info)) return false; int starMax = GetStarMax(type, id); return info.Star >= starMax; } // 是否可升星 public bool HasStarAddAttr(PhantasmPavilionType type, int id) { if (!Has(type, id)) return false; if (!HasInitAttr(type, id)) return false; int[] initAttrValueList = GetInitAttrValueList(type, id); int[] AttrPerStarAddList = GetAttrPerStarAddList(type, id); if (initAttrValueList.IsNullOrEmpty() || AttrPerStarAddList.IsNullOrEmpty() || initAttrValueList.Length != AttrPerStarAddList.Length) return false; return true; } public bool IsUsing(PhantasmPavilionType type, int id) { if (!Has(type, id)) return false; if (!TryGetNowShowID(type, out int result)) return false; return result == id; } public List ShowItemList(PhantasmPavilionType type, int tabType = 0, bool isSort = false) { List resList = new List(); switch (type) { case PhantasmPavilionType.Model: resList = ModelConfig.GetTabTypeTitles(tabType); break; case PhantasmPavilionType.Title: resList = TitleConfig.GetTabTypeTitles(tabType); break; default: resList = GetTableKeys(type); break; } if (isSort) { resList.Sort((int a, int b) => Cmp(a, b, type)); } return resList; } public int Cmp(int a, int b, PhantasmPavilionType type) { // 1. 获取 a 和 b 的解锁状态 int stateA = (int)GetUnLockState(type, a); int stateB = (int)GetUnLockState(type, b); // 将状态重新定义为优先级排序数值:已激活(2) > 可激活(1) > 未激活(0) int priorityA = stateA == 2 ? 0 : (stateA == 1 ? 1 : 2); int priorityB = stateB == 2 ? 0 : (stateB == 1 ? 1 : 2); // 优先判断状态 if (priorityA != priorityB) { return priorityA.CompareTo(priorityB); } // 2. 状态相同的话,获取两者的 SortIndex int sortIndexA = GetSortIndex(type, a); int sortIndexB = GetSortIndex(type, b); if (sortIndexA != sortIndexB) { return sortIndexA.CompareTo(sortIndexB); } // 3. 状态和 SortIndex 都相同的话,按唯一 ID 排序 return a.CompareTo(b); } public bool TryGetLimitTimeShow(PhantasmPavilionType type, int id, out int remainingSeconds) { remainingSeconds = 0; if (!Has(type, id)) return false; if (!IsLimitTime(type, id)) return false; if (!IsUnlock(type, id)) return false; if (!TryGetInfo(type, id, out var info)) return false; DateTime endDateTime = TimeUtility.GetTime(info.EndTime); TimeSpan remainingTime = endDateTime - TimeUtility.ServerNow; remainingSeconds = (int)remainingTime.TotalSeconds; return remainingSeconds > 0; } // 除道具解锁外,其他方式暂默认永久 // 是否有时效 true 有时间限制 false 永久(无时间限制) public bool IsLimitTime(PhantasmPavilionType type, int id) { if (!Has(type, id)) return false; // 如果不是“道具解锁”方式,也视为永久 if (GetUnlockWay(type, id) != (int)PhantasmPavilionUnlockWay.Item) return false; // 物品存在且是“道具解锁”,取决于有效期 int expireMinutes = GetExpireMinutes(type, id); return expireMinutes > 0; } //物品是否已过期 private bool IsExpired(PhantasmPavilionData info, PhantasmPavilionUnlockWay unlockWay) { // 只有“道具”方式才需要检查时效,武将解锁(Hero) 或 默认(Activate) 视为永久 if (unlockWay != PhantasmPavilionUnlockWay.Item) return false; // EndTime == 0 表示永久 bool isLimitedTime = info.EndTime > 0; if (!isLimitedTime) return false; // 是限时道具,检查当前时间是否已经超过了截止时间 bool timeHasPassed = info.EndTime < TimeUtility.AllSeconds; return timeHasPassed; } // 除道具解锁外,其他方式暂默认永久 // 1 - 默认解锁,即创角就可用的 // 2 - 道具解锁,支持时效、升级, Value配物品ID public bool IsUnlock(PhantasmPavilionType type, int id) { if (!Has(type, id)) return false; int unlockWayValue = GetUnlockWay(type, id); int unlockValue = GetUnlockValue(type, id); if (unlockWayValue == 1) return true; // 1 - 默认解锁 if (unlockWayValue == 2) // 2 - 道具解锁 { if (!TryGetInfo(type, id, out var info)) return false; if (!info.State) return false; if (IsExpired(info, PhantasmPavilionUnlockWay.Item)) return false; return true; } // 3、4、5及以上全部交给分发函数按表格类型独立处理 return CheckTableSpecificUnlock(type, unlockWayValue, unlockValue); } public PhantasmPavilionState GetUnLockState(PhantasmPavilionType type, int id) { if (!Has(type, id)) return PhantasmPavilionState.Locked; // 如果已经满足解锁条件,直接返回 Activated if (IsUnlock(type, id)) return PhantasmPavilionState.Activated; int unlockWayValue = GetUnlockWay(type, id); int unlockValue = GetUnlockValue(type, id); // 只有道具解锁(2)存在"未激活但材料足够"的特有中间状态 if (unlockWayValue == 2) { return CheckCanActivateByItem(type, id, unlockValue) ? PhantasmPavilionState.CanActivate : PhantasmPavilionState.Locked; } // 其他关联解锁如果不满足 IsUnlock,则必定是 Locked 状态 return PhantasmPavilionState.Locked; } // 检查是否满足“通过道具激活”的条件 private bool CheckCanActivateByItem(PhantasmPavilionType type, int id, int itemId) { // 道具配置不存在 if (!ItemConfig.HasKey(itemId)) return false; ItemConfig itemConfig = ItemConfig.Get(itemId); // 玩家等级不足 if (itemConfig.UseLV > PlayerDatas.Instance.baseData.LV) return false; // 道具数量不足 var hasCnt = PackManager.Instance.GetItemCountByID(PackType.Item, itemId); int unlockNeedCnt = GetUnlockNeedCnt(type, id); if (hasCnt < unlockNeedCnt) return false; return true; } /// /// 根据所属表格(Type)解析 UnlockWay 的特定含义并判断是否满足条件 (排除 UnlockWay 1 和 2) /// public bool CheckTableSpecificUnlock(PhantasmPavilionType type, int unlockWay, int unlockValue) { switch (type) { case PhantasmPavilionType.Face: // 头像表独有的 UnlockWay 解析规则 if (unlockWay == 3) return HeroManager.Instance.HasHero(unlockValue); if (unlockWay == 4) return HeroUIManager.Instance.IsHeroSkinActive(HeroConfig.GetHeroIDBySkinID(unlockValue), unlockValue); if (unlockWay == 5) return IsUnlock(PhantasmPavilionType.Model, unlockValue); // 关联形象 break; case PhantasmPavilionType.FacePic: case PhantasmPavilionType.ChatBox: case PhantasmPavilionType.Title: case PhantasmPavilionType.Model: // 其他表目前的共有解析规则 if (unlockWay == 3) return HeroManager.Instance.HasHero(unlockValue); if (unlockWay == 4) return HeroUIManager.Instance.IsHeroSkinActive(HeroConfig.GetHeroIDBySkinID(unlockValue), unlockValue); break; } return false; } public void CheckTimeOut() { bool isTimeOut = false; var expiredItems = new Dictionary>(); if (dataDict.IsNullOrEmpty()) return; // 单次遍历:检查限时物品并收集过期项目 foreach (var kv in dataDict) { var type = kv.Key; var dict = kv.Value; foreach (var kv2 in dict) { var id = kv2.Key; var data = kv2.Value; // 只检查限时物品 if (!IsLimitTime(type, id)) continue; int unlockWay = GetUnlockWay(type, id); bool isExpired = IsExpired(data, (PhantasmPavilionUnlockWay)unlockWay); if (isExpired) { isTimeOut = true; if (!expiredItems.ContainsKey(type)) { expiredItems[type] = new List(); } if (!expiredItems[type].Contains(id)) { expiredItems[type].Add(id); } } } } // 如果没有过期物品,直接返回 if (!isTimeOut) return; // 从dataDict中移除过期的项目 if (!expiredItems.IsNullOrEmpty()) { foreach (var kv in expiredItems) { var type = kv.Key; var list = kv.Value; if (dataDict.ContainsKey(type)) { foreach (var id in list) { dataDict[type].Remove(id); } } } } RefreshAttr(); UpdateRedPoint(); OnTimeOut?.Invoke(); } /// /// 判断该形象/头像是否可以显示在幻境阁列表中 /// public bool IsFaceOrModelVisible(int unlockWay, int unlockValue) { if (unlockWay == 3) { int heroId = unlockValue; return IsHeroCollectionOpen(heroId); } else if (unlockWay == 4) { // 皮肤途径,UnlockValue 是 SkinID int skinId = unlockValue; return IsHeroCollectionOpen(HeroConfig.GetHeroIDBySkinID(skinId)); } // 其他获取途径(如活动、默认等),不做限制,直接显示 return true; } /// /// 检查对应武将是否达到了开服天数要求 /// public bool IsHeroCollectionOpen(int heroId) { var config = HeroConfig.Get(heroId); if (config == null) return false; // 0表示不限制开服天数 if (config.OpenCollectionDay > 0 && TimeUtility.OpenDay + 1 < config.OpenCollectionDay) return false; return true; } #region 收封包 public event Action OnUpdateModelStarAdd; public void UpdateModelInfo(HB119_tagSCModelInfo vNetData) { if (vNetData == null) return; PhantasmPavilionType type = PhantasmPavilionType.Model; if (!dataDict.ContainsKey(type)) { dataDict.Add(type, new Dictionary()); } // 判断当前封包是否有任何一项的星级大于之前的星级 bool hasStarIncreased = false; foreach (var item in vNetData.ModelList) { if (dataDict[type].ContainsKey((int)item.ModelID)) { var oldData = dataDict[type][(int)item.ModelID]; if (item.Star > oldData.Star) { hasStarIncreased = true; break; } } } foreach (var item in vNetData.ModelList) { if (!dataDict[type].ContainsKey((int)item.ModelID)) { dataDict[type][(int)item.ModelID] = new PhantasmPavilionData(); } var data = dataDict[type][(int)item.ModelID]; data.ID = item.ModelID; data.State = item.State == 1; data.EndTime = item.EndTime; data.Star = item.Star; } RefreshAttr(); UpdateRedPoint(); if (hasStarIncreased) { OnUpdateModelStarAdd?.Invoke(); } OnUpdateModelInfoEvent?.Invoke(); } public void UpdateTitleInfo(HB126_tagSCTitleInfo vNetData) { if (vNetData == null) return; PhantasmPavilionType type = PhantasmPavilionType.Title; if (!dataDict.ContainsKey(type)) { dataDict.Add(type, new Dictionary()); } foreach (var item in vNetData.TitleList) { if (!dataDict[type].ContainsKey((int)item.TitleID)) { dataDict[type][(int)item.TitleID] = new PhantasmPavilionData(); } var data = dataDict[type][(int)item.TitleID]; data.ID = item.TitleID; data.State = item.State == 1; data.EndTime = item.EndTime; data.Star = item.Star; } RefreshAttr(); UpdateRedPoint(); OnUpdateTitleInfoEvent?.Invoke(); } public void UpdateChatBoxInfo(HB127_tagSCChatBoxInfo vNetData) { if (vNetData == null) return; PhantasmPavilionType type = PhantasmPavilionType.ChatBox; if (!dataDict.ContainsKey(type)) { dataDict.Add(type, new Dictionary()); } foreach (var item in vNetData.BoxList) { if (!dataDict[type].ContainsKey((int)item.BoxID)) { dataDict[type][(int)item.BoxID] = new PhantasmPavilionData(); } var data = dataDict[type][(int)item.BoxID]; data.ID = item.BoxID; data.State = item.State == 1; data.EndTime = item.EndTime; data.Star = item.Star; } RefreshAttr(); UpdateRedPoint(); OnUpdateChatBoxInfoEvent?.Invoke(); } public void UpdateFaceInfo(HB117_tagMCFaceInfo vNetData) { if (vNetData == null) return; PhantasmPavilionType type = PhantasmPavilionType.Face; if (!dataDict.ContainsKey(type)) { dataDict.Add(type, new Dictionary()); } foreach (var item in vNetData.FaceList) { if (!dataDict[type].ContainsKey((int)item.FaceID)) { dataDict[type][(int)item.FaceID] = new PhantasmPavilionData(); } var data = dataDict[type][(int)item.FaceID]; data.ID = item.FaceID; data.State = item.State == 1; data.EndTime = item.EndTime; data.Star = item.Star; } RefreshAttr(); UpdateRedPoint(); OnUpdateFaceInfoEvent?.Invoke(); } public void UpdateFacePicInfo(HB118_tagMCFacePicInfo vNetData) { if (vNetData == null) return; PhantasmPavilionType type = PhantasmPavilionType.FacePic; if (!dataDict.ContainsKey(type)) { dataDict.Add(type, new Dictionary()); } foreach (var item in vNetData.FacePicList) { if (!dataDict[type].ContainsKey((int)item.FacePicID)) { dataDict[type][(int)item.FacePicID] = new PhantasmPavilionData(); } var data = dataDict[type][(int)item.FacePicID]; data.ID = item.FacePicID; data.State = item.State == 1; data.EndTime = item.EndTime; data.Star = item.Star; } RefreshAttr(); UpdateRedPoint(); OnUpdateFacePicInfo?.Invoke(); } #endregion public void SendOPPack(PhantasmPavilionType type, PhantasmPavilionOperation op, uint opID) { SendB225Pack((byte)type, (byte)op, opID); } public void SendB225Pack(byte type, byte opType, uint opID) { var pack = new CB225_tagCSHJGOP(); pack.Type = type; // 类型 1-形象;2-头像;3-头像框;4-气泡;5-称号 pack.OPType = opType; // 操作 1-激活;2-佩戴;3-卸下;4-升星 pack.OPID = opID; // 操作对应的ID,如形象ID等 GameNetSystem.Instance.SendInfo(pack); } } public class PhantasmPavilionData { public uint ID; //ID public bool State; //是否已激活 public uint EndTime; //到期时间戳,0为永久 public byte Star; //星级 } //对应发包 1-形象;2-头像;3-头像框;4-气泡;5-称号 public enum PhantasmPavilionType { Model = 1, // 形象 Face, // 头像 FacePic, // 头像框 ChatBox, // 聊天气泡 Title, //称号 } //对应发包 1-激活;2-佩戴;3-卸下;4-升星 public enum PhantasmPavilionOperation { Activate = 1, // 激活 Wear, // 佩戴 Remove, // 卸下 UpgradeStar, // 升星 } public enum PhantasmPavilionUnlockWay { Activate = 1, // 默认(创角色就可以用的) Item, // 道具 Hero, // 武将 Skin, // 皮肤 Model, // 形象 } /// 幻境阁物品的状态 public enum PhantasmPavilionState { // 未激活 (0) Locked = 0, // 可激活 (1) - 满足激活条件,但尚未激活 CanActivate = 1, //已激活 (2) - 已激活且未过期 Activated = 2 }