| Main/Component/UI/Common/FuncOpen.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/Config/Configs/FuncOpenLVConfig.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/FunctionPreview.meta | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/FunctionPreview/FunctionPreviewCell.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/FunctionPreview/FunctionPreviewCell.cs.meta | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/FunctionPreview/FunctionPreviewWin.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/FunctionPreview/FunctionPreviewWin.cs.meta | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/Main/RightFuncInHome.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/System/Redpoint/MainRedDot.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| Main/Utility/EnumHelper.cs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
Main/Component/UI/Common/FuncOpen.cs
@@ -1,8 +1,8 @@ using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using LitJson; using System.Linq; public class FuncOpen { @@ -92,7 +92,7 @@ { for (int i = 0; i < vNetData.FuncCount; i++) { var funcState = vNetData.FuncStateList[i]; bool bPerFuncIsOpen = false; @@ -109,6 +109,10 @@ funcOpenState[funcState.FuncID] = funcState.State == 1; bAfterFuncIsOpen = funcOpenState[funcState.FuncID]; } awardStateDict[funcState.FuncID] = funcState.AwardState == 1; UpdatePreviewRedpoint(); if (OnFuncStateChangeEvent != null) { OnFuncStateChangeEvent(funcState.FuncID); @@ -118,7 +122,7 @@ private bool IsFuncOpen(int key, out int errorCode) { errorCode = 0; var config = FuncOpenLVConfig.Get(key); if (config == null) @@ -129,7 +133,7 @@ if (config.OpenDay > 0) { if (config.OpenDay > TimeUtility.OpenDay + 1) { { errorCode = 2; return false; } @@ -218,53 +222,11 @@ SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID))); break; case 5: SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_ManLevel", config.ManLevel/10000, config.ManLevel/100%100, config.ManLevel%100)); SysNotifyMgr.Instance.ShowStringTip(Language.Get("FuncLimit_ManLevel", config.ManLevel / 10000, config.ManLevel / 100 % 100, config.ManLevel % 100)); break; } } } } public string GetErrorTip(int key) { if (!FuncOpenLVConfig.HasKey(key)) return string.Empty; FuncOpenLVConfig config = FuncOpenLVConfig.Get(key); if (!IsFuncOpen(key, out int errorCode)) { switch (errorCode) { case 1: return Language.Get("FuncLimit_Level", config.LimitLV); case 2: //开服多少天 一般是组合 if (config.LimitLV != 0) { return Language.Get("FuncLimit_OpenDay_LV", config.LimitLV, TimeUtility.OpenDay + 1, config.OpenDay); } else if (config.LimitMissionID != 0) { return Language.Get("FuncLimit_OpenDay_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID), TimeUtility.OpenDay + 1, config.OpenDay); } else if (config.LimiRealmLV != 0) { return Language.Get("FuncLimit_OpenDay_Realm", RealmConfig.Get(config.LimiRealmLV).Name, TimeUtility.OpenDay + 1, config.OpenDay); } else { return Language.Get("FuncLimit_OpenDay", config.OpenDay); } case 3: return Language.Get("FuncLimit_Realm", RealmConfig.Get(config.LimiRealmLV).Name); case 4: return Language.Get("FuncLimit_Mission", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID)); case 5: return Language.Get("FuncLimit_ManLevel", config.ManLevel/10000, config.ManLevel/100%100, config.ManLevel%100); } } return string.Empty; } public int GetLimitLv(int key) @@ -300,6 +262,137 @@ } return true; } #region 功能预告 Dictionary<int, bool> awardStateDict = new Dictionary<int, bool>(); Dictionary<int, int> funcIndexDict = new Dictionary<int, int>(); public Dictionary<int, int> GetFuncIndexDict() { if (funcIndexDict.IsNullOrEmpty()) { foreach (var funcId in FuncOpenLVConfig.GetKeys()) { FuncOpenLVConfig config = FuncOpenLVConfig.Get(funcId); if (config.PreviewIndex > 0) { funcIndexDict[config.FuncId] = config.PreviewIndex; } } } return funcIndexDict; } public List<int> GetSortShowList() { List<int> sortShowList = new List<int>(); Dictionary<int, int> indexDict = GetFuncIndexDict(); // 按状态优先级排序:状态1(可领取)> 状态0(未解锁)> 状态2(已领取) // 每种状态内按 PreviewIndex 升序,相同则按 FuncId 升序 sortShowList = indexDict .Select(kv => new { FuncId = kv.Key, PreviewIndex = kv.Value, State = GetState(kv.Key) }) .OrderBy(x => x.State == 1 ? 0 : (x.State == 0 ? 1 : 2)) // 映射优先级:1→0, 0→1, 2→2 .ThenBy(x => x.PreviewIndex) .ThenBy(x => x.FuncId) .Select(x => x.FuncId) .ToList(); return sortShowList; } //第一个可领取的物品所在行索引 public bool TryGetJumpIndex(out int index) { index = 0; List<int> list = GetSortShowList(); if (list.IsNullOrEmpty()) return false; for (int i = 0; i < list.Count; i++) { if (GetState(list[i]) == 1) { index = i; return true; } } return false; } private bool IsAwardHave(int funcId) { return !awardStateDict.TryGetValue(funcId, out bool state) ? false : state; } // 0-未解锁 1-可领取 2-已领取 public int GetState(int funcId) { if (IsAwardHave(funcId)) return 2; return IsFuncOpen(funcId) ? 1 : 0; } public string GetErrorStr(int funcId) { if (!FuncOpenLVConfig.HasKey(funcId)) return string.Empty; FuncOpenLVConfig config = FuncOpenLVConfig.Get(funcId); List<string> conditionStrs = new List<string>(); if (config.LimitLV > 0) { conditionStrs.Add(Language.Get("FunctionPreviewErr01", config.LimitLV)); } if (config.LimiRealmLV > 0) { conditionStrs.Add(Language.Get("FunctionPreviewErr02", RealmConfig.Get(config.LimiRealmLV).Name)); } if (config.LimitMissionID > 0) { conditionStrs.Add(Language.Get("FunctionPreviewErr03", TaskManager.Instance.GetNeedFinishTaskCount(config.LimitMissionID))); } if (config.OpenDay > 0) { conditionStrs.Add(Language.Get("FunctionPreviewErr04", config.OpenDay)); } if (config.ManLevel > 0) { conditionStrs.Add(Language.Get("FunctionPreviewErr05", config.ManLevel / 10000, config.ManLevel / 100 % 100, config.ManLevel % 100)); } if (conditionStrs.Count == 0) { return string.Empty; } string connector = Language.Get("FunctionPreview01"); // "且" string unlockStr = Language.Get("FunctionPreview02"); // "解锁" string result = string.Join(connector, conditionStrs) + unlockStr; return result; } public void SendGetAward(int funcId) { var pack = new CA504_tagCMPlayerGetReward(); pack.RewardType = 17; pack.DataEx = (uint)funcId; GameNetSystem.Instance.SendInfo(pack); } Redpoint redpoint = new Redpoint(MainRedDot.RightFuncRedpoint, MainRedDot.FunctionPreviewRepoint); public void UpdatePreviewRedpoint() { redpoint.state = RedPointState.None; if (!TryGetJumpIndex(out int index)) return; redpoint.state = RedPointState.Simple; } #endregion } public interface ICheckFuncOpen Main/Config/Configs/FuncOpenLVConfig.cs
@@ -1,6 +1,6 @@ //-------------------------------------------------------- // [Author]: YYL // [ Date ]: Thursday, November 27, 2025 // [ Date ]: 2025年12月8日 //-------------------------------------------------------- using System.Collections.Generic; @@ -25,7 +25,8 @@ public string Name; public string Desc; public string Icon; public Dictionary<int, int[][]> Award; public int PreviewIndex; public int[][] AwardList; public override int LoadKey(string _key) { @@ -55,7 +56,9 @@ Icon = tables[8]; Award = ConfigParse.ParseIntArray2Dict(tables[9].Replace("(", "[").Replace(")", "]")); int.TryParse(tables[9],out PreviewIndex); AwardList = JsonMapper.ToObject<int[][]>(tables[10].Replace("(", "[").Replace(")", "]")); } catch (Exception exception) { Main/System/FunctionPreview.meta
New file @@ -0,0 +1,8 @@ fileFormatVersion: 2 guid: e7acf37249ff26f4f85a11d0e3e8f65a folderAsset: yes DefaultImporter: externalObjects: {} userData: assetBundleName: assetBundleVariant: Main/System/FunctionPreview/FunctionPreviewCell.cs
New file @@ -0,0 +1,53 @@ using UnityEngine; public class FunctionPreviewCell : MonoBehaviour { [SerializeField] ImageEx imgIcon; [SerializeField] TextEx txtName; [SerializeField] TextEx txtDesc; [SerializeField] ItemCell itemCell; [SerializeField] Transform transItemCellMask; [SerializeField] ImageEx imgRed; [SerializeField] Transform transOpenInfo; [SerializeField] RichText txtOpenInfo; [SerializeField] Transform transMask; public void Display(int index, CellView cell) { int funcId = cell.info.Value.infoInt1; if (!FuncOpenLVConfig.HasKey(funcId)) return; FuncOpenLVConfig config = FuncOpenLVConfig.Get(funcId); // 0-未解锁 1-可领取 2-已领取 int state = FuncOpen.Instance.GetState(funcId); imgRed.SetActive(state == 1); transOpenInfo.SetActive(state == 0); transMask.SetActive(state != 1); transItemCellMask.SetActive(state == 2); imgIcon.SetSprite(config.Icon); imgIcon.SetNativeSize(); txtName.text = config.Name; txtDesc.text = config.Desc; int[][] awardList = config.AwardList; itemCell.SetActive(!awardList.IsNullOrEmpty() && state != 0); if (!awardList.IsNullOrEmpty()) { itemCell.Init(new ItemCellModel(awardList[0][0], true, awardList[0][1])); itemCell.button.SetListener(() => { if (state == 1) { FuncOpen.Instance.SendGetAward(funcId); } else { ItemTipUtility.Show(awardList[0][0]); } }); } txtOpenInfo.text = FuncOpen.Instance.GetErrorStr(funcId); } } Main/System/FunctionPreview/FunctionPreviewCell.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: 807ec470632e30e4fbebaad0c81ba631 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/FunctionPreview/FunctionPreviewWin.cs
New file @@ -0,0 +1,48 @@ using UnityEngine; public class FunctionPreviewWin : UIBase { [SerializeField] ScrollerController scroller; protected override void OnPreOpen() { scroller.lockType = EnhanceLockType.KeepVertical; scroller.OnRefreshCell += OnRefreshCell; FuncOpen.Instance.OnFuncStateChangeEvent += OnFuncStateChangeEvent; CreateScoller(); } protected override void OnPreClose() { scroller.OnRefreshCell -= OnRefreshCell; FuncOpen.Instance.OnFuncStateChangeEvent -= OnFuncStateChangeEvent; } private void OnFuncStateChangeEvent(int obj) { CreateScoller(); } private void OnRefreshCell(ScrollerDataType type, CellView cell) { var _cell = cell.GetComponent<FunctionPreviewCell>(); _cell?.Display(cell.index, cell); } private void CreateScoller() { scroller.Refresh(); var list = FuncOpen.Instance.GetSortShowList(); if (!list.IsNullOrEmpty()) { for (int i = 0; i < list.Count; i++) { CellInfo info = new CellInfo(); info.infoInt1 = list[i]; scroller.AddCell(ScrollerDataType.Header, i, info); } } scroller.Restart(); } } Main/System/FunctionPreview/FunctionPreviewWin.cs.meta
New file @@ -0,0 +1,11 @@ fileFormatVersion: 2 guid: e7c6142d362c8194c9cbe93b1d76f904 MonoImporter: externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 icon: {instanceID: 0} userData: assetBundleName: assetBundleVariant: Main/System/Main/RightFuncInHome.cs
@@ -17,6 +17,7 @@ [SerializeField] Button battlePassBtn; [SerializeField] Button llmjBtn; //历练秘笈 [SerializeField] Button signBtn; [SerializeField] Button previewBtn; static string listenWindowName = ""; //监听关闭时再显示 @@ -79,6 +80,13 @@ ListenWindow("SignWin"); UIManager.Instance.OpenWindow<SignWin>(); }); previewBtn.AddListener(() => { //用于监听界面,打开时缩进右边功能栏,关闭时显示 ListenWindow("FunctionPreviewWin"); UIManager.Instance.OpenWindow<FunctionPreviewWin>(); }); } void ShowBtns() @@ -89,6 +97,7 @@ llmjBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.LLMJ)); signBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.DaySign)); monthCardBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.PrivilegeCard)); previewBtn.SetActive(FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.FunctionPreview)); } Main/System/Redpoint/MainRedDot.cs
@@ -131,6 +131,7 @@ public const int TianziBillboradRepoint = 471; //天子的考验 public const int PhantasmPavilionRepoint = 472; //幻境阁 public const int LineupRecommendRepoint = 473; //阵容推荐 public const int FunctionPreviewRepoint = 474; //功能预告 public void Register() { Main/Utility/EnumHelper.cs
@@ -837,6 +837,7 @@ Horse = 37, //坐骑 BattlePass = 40, //基金(战令) LLMJ = 41, //历练秘笈 FunctionPreview = 48, //功能预览 }