393 lines
13 KiB
C#
393 lines
13 KiB
C#
using Framework;
|
||
using System.Collections.Generic;
|
||
using cfg;
|
||
using cfg.LevelCfg;
|
||
using UnityEngine;
|
||
|
||
namespace Gameplay.Level
|
||
{
|
||
/// <summary>
|
||
/// 关卡管理器
|
||
/// </summary>
|
||
public partial class LevelManager
|
||
{
|
||
private const string LAST_FIGHT_LEVEL_PREFIX = "last_fight_level_";
|
||
|
||
/// <summary>
|
||
/// 关卡信息字典
|
||
/// </summary>
|
||
private Dictionary<int, LevelInfo> dicLevelInfo = new();
|
||
/// <summary>
|
||
/// 章节信息字典
|
||
/// </summary>
|
||
private Dictionary<int, ChapterInfo> dicChapterInfo = new();
|
||
/// <summary>
|
||
/// 关卡组信息字典,key:关卡组id,value:关卡组信息
|
||
/// </summary>
|
||
private Dictionary<int, LevelGroupInfo> dicLevelGroupInfo = new();
|
||
/// <summary>
|
||
/// 关卡组红点id
|
||
/// </summary>
|
||
private readonly int[] levelGroupRedPointIDs = new[] { 101, 102, 103, 104 };
|
||
/// <summary>
|
||
/// 章节类型字典
|
||
/// </summary>
|
||
private Dictionary<E_ChapterType, List<ChapterInfo>> dicChapterType = new();
|
||
|
||
private void InitData()
|
||
{
|
||
EventManager.Instance.Register(EventManager.EventName.AllConfigLoad, OnAllConfigLoad);
|
||
EventManager.Instance.Register<int>(EventManager.EventName.NewLevelServerData, OnNewLevelServerData);
|
||
}
|
||
|
||
private void ReleaseData()
|
||
{
|
||
EventManager.Instance.Unregister<int>(EventManager.EventName.NewLevelServerData, OnNewLevelServerData);
|
||
EventManager.Instance.Unregister(EventManager.EventName.AllConfigLoad, OnAllConfigLoad);
|
||
|
||
DisposeRedPointTree();
|
||
dicLevelInfo = null;
|
||
dicChapterInfo = null;
|
||
dicLevelGroupInfo = null;
|
||
}
|
||
|
||
#region API
|
||
/// <summary>
|
||
/// 刷新所有关卡信息
|
||
/// </summary>
|
||
public void RefreshAllLevelInfo()
|
||
{
|
||
foreach (LevelInfo levelInfo in dicLevelInfo.Values)
|
||
{
|
||
levelInfo?.RefreshServerData(true);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通关关卡id获取关卡信息
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
public bool TryGetLevelInfoByID(int id, out LevelInfo levelInfo)
|
||
{
|
||
if (!dicLevelInfo.TryGetValue(id, out levelInfo))
|
||
{
|
||
DebugUtil.LogError($"找不到levelInfo,id:{id}");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过关卡组id获取关卡组信息
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
public bool TryGetLevelGroupInfoByID(int id, out LevelGroupInfo levelGroupInfo)
|
||
{
|
||
if (!dicLevelGroupInfo.TryGetValue(id, out levelGroupInfo))
|
||
{
|
||
DebugUtil.LogError($"找不到LevelGroupInfo,id:{id}");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过章节id获取章节信息
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <returns></returns>
|
||
public bool TryGetChapterInfoByID(int id, out ChapterInfo chapterInfo)
|
||
{
|
||
if (!dicChapterInfo.TryGetValue(id, out chapterInfo))
|
||
{
|
||
DebugUtil.LogError($"找不到levelGroupInfo,id:{id}");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据章节类型获取章节信息
|
||
/// </summary>
|
||
/// <param name="levelChapterType"></param>
|
||
/// <returns></returns>
|
||
public bool TryGetChapterInfosByType(E_ChapterType type, out List<ChapterInfo> listChapterInfo)
|
||
{
|
||
if (dicChapterType.TryGetValue(type, out listChapterInfo) && null != listChapterInfo)
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取某种关卡类型上一次战斗的关卡
|
||
/// </summary>
|
||
/// <param name="type"></param>
|
||
/// <returns></returns>
|
||
public LevelInfo GetLastFightLevelInfo(E_ChapterType type)
|
||
{
|
||
string key = GetChapterTypeSaveKey(type);
|
||
if (!PlayerPrefs.HasKey(key))
|
||
return null;
|
||
|
||
int levelID = PlayerPrefs.GetInt(key);
|
||
TryGetLevelInfoByID(levelID, out LevelInfo levelInfo);
|
||
|
||
return levelInfo;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过id判断关卡是否解锁
|
||
/// </summary>
|
||
/// <param name="levelID"></param>
|
||
/// <returns></returns>
|
||
public bool CheckLevelUnlock(int levelID)
|
||
{
|
||
if(!TryGetLevelInfoByID(levelID, out LevelInfo levelInfo))
|
||
{
|
||
DebugUtil.LogError($"cant find levelInfo,id:{levelID}");
|
||
return false;
|
||
}
|
||
|
||
return !levelInfo.IsLock;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过关卡id转数字
|
||
/// </summary>
|
||
/// <param name="levelID"></param>
|
||
/// <returns></returns>
|
||
public string LevelIDToNum(int levelID)
|
||
{
|
||
if(!TryGetLevelInfoByID(levelID, out LevelInfo levelInfo))
|
||
{
|
||
DebugUtil.LogError($"cant find levelInfo,id:{levelID}");
|
||
return string.Empty;
|
||
}
|
||
|
||
return levelInfo.FullNumebr;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 通过关卡id转名字
|
||
/// </summary>
|
||
/// <param name="levelID"></param>
|
||
/// <returns></returns>
|
||
public string LevelIDToName(int levelID)
|
||
{
|
||
if(!TryGetLevelInfoByID(levelID, out LevelInfo levelInfo))
|
||
{
|
||
DebugUtil.LogError($"cant find levelInfo,id:{levelID}");
|
||
return string.Empty;
|
||
}
|
||
|
||
return levelInfo.Name;
|
||
}
|
||
|
||
public List<int> GetSuccessConditionData(ConditionType conditionType)
|
||
{
|
||
if (CurrentLevel == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
var levelData = CurrentLevel.GetLevelData();
|
||
var stage = levelData.stages;
|
||
var condition = stage[CurrentLevel.currentStageIndex].successCondition;
|
||
var paramList = new List<float>(); ;
|
||
foreach (var arg in condition.conditionArgs)
|
||
{
|
||
paramList.Add(arg.Arg);
|
||
}
|
||
var retList = new List<int>();
|
||
retList = ParseConditionParamArgs(paramList, conditionType);
|
||
return retList;
|
||
}
|
||
#endregion
|
||
|
||
#region 私有方法
|
||
/// <summary>
|
||
/// 加载配置
|
||
/// </summary>
|
||
private void OnAllConfigLoad()
|
||
{
|
||
LoadAllLevelInfo();
|
||
LoadAllLevelGroup();
|
||
LoadAllChapter();
|
||
ConstructRedPointTree();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载所有关卡信息
|
||
/// </summary>
|
||
private void LoadAllLevelInfo()
|
||
{
|
||
dicLevelInfo.Clear();
|
||
List<DataLevel> listAllLevelConfig = TableManager.Instance.Tables.Level.DataList;
|
||
|
||
foreach (DataLevel config in listAllLevelConfig)
|
||
{
|
||
dicLevelInfo.Add(config.Id, new LevelInfo(config));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载所有关卡组信息
|
||
/// </summary>
|
||
private void LoadAllLevelGroup()
|
||
{
|
||
dicLevelGroupInfo.Clear();
|
||
foreach (LevelInfo levelInfo in dicLevelInfo.Values)
|
||
{
|
||
int levelGroupID = levelInfo.Cfg.LevelGroupID;
|
||
if (0 == levelGroupID)
|
||
continue;
|
||
|
||
if (!dicLevelGroupInfo.TryGetValue(levelGroupID, out LevelGroupInfo levelGroupInfo))
|
||
{
|
||
DataLevelGroup config = TableManager.Instance.Tables.LevelGroupConfig.Get(levelGroupID);
|
||
if (null != config)
|
||
{
|
||
levelGroupInfo = new LevelGroupInfo(config);
|
||
dicLevelGroupInfo.Add(levelGroupID, levelGroupInfo);
|
||
}
|
||
else
|
||
DebugUtil.LogError($"找不到关卡组配置, id: {levelGroupID}");
|
||
}
|
||
|
||
levelGroupInfo?.AddLevel(levelInfo);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载所有章节
|
||
/// </summary>
|
||
private void LoadAllChapter()
|
||
{
|
||
dicChapterInfo.Clear();
|
||
foreach (LevelGroupInfo levelGroupInfo in dicLevelGroupInfo.Values)
|
||
{
|
||
int chapterID = levelGroupInfo.Cfg.ChapterID;
|
||
if (!dicChapterInfo.TryGetValue(chapterID, out ChapterInfo chapterInfo))
|
||
{
|
||
DataChapter config = TableManager.Instance.Tables.Chapter.Get(chapterID);
|
||
if (null != config)
|
||
{
|
||
chapterInfo = new ChapterInfo(config);
|
||
dicChapterInfo.Add(chapterID, chapterInfo);
|
||
}
|
||
else
|
||
DebugUtil.LogError($"找不到章节配置,id:{chapterID}");
|
||
}
|
||
|
||
chapterInfo?.AddLevelGroupInfo(levelGroupInfo);
|
||
}
|
||
|
||
foreach (ChapterInfo chapterInfo in dicChapterInfo.Values)
|
||
{
|
||
E_ChapterType chapterType = chapterInfo.Cfg.Type;
|
||
if (!dicChapterType.TryGetValue(chapterType, out List<ChapterInfo> list))
|
||
{
|
||
list = new();
|
||
dicChapterType.Add(chapterType, list);
|
||
}
|
||
|
||
list.Add(chapterInfo);
|
||
}
|
||
}
|
||
|
||
private void ConstructRedPointTree()
|
||
{
|
||
foreach (ChapterInfo chapterInfo in dicChapterInfo.Values)
|
||
{
|
||
int index = (int)chapterInfo.Cfg.Type;
|
||
if (index < 0 || index > levelGroupRedPointIDs.Length)
|
||
{
|
||
DebugUtil.LogError($"index is out of range!index:{index}");
|
||
continue;
|
||
}
|
||
|
||
int redPointParentID = levelGroupRedPointIDs[index];
|
||
chapterInfo.ConstructRedPointTree(redPointParentID);
|
||
}
|
||
}
|
||
|
||
private void DisposeRedPointTree()
|
||
{
|
||
foreach (ChapterInfo chapterInfo in dicChapterInfo.Values)
|
||
{
|
||
if (null != chapterInfo.RedPoint)
|
||
RedPointManager.Instance.RemoveDynamicNode(chapterInfo.RedPoint);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新的关卡服务器数据
|
||
/// </summary>
|
||
/// <param name="levelID"></param>
|
||
private void OnNewLevelServerData(int levelID)
|
||
{
|
||
if (TryGetLevelInfoByID(levelID, out LevelInfo levelInfo))
|
||
levelInfo.RefreshServerData(false);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存战斗关卡
|
||
/// </summary>
|
||
/// <param name="levelInfo"></param>
|
||
private void SaveFightLevel(LevelInfo levelInfo)
|
||
{
|
||
if(null == levelInfo)
|
||
return;
|
||
|
||
LevelGroupInfo levelGroupInfo = levelInfo.GroupInfo;
|
||
if(null == levelGroupInfo)
|
||
return;
|
||
|
||
ChapterInfo chapterInfo = levelGroupInfo.ChapterInfo;
|
||
if(null == chapterInfo)
|
||
return;
|
||
|
||
PlayerPrefs.SetInt(GetChapterTypeSaveKey(chapterInfo.Cfg.Type), levelInfo.Cfg.Id);
|
||
}
|
||
|
||
private string GetChapterTypeSaveKey(E_ChapterType chapterType) => LAST_FIGHT_LEVEL_PREFIX + chapterType;
|
||
|
||
public List<int> ParseConditionParamArgs(List<float> args, ConditionType conditionType)
|
||
{
|
||
List<int> retInt = new List<int>();
|
||
switch (conditionType)
|
||
{
|
||
case ConditionType.CombatKillEnemy:
|
||
if (args.Count < 1)
|
||
{
|
||
DebugUtil.LogError($"关卡条件守护参数出错!关卡ID:{CurrentLevel?.ID}");
|
||
break;
|
||
}
|
||
|
||
retInt.Add((int)args[0]);
|
||
break;
|
||
case ConditionType.CombatGuardAllies:
|
||
if (args.Count < 1)
|
||
{
|
||
DebugUtil.LogError($"关卡条件守护参数出错!关卡ID:{CurrentLevel?.ID}");
|
||
break;
|
||
}
|
||
|
||
//取到倒计时时间
|
||
retInt.Add((int)args[0]);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
return retInt;
|
||
}
|
||
#endregion
|
||
}
|
||
} |