using cfg;
using System.IO;
using Framework;
using System.Linq;
using UnityEditor;
using UnityEngine;
using cfg.LevelCfg;
using PhxhSDK.Phxh;
using Gameplay.Level;
using UnityEditor.SceneManagement;
public abstract class LevelValidatorBase
{
///
/// 错误数据
///
public bool ErrorData;
///
/// 错误场景
///
protected bool ErrorScene;
///
/// 错误信息
///
public string ErrorMessage;
///
/// 警告信息
///
public string WarningMessage;
protected LevelData LevelData;
protected MapData MapData;
protected readonly string LevelDataPath;
protected readonly string MapDataPath;
private readonly DataLevel levelCfg;
protected LevelValidatorBase(string levelDataPath, string mapDataPath)
{
LevelDataPath = levelDataPath;
MapDataPath = mapDataPath;
CheckWellResourced();
}
protected LevelValidatorBase(DataLevel levelCfg)
{
this.levelCfg = levelCfg;
LevelDataPath = levelCfg.LevelData;
MapDataPath = levelCfg.MapData;
CheckWellResourced();
CheckMapScene();
}
private void CheckMapScene()
{
if (levelCfg == null || string.IsNullOrEmpty(levelCfg.LevelScene) || !File.Exists(levelCfg.LevelScene))
{
ErrorScene = true;
AppendWithNewLine(ref ErrorMessage, "场景路径不存在,请检查资源");
return;
}
if (!File.Exists(GetPostScenePath()))
{
ErrorScene = true;
AppendWithNewLine(ref ErrorMessage, $"后处理场景不存在,请先后处理{levelCfg.LevelScene}");
}
}
private void CheckWellResourced()
{
if (string.IsNullOrEmpty(LevelDataPath) || string.IsNullOrEmpty(MapDataPath))
{
AppendWithNewLine(ref ErrorMessage, "地图或关卡数据为空,请检查配置表");
ErrorData = true;
return;
}
var levelPath = string.Format(Constants.LEVEL_CONFIG_FORMAT_PATH, LevelDataPath);
var mapPath = string.Format(Constants.MAP_CONFIG_FORMAT_PATH, MapDataPath);
var levelAsset = AssetDatabase.LoadAssetAtPath(levelPath);
var mapAsset = AssetDatabase.LoadAssetAtPath(mapPath);
if (levelAsset == null || mapAsset == null)
{
AppendWithNewLine(ref ErrorMessage, $"【地图数据路径:{MapDataPath} / 关卡数据路径:{LevelDataPath} 】加载失败,请检查本地是否有对应数据文件");
ErrorData = true;
return;
}
LevelData = JsonToData(levelAsset);
MapData = JsonToData(mapAsset);
if (LevelData == null || MapData == null)
{
AppendWithNewLine(ref ErrorMessage, "无法正确转换关卡和地图数据");
ErrorData = true;
}
}
public abstract bool CheckData();
private T JsonToData(TextAsset jsonText) where T : new()
{
if (jsonText != null)
{
var jsonStr = jsonText.text;
if (string.IsNullOrEmpty(jsonStr))
{
return new T();
}
else
{
var path = AssetDatabase.GetAssetPath(jsonText);
return JsonHelper.LoadJson(path);
}
}
return default;
}
protected bool RegionIsLegal(int regionID)
{
return MapData.regions.Count > regionID;
}
///
/// 后处理场景路径
///
private string _postScenePath;
protected string GetPostScenePath()
{
if (ErrorScene) return null;
if (!string.IsNullOrEmpty(_postScenePath)) return _postScenePath;
var scenePath = levelCfg.LevelScene;
var postSceneDirectory = Path.GetFileNameWithoutExtension(scenePath.Replace("/", "_"));
var postScene = Path.GetFileNameWithoutExtension(scenePath) + "_PostProcess.unity";
_postScenePath = $"Assets/Art/AutoGen/PostProcessScenes/{postSceneDirectory}/{postScene}";
return _postScenePath;
}
protected void AppendWithNewLine(ref string original, string newString)
{
if (!string.IsNullOrEmpty(original))
{
original += "\n";
}
original += newString;
}
}
///
/// 检查占领点是否合法
///
public class CheckCaptureData : LevelValidatorBase
{
public CheckCaptureData(string levelDataPath, string mapDataPath) : base(levelDataPath, mapDataPath)
{
}
public override bool CheckData()
{
if (ErrorData) return false;
if (MapData.capturePoints.Count > 0)
{
if (LevelData.captureProgress <= 0)
{
ErrorMessage = $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】有占领点,但无占领进度信息!";
return false;
}
}
return true;
}
}
///
/// 检查扛旗点
///
public class CheckFlagData : LevelValidatorBase
{
public CheckFlagData(string levelDataPath, string mapDataPath) : base(levelDataPath, mapDataPath)
{
}
public override bool CheckData()
{
if (ErrorData) return false;
if (MapData.flagStartPoints.Count > 0)
{
DebugUtil.Log("有扛旗起点");
if (LevelData.flagTargetRegionId == 0 && RegionIsLegal(0))
{
WarningMessage = $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】有扛旗起点,扛旗终点区域为默认 0 !";
}
if (!RegionIsLegal(LevelData.flagTargetRegionId))
{
ErrorMessage =
$"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】有扛旗起点,扛旗终点区域【{LevelData.flagTargetRegionId}】不存在 !";
return false;
}
}
return true;
}
}
///
/// 检查关卡区域设置
///
public class CheckLevelRegionData : LevelValidatorBase
{
public CheckLevelRegionData(string levelDataPath, string mapDataPath) : base(levelDataPath, mapDataPath)
{
}
public override bool CheckData()
{
if (ErrorData) return false;
if (!RegionIsLegal(LevelData.preparingRegionId))
{
ErrorMessage = $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】出战区【{LevelData.preparingRegionId}】错误,不存在 !";
return false;
}
if (!RegionIsLegal(LevelData.fallbackRegionId))
{
ErrorMessage = $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】撤退区【{LevelData.fallbackRegionId}】错误,不存在 !";
return false;
}
if (!RegionIsLegal(LevelData.enemyFallbackRegionId))
{
ErrorMessage =
$"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】敌方撤退区【{LevelData.enemyFallbackRegionId}】错误,不存在 !";
return false;
}
if (!RegionIsLegal(LevelData.pvpDefendRegionId))
{
ErrorMessage = $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】PVP防守区【{LevelData.pvpDefendRegionId}】错误,不存在 !";
return false;
}
if (LevelData.fallbackRegionId == LevelData.enemyFallbackRegionId)
{
WarningMessage = $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】敌人撤退区域和我方撤退区域相同 !";
}
return true;
}
}
///
/// 检查护送相关设置
///
public class CheckProtectData : LevelValidatorBase
{
public CheckProtectData(string levelDataPath, string mapDataPath) : base(levelDataPath, mapDataPath)
{
}
public override bool CheckData()
{
if (ErrorData) return false;
string errorUnitIds = "";
if (LevelData.protectUnitInfos.Count > 0)
{
foreach (var protectUnit in LevelData.protectUnitInfos)
{
if (protectUnit.protectStartPoint == protectUnit.protectTargetPoint)
{
errorUnitIds = errorUnitIds + protectUnit.id + " ";
}
}
}
if (!string.IsNullOrEmpty(errorUnitIds))
{
ErrorMessage = $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】护送对象【{errorUnitIds}】的终点和起点相同";
}
return true;
}
}
///
/// 检查是否存在后处理场景 及场景中是否有未删除的人物或载具模型
///
public class CheckScenePostProcess : LevelValidatorBase
{
public CheckScenePostProcess(DataLevel levelCfg) : base(levelCfg)
{
}
public override bool CheckData()
{
if (ErrorData || ErrorScene) return false;
var postScenePath = GetPostScenePath();
var scene = EditorSceneManager.OpenScene(postScenePath, OpenSceneMode.Additive);
var rootObjects = scene.GetRootGameObjects();
if (rootObjects.Any(obj => obj.name.StartsWith("P_")))
{
EditorSceneManager.CloseScene(scene, true);
AppendWithNewLine(ref ErrorMessage, $"【地图: {postScenePath} 】后处理场景中有未删除的人物或载具模型");
return false;
}
EditorSceneManager.CloseScene(scene, true);
return true;
}
}
///
/// 检查胜利胜败阶段条件
///
public class CheckLevelCondition : LevelValidatorBase
{
public CheckLevelCondition(string levelDataPath, string mapDataPath) : base(levelDataPath, mapDataPath)
{
}
public override bool CheckData()
{
if (ErrorData) return false;
var stages = LevelData.stages;
if (stages is { Count: <= 0 })
{
AppendWithNewLine(ref ErrorMessage, $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】中没有设置阶段信息");
return false;
}
foreach (var stage in stages)
{
if (stage.successCondition.conditionType == ConditionType.None)
{
AppendWithNewLine(ref ErrorMessage, $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】中获胜目标为None");
return false;
}
if (stage.failConditions is { Count: <= 0 })
{
AppendWithNewLine(ref ErrorMessage, $"【【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】中没有设置失败阶段");
return false;
}
if (stage.failConditions.Any(failCondition => failCondition.conditionType == ConditionType.None))
{
AppendWithNewLine(ref ErrorMessage, $"【【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】中失败阶段目标为None");
return false;
}
}
return true;
}
}
///
/// 检查若为星级关卡 参数是否正确
///
public class CheckLevelStarTarget : LevelValidatorBase
{
public CheckLevelStarTarget(string levelDataPath, string mapDataPath) : base(levelDataPath, mapDataPath)
{
}
public override bool CheckData()
{
if (ErrorData) return false;
if (LevelData.scoreLevel) return true;
var starTargets = LevelData.starTarget;
if (starTargets is { Count: <= 0 })
{
AppendWithNewLine(ref ErrorMessage, $"【【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】为星级关卡,但未设置星级目标");
return false;
}
if (starTargets.Any(startTarget => startTarget.conditionType == ConditionType.None))
{
AppendWithNewLine(ref ErrorMessage, $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】中有星级目标条件为None");
return false;
}
return true;
}
}
///
/// 检查若为评分关卡 参数是否正确
///
public class CheckLevelScoreTarget : LevelValidatorBase
{
public CheckLevelScoreTarget(string levelDataPath, string mapDataPath) : base(levelDataPath, mapDataPath)
{
}
public override bool CheckData()
{
if (ErrorData) return false;
if (!LevelData.scoreLevel) return true;
var scoreTargets = LevelData.scoreTarget;
if (scoreTargets is { Count: <= 0 })
{
AppendWithNewLine(ref ErrorMessage, $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】为评分关卡,但未设置评分目标");
return false;
}
foreach (var scoreTarget in scoreTargets)
{
if (scoreTarget.conditionType == ConditionType.None)
{
AppendWithNewLine(ref ErrorMessage, $"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】中有评分目标条件为None");
return false;
}
if (scoreTarget.score <= 0)
{
AppendWithNewLine(ref ErrorMessage,
$"【地图数据:{MapDataPath} / 关卡数据:{LevelDataPath} 】中评分目标【{scoreTarget.conditionType}】的分数为 0");
return false;
}
}
return true;
}
}