using System; using UnityEngine; using Sirenix.OdinInspector; using System.Collections.Generic; using System.Runtime.Serialization; using UnityEngine.Serialization; namespace Gameplay.Level { [Serializable] public class LevelData { [Serializable] public class Task { [LabelText("任务ID")] public int taskId; [LabelText("任务名称")] public string taskNameKey; [LabelText("任务描述")] public string taskDescKey; [LabelText("任务目标")] [ListDrawerSettings(CustomAddFunction = "OnAddCondition")] public List taskConditions = new(); [LabelText("前置任务ID")] public int preTaskId = -1; [LabelText("后置任务ID")] public int postTaskId = -1; [LabelText("阻拦区域ID")] public int blockRegionId = -1; private void OnAddCondition() { ConditionModifier conditionModifier = new(); conditionModifier.SetFilterTypes(ConditionUtil.AllLevelConditionFilter); taskConditions.Add(conditionModifier); } [OnDeserialized] public void OnAfterDeserialize(StreamingContext context) { foreach (var conditionModifier in taskConditions) { conditionModifier.SetFilterTypes(ConditionUtil.AllLevelConditionFilter); } } } [Serializable] public class Stage { // TODO 舍弃 [HideInInspector] [LabelText("胜利条件")] public ConditionModifier successCondition = new(ConditionUtil.LevelSuccessConditionFilter); // TODO 舍弃 [HideInInspector] [LabelText("失败条件")] [ListDrawerSettings(CustomAddFunction = "OnAddFailCondition")] public List failConditions = new(); [LabelText("胜利目标")] public int successTaskID; [LabelText("失败目标")] public int failTaskID; [LabelText("任务列表")] [ListDrawerSettings(CustomAddFunction = "OnAddTask")] public List tasks = new(); private void OnAddFailCondition() { ConditionModifier conditionModifier = new(); conditionModifier.SetFilterTypes(ConditionUtil.LevelFailConditionFilter); failConditions.Add(conditionModifier); } private void OnAddTask() { var task = new Task { taskId = tasks.Count + 1 // 任务ID从1开始 }; tasks.Add(task); } [OnDeserialized] public void OnAfterDeserialize(System.Runtime.Serialization.StreamingContext context) { successCondition.SetFilterTypes(ConditionUtil.LevelSuccessConditionFilter); foreach (var failCondition in failConditions) { failCondition.SetFilterTypes(ConditionUtil.LevelFailConditionFilter); } } } [Serializable] public class NPCInfo { [HideInInspector] public int index; [HideInInspector] public int id; // 仅供展示 [ReadOnly] public int level; [ReadOnly] [LabelText("位置")] public Vector2Int position; [LabelText("初始护盾")] public float shield; [LabelText("初始血量")] public float ph; [LabelText("初始士气")] public float morale; [LabelText("Buff")] public List buff = new List(); [LabelText("DeBuff")] public List deBuff = new List(); [LabelText("AI类型(需舍弃)")] public AIType aIType = AIType.None; [LabelText("特殊触发AI(需舍弃)")] public AttachAIType attachAIType; [HideInInspector] public CharacterToward npcToward; [LabelText("巡逻信息")] public List patrolInfos = new List(4); [LabelText("编组")] public List groups = new List(4); [LabelText("防守距离")] public int defensiveDistance; [HideInInspector] public string configName; [LabelText("是否为中途生成AI")] public bool isHideOnLoad; [LabelText("所属波数")] public int waveIndex; [LabelText("刷新时间(s)")] public int refreshTime; [LabelText("所属防守区域")] public int defenseRegionIndex; [LabelText("指定路线ID")] public int specifyRoadID = -1; [LabelText("显示路径")] public bool showRoadLine; [LabelText("指定区域ID")] public int specifyRegionID = -1; } [Serializable] public class PatrolInfo { [HorizontalGroup("PatrolInfo")] [LabelText("巡逻点位")] public Vector2Int patrolPoint; [HorizontalGroup("PatrolInfo")] [LabelText("等待时间")] public float waitTime = 0f; } [Serializable] public class SpawnMonsterData { [LabelText("波次ID")] public int waveIndex; [LabelText("刷新方式")] public ELevelUnitGenType refreshType = ELevelUnitGenType.Default; [LabelText("间隔时间")] [ShowIf("@refreshType==ELevelUnitGenType.TimeLoop")] public int refreshInterval; [LabelText("最大次数 (-1无限循环), 如果为跳转则表示跳转ID")] public int maxCount; } [Serializable] public class LevelTriggerData { [LabelText("触发类型")] public ELevelTriggerType levelTriggerType = ELevelTriggerType.Default; [LabelText("参数 (时间/区域ID)")] public int triggerTime = 0; [LabelText("刷怪波次")] public int wave; [LabelText("任务ID")] [ShowIf("@levelTriggerType==ELevelTriggerType.TaskComplete")] public int taskID; [LabelText("触发Effect类型")] public ELevelTriggerEffectType effectType = ELevelTriggerEffectType.StartGenUnit; [LabelText("怪物波次IDs")] [ShowIf("@effectType==ELevelTriggerEffectType.ForceKillUnits")] public List waveList = new List(); } [Serializable] public class PrescribedRoadInfo { public int roadID; public List cellIndex = new List(); } #region LevelGuide /// /// 波次横幅显示 /// [Serializable] public class WaveInfoData { [ReadOnly] [LabelText("ID")] public int localID; [LabelText("触发波次ID")] public int waveID = -1; [LabelText("第几次循环")] public int loopCount = 1; [LabelText("是否显示横幅")] public bool showWaveInfo; } /// /// 关卡进度引导 /// [Serializable] public class ProgressGuideData { [ReadOnly] [LabelText("ID")] public int localID; [LabelText("关卡进度参数:类型")] public ELevelGuideProgressType progressType = ELevelGuideProgressType.SuccessProgress; [LabelText("触发条件")] public ConditionModifier triggerCondition = new(ConditionUtil.LevelGuideConditionFilter); [LabelText("完成条件")] public ConditionModifier finishCondition = new(ConditionUtil.LevelGuideEndConditionFilter); } /// /// 关卡立标引导 /// [Serializable] public class SetFlagGuideData { [ReadOnly] [LabelText("ID")] public int localID; [LabelText("立标类型")] public ELevelGuideSetFlagType setFlagType = ELevelGuideSetFlagType.CellIndex; [LabelText("选择单位类型")] [ShowIf("@setFlagType==ELevelGuideSetFlagType.Unit")] public ESetFlagUnitType unitType = ESetFlagUnitType.Self; [LabelText("角色ID")] [ShowIf("@setFlagType==ELevelGuideSetFlagType.Unit")] public int setFlagID = -1; [LabelText("地格IDs")] [ShowIf("@setFlagType==ELevelGuideSetFlagType.CellIndex")] public List setFlagIDs = new(); [LabelText("立标提示内容")] public string setFlagKey; [LabelText("触发条件")] public ConditionModifier triggerCondition = new(ConditionUtil.LevelGuideConditionFilter); [LabelText("完成条件")] public ConditionModifier finishCondition = new(ConditionUtil.LevelGuideEndConditionFilter); } /// /// 关卡信息面板引导 /// [Serializable] public class InfoPanelGuideData { [ReadOnly] [LabelText("ID")] public int localID; [LabelText("标题ID")] public string titleKey; [LabelText("内容ID")] public string contentKey; [LabelText("触发条件")] public ConditionModifier triggerCondition = new(ConditionUtil.LevelGuideConditionFilter); [LabelText("完成条件")] public ConditionModifier finishCondition = new(ConditionUtil.LevelGuideEndConditionFilter); } #endregion public enum CharacterToward { TopLeft, TopRight, Right, BottomRight, BottomLeft, Left, } public enum AIType { BasicAI, FallBackAI, FallBackIntensifyAI, OutflankAI, DefendAI, StupidDefendAI, None, } public enum AttachAIType { None, ChainAI, ProvokeAI, SpecialBehaviorAI, AttackProtectUnitAI, } public LevelData() { } [LabelText("出战区")] [HideInInspector] public int preparingRegionId; [LabelText("出战区朝向")] [HideInInspector] public CharacterToward preparingRegionToward; [LabelText("撤退区")] [HideInInspector] public int fallbackRegionId; [LabelText("敌方撤退区")] [HideInInspector] public int enemyFallbackRegionId; [LabelText("PVP防守区")] [HideInInspector] public int pvpDefendRegionId; [LabelText("PVP防守方朝向")] [HideInInspector] public CharacterToward pvpDefendToward; // TODO 删除 [HideInInspector] [BoxGroup("主线")] [LabelText("关卡任务")] public Stage stage; [BoxGroup("支线")] [LabelText("设置该关卡为评分关卡")] public bool scoreLevel = false; [BoxGroup("支线")] [LabelText("星级目标"), HideIf("scoreLevel")] [ListDrawerSettings(HideAddButton = true, HideRemoveButton = true)] public List starTarget = new() { new ConditionModifier(ConditionUtil.LevelStarConditionFilter), new ConditionModifier(ConditionUtil.LevelStarConditionFilter), new ConditionModifier(ConditionUtil.LevelStarConditionFilter) }; [BoxGroup("支线")] [LabelText("评分目标"), ShowIf("scoreLevel")] [ListDrawerSettings(CustomAddFunction = "OnAddScoreCondition")] public List scoreTarget = new List(15); private void OnAddScoreCondition() { ConditionModifier conditionModifier = new(); conditionModifier.SetFilterTypes(ConditionUtil.LevelScoreConditionFilter, true); scoreTarget.Add(conditionModifier); } [BoxGroup("防守相关设置")] [LabelText("防守关卡数据")] public List spawnMonsterDatas; [BoxGroup("防守相关设置")] [LabelText("波次横幅显示数据")] [ListDrawerSettings(CustomAddFunction = "OnAddWaveInfoData")] public List waveInfoDatas = new(); private void OnAddWaveInfoData() { var waveInfoData = new WaveInfoData { localID = waveInfoDatas.Count + 1 }; waveInfoDatas.Add(waveInfoData); } [BoxGroup("触发器")] [LabelText("关卡触发器")] public List levelTriggerDatas; [BoxGroup("特殊需求")] [LabelText("初始生命百分值")] public float initialHealthPercent = 1.0f; [BoxGroup("特殊需求")] [LabelText("初始护盾百分值")] public float initialShieldPercent = 1.0f; #region 关卡引导 [BoxGroup("关卡引导")] [LabelText("关卡进度")] [ListDrawerSettings(CustomAddFunction = "OnAddProgressGuideData")] public List progressGuideDatas = new(); [BoxGroup("关卡引导")] [LabelText("立标数据")] [ListDrawerSettings(CustomAddFunction = "OnAddSetFlagGuideData")] public List setFlagGuideDatas = new(); [BoxGroup("关卡引导")] [LabelText("信息板数据")] [ListDrawerSettings(CustomAddFunction = "OnAddInfoPanelGuideData")] public List infoPanelGuideDatas = new(); private void OnAddProgressGuideData() { var progressGuideData = new ProgressGuideData { localID = progressGuideDatas.Count + 1 }; progressGuideDatas.Add(progressGuideData); } private void OnAddSetFlagGuideData() { var setFlagGuideData = new SetFlagGuideData { localID = setFlagGuideDatas.Count + 1 }; setFlagGuideDatas.Add(setFlagGuideData); } private void OnAddInfoPanelGuideData() { var infoPanelGuideData = new InfoPanelGuideData { localID = infoPanelGuideDatas.Count + 1 }; infoPanelGuideDatas.Add(infoPanelGuideData); } #endregion /// /// 刷新生成点位 /// [HideInInspector] public List refreshPoints = new List(); /// /// 指定路线 /// [HideInInspector] public List roadInfos = new List(4); [HideInInspector] public List npcInfos = new(); [HideInInspector] public List selfNpcInfos = new(); [Serializable] public class CaptureInfo { [LabelText("占领点位")] public int CapturePoint; [LabelText("占领时间")] public int CaptureProgress = 0; } [HideInInspector] public List CapturePoints = new(8); [HideInInspector] public List flagStartPoints = new List(); [HideInInspector] public List flagEndPoints = new List(); [HideInInspector] public List fallbackSinglePoints = new List(); [HideInInspector] public List fallbackReusablePoints = new List(); [HideInInspector] public int fallBackCount; [OnDeserialized] public void OnAfterDeserialize(StreamingContext context) { if (starTarget.Count != 3) { starTarget.Clear(); starTarget.Add(new ConditionModifier()); starTarget.Add(new ConditionModifier()); starTarget.Add(new ConditionModifier()); } foreach (var starCondition in starTarget) { starCondition.SetFilterTypes(ConditionUtil.LevelStarConditionFilter); } foreach (var scoreCondition in scoreTarget) { scoreCondition.SetFilterTypes(ConditionUtil.LevelScoreConditionFilter, scoreLevel); } } } }