using System; using UnityEngine; using Sirenix.OdinInspector; using System.Collections.Generic; using System.Runtime.Serialization; using cfg.AICfg; namespace Gameplay.Level { [Serializable] public class LevelData { #region class [Serializable] public class Region { public int id; public List positions = new(); [LabelText("手动指定中心格子索引")] public int centerCellIndex = -1; public string note; // 策划使用备注 } [Serializable] public class BlockRegion { public int id; public List positions = new(); /// /// 指示路径 /// public string path; /// /// 指示位置 /// public Vector3 centerPos = Vector3.zero; public string note; // 策划使用备注 } [Serializable] public class NPCInfo { [HideInInspector] public int index; // LocalID [HideInInspector] public int id; // 怪物ID [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(); [HideInInspector] public CharacterToward npcToward; [LabelText("编组")] public List groups = new List(4); [LabelText("是否为中途生成AI")] public bool isHideOnLoad; [LabelText("所属波数")] public int waveIndex; [LabelText("延迟出现时间(s)")] public int refreshTime; [LabelText("巡逻路线ID")] public int patrolRoadID = -1; [LabelText("显示路径")] public bool showRoadLine; [LabelText("指定区域ID")] public int specifyRegionID = -1; [LabelText("预设路径id")] public int presetPathId = -1; [LabelText("阵营ID 0:己方,1:敌方,2:中立")] public int troopId; [LabelText("是否开启侦察")] public bool isOpenInvestigate = true; } [Serializable] public class PatrolInfo { [HorizontalGroup("PatrolInfo")] [LabelText("巡逻点位")] public int cellIndex; [HideInInspector] public Vector2Int patrolPoint; [HorizontalGroup("PatrolInfo")] [LabelText("等待时间")] public float waitTime = 0f; } [Serializable] public class PatrolData { [HorizontalGroup("PatrolData")] [ReadOnly] public int id; [HorizontalGroup("PatrolData")] [LabelText("巡逻点位数据")] public List patrolInfos = new(); } [Serializable] public class TaskInfo { [HideInInspector] public int taskID; [LabelText("任务类型")] public ConditionModifier taskCondition = new(ConditionUtil.GetAllConditionFilter()); [LabelText("任务注释")] public string taskNote; // 策划使用备注 [LabelText("任务文本替换")] public string taskDesc; // 手写stringKey [LabelText("前置任务")] public int preTaskID; [LabelText("后置任务")] public int postTaskID; [OnDeserialized] public void OnAfterDeserialize(StreamingContext context) { taskCondition.SetFilterTypes(ConditionUtil.GetAllConditionFilter()); } } [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; [LabelText("首波延迟时间")] public float firstDelay = 1f; // 首次延迟时间 } [Serializable] public class LevelTriggerData { [HideInInspector] public int triggerTaskID; // TODO 删除 [HideInInspector] [LabelText("触发类型")] public ELevelTriggerType levelTriggerType = ELevelTriggerType.Default; [LabelText("参数 (时间/区域ID)")] public int triggerTime = 0; [LabelText("刷怪波次")] public int wave; // TODO 删除 [HideInInspector] [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(); [LabelText("触发间隔")] [ShowIf("@effectType==ELevelTriggerEffectType.StartFullSceneDamage")] public float repeatInterval = 3f; // 重复触发间隔(秒),默认3秒 [LabelText("伤害buffId")] [ShowIf("@effectType==ELevelTriggerEffectType.StartFullSceneDamage")] public int damageBuffId = -1; // 触发后给敌方添加的伤害加成buffID,默认-1不添加 } #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 { [LabelText("ID")] public int id; [LabelText("关卡进度参数:类型")] public ELevelGuideProgressType progressType; // TODO 删除 [LabelText("旧/触发条件")] public ConditionModifier triggerCondition; // TODO 删除 [LabelText("旧/完成条件")] public ConditionModifier finishCondition; [HideInInspector] [LabelText("触发条件")] public int triggerTaskID; [HideInInspector] [LabelText("完成条件")] public int finishTaskID; public ProgressGuideData(ProgressGuideData data) { progressType = data.progressType; triggerTaskID = data.triggerTaskID; finishTaskID = data.finishTaskID; // TODO 删除 triggerCondition = data.triggerCondition; finishCondition = data.finishCondition; } public ProgressGuideData() { progressType = ELevelGuideProgressType.SuccessProgress; // TODO 删除 triggerCondition = new ConditionModifier(ConditionUtil.GetAllConditionFilter()); finishCondition = new ConditionModifier(ConditionUtil.GetAllConditionFilter()); } // TODO 删除 [OnDeserialized] public void OnAfterDeserialize(StreamingContext context) { triggerCondition.SetFilterTypes(ConditionUtil.GetAllConditionFilter()); finishCondition.SetFilterTypes(ConditionUtil.GetAllConditionFilter()); } } /// /// 关卡立标引导 /// [Serializable] public class SetFlagGuideData { [LabelText("ID")] public int id; [LabelText("立标类型")] public ELevelGuideSetFlagType setFlagType; [LabelText("选择单位类型")] [ShowIf("@setFlagType==ELevelGuideSetFlagType.Unit")] public ESetFlagUnitType unitType; [LabelText("对应ID")] public int setFlagID; [HorizontalGroup("1")] [LabelText("立标提示内容")] public string setFlagKey; [HorizontalGroup("1")] [LabelText("备注")] public string note; // 策划使用备注 [HideInInspector] [LabelText("立标配置ID")] public int guideTagID; // 编辑器使用 [HideInInspector] [LabelText("立标路径")] public string guideTagPath; // TODO 删除 [LabelText("旧/触发条件")] public ConditionModifier triggerCondition; // TODO 删除 [LabelText("旧/完成条件")] public ConditionModifier finishCondition; [HideInInspector] [LabelText("触发条件")] public int triggerTaskID; [HideInInspector] [LabelText("完成条件")] public int finishTaskID; public SetFlagGuideData(SetFlagGuideData data) { setFlagType = data.setFlagType; unitType = data.unitType; setFlagID = data.setFlagID; setFlagKey = data.setFlagKey; guideTagID = data.guideTagID; guideTagPath = data.guideTagPath; triggerTaskID = data.triggerTaskID; finishTaskID = data.finishTaskID; // TODO 删除 triggerCondition = data.triggerCondition; finishCondition = data.finishCondition; } public SetFlagGuideData() { setFlagType = ELevelGuideSetFlagType.CellIndex; unitType = ESetFlagUnitType.Self; setFlagID = -1; // TODO 删除 triggerCondition = new ConditionModifier(ConditionUtil.GetAllConditionFilter()); finishCondition = new ConditionModifier(ConditionUtil.GetAllConditionFilter()); } // TODO 删除 [OnDeserialized] public void OnAfterDeserialize(StreamingContext context) { triggerCondition.SetFilterTypes(ConditionUtil.GetAllConditionFilter()); finishCondition.SetFilterTypes(ConditionUtil.GetAllConditionFilter()); } } /// /// 关卡信息面板引导 /// [Serializable] public class InfoPanelGuideData { [LabelText("ID")] public int id; [HorizontalGroup("1")] [LabelText("标题ID")] public string titleKey; [HorizontalGroup("1")] [LabelText("备注")] public string noteTitle; // 策划使用备注 [HorizontalGroup("2")] [LabelText("内容ID")] public string contentKey; [HorizontalGroup("2")] [LabelText("备注")] public string noteContent; // 策划使用备注 // TODO 删除 [LabelText("旧/触发条件")] public ConditionModifier triggerCondition; // TODO 删除 [LabelText("旧/完成条件")] public ConditionModifier finishCondition; [HideInInspector] [LabelText("触发条件")] public int triggerTaskID; [HideInInspector] [LabelText("完成条件")] public int finishTaskID; public InfoPanelGuideData(InfoPanelGuideData data) { titleKey = data.titleKey; contentKey = data.contentKey; triggerTaskID = data.triggerTaskID; finishTaskID = data.finishTaskID; // TODO 删除 triggerCondition = data.triggerCondition; finishCondition = data.finishCondition; } public InfoPanelGuideData() { // TODO 删除 triggerCondition = new ConditionModifier(ConditionUtil.GetAllConditionFilter()); finishCondition = new ConditionModifier(ConditionUtil.GetAllConditionFilter()); } // TODO 删除 [OnDeserialized] public void OnAfterDeserialize(StreamingContext context) { triggerCondition.SetFilterTypes(ConditionUtil.GetAllConditionFilter()); finishCondition.SetFilterTypes(ConditionUtil.GetAllConditionFilter()); } } #endregion #region 关卡AI广播 /// /// AI广播对象类型 /// public enum E_AIBroadcastTargetType { [LabelText("怪物组")] EnemyGroup, [LabelText("所有怪物,包括未出生的")] AllEnemy, [LabelText("所有怪物,不包括未出生的")] AllCurEnemy, [LabelText("怪物")] Enemy, } /// /// AI行为目标类型 /// public enum E_AIActionTarget { [LabelText("单位目标")] Unit, [LabelText("建筑目标")] Build, [LabelText("地格目标")] Cell, [LabelText("区域目标")] Area, [LabelText("路径ID")] Path, [LabelText("我方全体非强隐单位")] SelfTroop, } /// /// AI预设切换类型 /// public enum E_AIPresetChangeType { None, [LabelText("整体预设")] All = 1, [LabelText("区域巡逻")] AreaPatrol = 2, [LabelText("路径巡逻")] PathPatrol = 3, [LabelText("驻守")] Idle = 4, [LabelText("常规到达")] NormalReach = 5, //[LabelText("上车到达")] //VehicleReach = 6, [LabelText("存活")] Living = 7, [LabelText("常规")] Normal = 8, [LabelText("舍命")] LayLive = 9, [LabelText("牛皮糖")] StickyCandy = 10, } /// /// AI广播数据 /// [Serializable] public sealed class AIBroadcastData { // TODO 删除 [HideInInspector] [LabelText("触发条件")] public ConditionModifier triggerCondition; [HideInInspector] [LabelText("触发条件")] public int triggerTaskID; [LabelText("AI广播对象类型")] public E_AIBroadcastTargetType aiBroadcastTargetType; [LabelText("目标id列表")] [ShowIf( "@E_AIBroadcastTargetType.EnemyGroup == aiBroadcastTargetType || E_AIBroadcastTargetType.Enemy == aiBroadcastTargetType")] public List listTargetId; [LabelText("AI行为")] public EAIAction AIAction; [LabelText("AI行为目标")] [ShowIf("@EAIAction.None != AIAction")] public E_AIActionTarget AIActionTarget; [LabelText("单位目标id")] [ShowIf("@EAIAction.None != AIAction && AIActionTarget != E_AIActionTarget.SelfTroop")] public int actionTargetId; [LabelText("AI状态切换")] public EAIState AIState; [LabelText("AI预设切换类型")] public E_AIPresetChangeType AIPresetChangeType; [LabelText("AI预设ID")] [ShowIf("@E_AIPresetChangeType.All == AIPresetChangeType")] public int AIPresetId; [LabelText("是否循环巡逻,true:循环,false:往返")] [ShowIf( "@E_AIPresetChangeType.AreaPatrol == AIPresetChangeType || E_AIPresetChangeType.PathPatrol == AIPresetChangeType")] public bool isLoopPatrol; [LabelText("巡逻地点ID")] [ShowIf( "@E_AIPresetChangeType.AreaPatrol == AIPresetChangeType || E_AIPresetChangeType.PathPatrol == AIPresetChangeType")] public int PatrolId; [LabelText("入住建筑类型")] [ShowIf( "@E_AIPresetChangeType.Idle == AIPresetChangeType || E_AIPresetChangeType.Normal == AIPresetChangeType || E_AIPresetChangeType.Living == AIPresetChangeType")] public List listBuildType; [LabelText("是否回到出生点")] [ShowIf("@E_AIPresetChangeType.Idle == AIPresetChangeType")] public bool IsBackBirth; #region 常规到达 [LabelText("前进速度类型,true:移速,false:巡逻速度")] [ShowIf("@E_AIPresetChangeType.NormalReach == AIPresetChangeType")] public bool reachSpeedType; [LabelText("遇敌后是否攻击")] [ShowIf("@E_AIPresetChangeType.NormalReach == AIPresetChangeType")] public bool reachOpenAttack; #endregion #region 存活 [LabelText("是否回到上一个状态")] [ShowIf("@E_AIPresetChangeType.Living == AIPresetChangeType")] public bool isBackState; [LabelText("是否限制追踪距离")] [ShowIf( "@E_AIPresetChangeType.Normal == AIPresetChangeType || E_AIPresetChangeType.LayLive == AIPresetChangeType")] public bool isLimitDistance; #endregion public AIBroadcastData() { // TODO 删除 triggerCondition = new ConditionModifier(); } } #endregion /// /// 角色方向(兼容老方向) /// public enum CharacterToward { Toward1 = 6, Toward2 = 1, Toward3 = 7, Toward4 = 2, Toward5 = 8, Toward6 = 3, Toward7 = 9, Toward8 = 4, Toward9 = 10, Toward10 = 5, Toward11 = 11, Toward12 = 0, } /// /// 占领数据 /// [Serializable] public class CaptureInfo { [LabelText("占领区ID")] public int captureRegionID; [LabelText("占领点位")] public List capturePoints = new List(); [LabelText("进度标识点")] public int captureFlag; [LabelText("占领时间")] public int CaptureProgress = 0; [LabelText("占领地面特效ID")] public int captureEffectID; [LabelText("占领地面完成特效ID")] public int captureFinishEffectID; [LabelText("占领地面特效创建地格")] public int captureEffectPoint; } /// /// 撤离数据 /// [Serializable] public class RetreatInfo { public List retreatPoints = new List(); public int retreatFlag; } #endregion public LevelData() { } [HideInInspector] public List taskInfos = new(); /// /// 巡逻路径 /// [HideInInspector] public List patrolRoadData = new(); /// /// 巡逻区域 /// [HideInInspector] public List patrolRegionData = new(); #region 关卡胜利失败星级条件 [HideInInspector] public int successTaskID; [HideInInspector] public int failTaskID; [HideInInspector] public List starTaskIDs = new() { 0, 0, 0 }; #endregion #region 评分关卡条件 [BoxGroup("支线(战役)")] [LabelText("设置该关卡为评分关卡")] [HideInInspector] public bool scoreLevel; [HideInInspector] public List scoreTaskID = new(15); // TODO 删除 [HideInInspector] public List scoreTarget = new(15); #endregion [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); } [HideInInspector] public List levelTriggerDatas = new(); [BoxGroup("特殊需求")] [LabelText("初始生命百分值")] public float initialHealthPercent = 1.0f; [BoxGroup("特殊需求")] [LabelText("初始护盾百分值")] public float initialShieldPercent = 1.0f; #region 关卡引导 [HideInInspector] [LabelText("关卡进度")] public List progressGuideDatas = new(); [HideInInspector] [LabelText("立标数据")] public List setFlagGuideDatas = new(); [HideInInspector] [LabelText("信息板数据")] public List infoPanelGuideDatas = new(); #endregion #region 关卡AI广播 [HideInInspector] [LabelText("关卡AI广播进度")] public List listAIBroadcastData = new(); #endregion /// /// 刷新生成点位 /// [HideInInspector] public List refreshPoints = new List(); [HideInInspector] public List npcInfos = new(); [HideInInspector] public List midNpcInfos = new(); [HideInInspector] public List selfNpcInfos = new(); [HideInInspector] public Dictionary> npcGroupInfos = new(); /// /// 阻挡攻击数据 /// [HideInInspector] public List BlockSphereInfos = new(); [HideInInspector] public List CapturePoints = new(8); [HideInInspector] public List enemyRetreatReusablePoints = new List(); [HideInInspector] public RetreatInfo retreatPoints = new RetreatInfo(); [HideInInspector] public int fallBackCount; #region 地区相关 /// /// 出战区 /// [HideInInspector] public int preparingRegionId; /// /// 出战区朝向 /// [HideInInspector] public CharacterToward preparingRegionToward; /// /// PVP防守区 /// [HideInInspector] public int pvpDefendRegionId; /// /// PVP防守方朝向 /// [HideInInspector] public CharacterToward pvpDefendToward; /// /// 雷区 /// [HideInInspector] public List minesRegions = new(); /// /// 阻挡区 /// [HideInInspector] public List blockRegions = new(); /// /// 防守区 /// [HideInInspector] public List defenseRegions = new(); /// /// 扛旗起点 /// [HideInInspector] public List flagStartPoints = new List(); /// /// 扛旗终点 /// [HideInInspector] public List flagEndPoints = new List(); #endregion } }