using Framework; using System.Collections.Generic; using System.Linq; using cfg.LevelCfg; using UnityEngine; namespace Gameplay.Level { public partial class LevelManager { private const string LAST_FIGHT_LEVEL_PREFIX = "last_fight_level_"; private Dictionary _levelDic = new(); private Dictionary _chapterInfoDic = new(); private Dictionary _levelGroupDic = new(); private readonly int[] _levelGroupTypeRedPointIDArray = new[] { 101, 102, 103 }; private Dictionary> _chapterTypeDic = new(); private void InitData() { RegisterEventData(); } private void ReleaseData() { UnregisterEventData(); DisposeRedPointTree(); _levelDic = null; _chapterInfoDic = null; _levelGroupDic = null; } private void RegisterEventData() { EventManager.Instance.Register(EventManager.EventName.AllConfigLoad, OnAllConfigLoad); EventManager.Instance.Register(EventManager.EventName.NewLevelServerData, OnNewLevelServerData); } private void UnregisterEventData() { EventManager.Instance.Unregister(EventManager.EventName.AllConfigLoad, OnAllConfigLoad); EventManager.Instance.Unregister(EventManager.EventName.NewLevelServerData, OnNewLevelServerData); } private void OnAllConfigLoad() { LoadAllLevel(); LoadAllLevelGroup(); LoadAllChapter(); InitSortIndex(); ConstructRedPointTree(); } private void LoadAllLevel() { _levelDic.Clear(); var allLevelConfig = TableManager.Instance.Tables.Level.DataList; int sortIndex = 0; foreach (var config in allLevelConfig) { var levelInfo = new LevelInfo(config); _levelDic.Add(levelInfo.ID, levelInfo); } } private void LoadAllChapter() { _chapterInfoDic.Clear(); foreach (var levelGroupInfo in _levelGroupDic.Values) { var chapterID = levelGroupInfo.ChapterID; ChapterInfo chapterInfo = null; if (!_chapterInfoDic.TryGetValue(chapterID, out chapterInfo)) { var config = TableManager.Instance.Tables.Chapter.Get(chapterID); if (config != null) { chapterInfo = new ChapterInfo(config); _chapterInfoDic.Add(chapterID, chapterInfo); } else { DebugUtil.LogError($"cant find LevelGroup config,{chapterID}"); } } if (chapterInfo != null) chapterInfo.AddLevelGroup(levelGroupInfo); } foreach (var chapterInfo in _chapterInfoDic.Values) { var chapterType = chapterInfo.ChapterType; if (!_chapterTypeDic.TryGetValue(chapterType, out var list)) { list = new(); _chapterTypeDic.Add(chapterType, list); } list.Add(chapterInfo); } } private void LoadAllLevelGroup() { _levelGroupDic.Clear(); foreach (var levelInfo in _levelDic.Values) { var levelGroupID = levelInfo.LevelGroupID; LevelGroupInfo levelGroupInfo = null; if (!_levelGroupDic.TryGetValue(levelGroupID, out levelGroupInfo)) { var config = TableManager.Instance.Tables.LevelGroupConfig.Get(levelGroupID); if (config != null) { levelGroupInfo = new LevelGroupInfo(config); _levelGroupDic.Add(levelGroupID, levelGroupInfo); } else { DebugUtil.LogError($"cant find chapter config,{levelGroupID}"); } } if (levelGroupInfo != null) levelGroupInfo.AddLevel(levelInfo); } } private void InitSortIndex() { foreach (var list in _chapterTypeDic.Values) { list.Sort((a, b) => a.ID.CompareTo(b.ID)); for (int i = 0; i < list.Count; i++) { var chapterInfo = list[i]; chapterInfo.SortIndex = i; chapterInfo.InitAllLevelSortIndex(); } } } private void ConstructRedPointTree() { foreach (var levelGroupInfo in _chapterInfoDic.Values) { var index = (int)levelGroupInfo.ChapterType; if (index < 0 || index > _levelGroupTypeRedPointIDArray.Length) { DebugUtil.LogError($"index is out of range!index:{index}"); continue; } var redPointParentID = _levelGroupTypeRedPointIDArray[index]; levelGroupInfo.ConstructRedPointTree(redPointParentID); } } private void DisposeRedPointTree() { foreach (var levelGroupInfo in _chapterInfoDic.Values) { if (levelGroupInfo.RedPointNode != null) { RedPointManager.Instance.RemoveDynamicNode(levelGroupInfo.RedPointNode); } } } private void OnNewLevelServerData(int levelID) { var levelInfo = GetLevelInfoByID(levelID); if (levelInfo != null) { levelInfo.RefreshServerData(); } } private void SaveFightLevel(LevelInfo levelInfo) { if(levelInfo == null) return; var levelGroupInfo = levelInfo.LevelGroupInfo; if(levelGroupInfo == null) return; var chapterInfo = levelGroupInfo.ChapterInfo; if(chapterInfo == null) return; PlayerPrefs.SetInt(GetChapterTypeSaveKey(chapterInfo.ChapterType), levelInfo.ID); } private string GetChapterTypeSaveKey(LevelChapterType chapterType) => LAST_FIGHT_LEVEL_PREFIX + chapterType; #region API public LevelInfo GetLevelInfoByID(int id) { if (!_levelDic.TryGetValue(id, out var levelInfo)) { DebugUtil.LogError($"找不到levelInfo,id:{id}"); } return levelInfo; } public LevelGroupInfo GetLevelGroupInfoByID(int id) { if (!_levelGroupDic.TryGetValue(id, out var chapterInfo)) { DebugUtil.LogError($"找不到chapterInfo,id:{id}"); } return chapterInfo; } public ChapterInfo GetChapterInfoByID(int id) { if (!_chapterInfoDic.TryGetValue(id, out var levelGroupInfo)) { DebugUtil.LogError($"找不到levelGroupInfo,id:{id}"); } return levelGroupInfo; } public List GetAllChapterInfo() { return _chapterInfoDic.Values.ToList(); } public List GetAllLevelInfo() { return _levelDic.Values.ToList(); } public List GetAllLevelGroupInfo() { return _levelGroupDic.Values.ToList(); } //获取某种关卡类型的最新进度 public LevelInfo GetLatestLevelInfo(LevelChapterType type) { if (_chapterTypeDic.TryGetValue(type, out var list)) { var latestChapterInfo = list.Where(chapterInfo => !chapterInfo.IsLock).ToList()[^1]; if (latestChapterInfo == null) return null; var allUnlockLevels = latestChapterInfo.AllLevelInfo.Where(level => !level.IsLock).ToList(); allUnlockLevels.Sort((a, b) => a.ID.CompareTo(b.ID)); return allUnlockLevels[^1]; } return null; } //获取某种关卡类型上一次战斗的关卡 public LevelInfo GetLastFightLevelInfo(LevelChapterType type) { var key = GetChapterTypeSaveKey(type); if (!PlayerPrefs.HasKey(key)) { return null; } var levelID = PlayerPrefs.GetInt(key); var levelInfo = GetLevelInfoByID(levelID); return levelInfo; } #endregion } }