NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/GameWrapper/Level/LevelData.cs

595 lines
21 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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
{
[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<int> buff = new List<int>();
[LabelText("DeBuff")] public List<int> deBuff = new List<int>();
[HideInInspector] public CharacterToward npcToward;
[LabelText("编组")] public List<int> groups = new List<int>(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<PatrolInfo> patrolInfos = new();
}
/// <summary>
/// 巡逻路径
/// </summary>
public List<PatrolData> patrolRoadData = new();
/// <summary>
/// 巡逻区域
/// </summary>
public List<PatrolData> patrolRegionData = new();
[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
{
[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<int> waveList = new List<int>();
[LabelText("触发间隔")]
[ShowIf("@effectType==ELevelTriggerEffectType.StartFullSceneDamage")]
public float repeatInterval = 3f; // 重复触发间隔(秒)默认3秒
[LabelText("伤害buffId")]
[ShowIf("@effectType==ELevelTriggerEffectType.StartFullSceneDamage")]
public int damageBuffId = -1; // 触发后给敌方添加的伤害加成buffID默认-1不添加
}
#region LevelGuide
/// <summary>
/// 波次横幅显示
/// </summary>
[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;
}
/// <summary>
/// 关卡进度引导
/// </summary>
[Serializable]
public class ProgressGuideData
{
[LabelText("ID")]
public int id;
[LabelText("关卡进度参数:类型")] public ELevelGuideProgressType progressType;
[LabelText("触发条件")] public ConditionModifier triggerCondition;
[LabelText("完成条件")] public ConditionModifier finishCondition;
public ProgressGuideData(ProgressGuideData data)
{
progressType = data.progressType;
triggerCondition = data.triggerCondition;
finishCondition = data.finishCondition;
}
public ProgressGuideData()
{
progressType = ELevelGuideProgressType.SuccessProgress;
triggerCondition = new ConditionModifier(ConditionUtil.LevelGuideConditionFilter);
finishCondition = new ConditionModifier(ConditionUtil.LevelGuideEndConditionFilter);
}
[OnDeserialized]
public void OnAfterDeserialize(StreamingContext context)
{
triggerCondition.SetFilterTypes(ConditionUtil.LevelGuideConditionFilter);
finishCondition.SetFilterTypes(ConditionUtil.LevelGuideEndConditionFilter);
}
}
/// <summary>
/// 关卡立标引导
/// </summary>
[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;
[LabelText("触发条件")] public ConditionModifier triggerCondition;
[LabelText("完成条件")] public ConditionModifier finishCondition;
public SetFlagGuideData(SetFlagGuideData data)
{
setFlagType = data.setFlagType;
unitType = data.unitType;
setFlagID = data.setFlagID;
setFlagKey = data.setFlagKey;
guideTagID = data.guideTagID;
guideTagPath = data.guideTagPath;
triggerCondition = data.triggerCondition;
finishCondition = data.finishCondition;
}
public SetFlagGuideData()
{
setFlagType = ELevelGuideSetFlagType.CellIndex;
unitType = ESetFlagUnitType.Self;
setFlagID = -1;
triggerCondition = new ConditionModifier(ConditionUtil.LevelGuideConditionFilter);
finishCondition = new ConditionModifier(ConditionUtil.LevelGuideEndConditionFilter);
}
[OnDeserialized]
public void OnAfterDeserialize(StreamingContext context)
{
triggerCondition.SetFilterTypes(ConditionUtil.LevelGuideConditionFilter);
finishCondition.SetFilterTypes(ConditionUtil.LevelGuideEndConditionFilter);
}
}
/// <summary>
/// 关卡信息面板引导
/// </summary>
[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; // 策划使用备注
[LabelText("触发条件")] public ConditionModifier triggerCondition;
[LabelText("完成条件")] public ConditionModifier finishCondition;
public InfoPanelGuideData(InfoPanelGuideData data)
{
titleKey = data.titleKey;
contentKey = data.contentKey;
triggerCondition = data.triggerCondition;
finishCondition = data.finishCondition;
}
public InfoPanelGuideData()
{
triggerCondition = new ConditionModifier(ConditionUtil.LevelGuideConditionFilter);
finishCondition = new ConditionModifier(ConditionUtil.LevelGuideEndConditionFilter);
}
[OnDeserialized]
public void OnAfterDeserialize(StreamingContext context)
{
triggerCondition.SetFilterTypes(ConditionUtil.LevelGuideConditionFilter);
finishCondition.SetFilterTypes(ConditionUtil.LevelGuideEndConditionFilter);
}
}
#endregion
#region 关卡AI广播
/// <summary>
/// AI广播对象类型
/// </summary>
public enum E_AIBroadcastTargetType
{
[LabelText("怪物组")]
EnemyGroup,
[LabelText("所有怪物,包括未出生的")]
AllEnemy,
[LabelText("所有怪物,不包括未出生的")]
AllCurEnemy,
[LabelText("怪物")]
Enemy,
}
/// <summary>
/// AI行为目标类型
/// </summary>
public enum E_AIActionTarget
{
[LabelText("单位目标")]
Unit,
[LabelText("建筑目标")]
Build,
[LabelText("地格目标")]
Cell,
[LabelText("区域目标")]
Area,
[LabelText("路径ID")]
Path,
}
/// <summary>
/// AI预设切换类型
/// </summary>
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,
}
/// <summary>
/// AI广播数据
/// </summary>
[Serializable]
public sealed class AIBroadcastData
{
[LabelText("触发条件")]
public ConditionModifier triggerCondition;
[LabelText("AI广播对象类型")]
public E_AIBroadcastTargetType aiBroadcastTargetType;
[LabelText("目标id列表")]
[ShowIf("@E_AIBroadcastTargetType.EnemyGroup == aiBroadcastTargetType || E_AIBroadcastTargetType.Enemy == aiBroadcastTargetType")]
public List<int> listTargetId;
[LabelText("AI行为")]
public EAIAction AIAction;
[LabelText("AI行为目标")]
[ShowIf("@EAIAction.None != AIAction")]
public E_AIActionTarget AIActionTarget;
[LabelText("单位目标id")]
[ShowIf("@EAIAction.None != AIAction")]
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<int> 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()
{
triggerCondition = new ConditionModifier();
}
}
#endregion
/// <summary>
/// 角色方向(兼容老方向)
/// </summary>
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,
}
// TODO 删除 PVP行为树还在使用
public enum AIType
{
BasicAI,
FallBackAI,
FallBackIntensifyAI,
OutflankAI,
DefendAI,
StupidDefendAI,
None,
}
// TODO 删除 PVP行为树还在使用
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;
[BoxGroup("支线")] [LabelText("设置该关卡为评分关卡")]
public bool scoreLevel = false;
[BoxGroup("支线")]
[LabelText("星级目标"), HideIf("scoreLevel")]
[ListDrawerSettings(HideAddButton = true, HideRemoveButton = true)]
public List<ConditionModifier> starTarget = new()
{
new ConditionModifier(ConditionUtil.LevelStarConditionFilter),
new ConditionModifier(ConditionUtil.LevelStarConditionFilter),
new ConditionModifier(ConditionUtil.LevelStarConditionFilter)
};
[BoxGroup("支线")]
[LabelText("评分目标"), ShowIf("scoreLevel")]
[ListDrawerSettings(CustomAddFunction = "OnAddScoreCondition")]
public List<ConditionModifier> scoreTarget = new List<ConditionModifier>(15);
private void OnAddScoreCondition()
{
ConditionModifier conditionModifier = new();
conditionModifier.SetFilterTypes(ConditionUtil.LevelScoreConditionFilter, true);
scoreTarget.Add(conditionModifier);
}
[BoxGroup("防守相关设置")] [LabelText("防守关卡数据")]
public List<SpawnMonsterData> spawnMonsterDatas;
[BoxGroup("防守相关设置")] [LabelText("波次横幅显示数据")] [ListDrawerSettings(CustomAddFunction = "OnAddWaveInfoData")]
public List<WaveInfoData> waveInfoDatas = new();
private void OnAddWaveInfoData()
{
var waveInfoData = new WaveInfoData
{
localID = waveInfoDatas.Count + 1
};
waveInfoDatas.Add(waveInfoData);
}
[BoxGroup("触发器")] [LabelText("关卡触发器")] public List<LevelTriggerData> levelTriggerDatas;
[BoxGroup("特殊需求")] [LabelText("初始生命百分值")]
public float initialHealthPercent = 1.0f;
[BoxGroup("特殊需求")] [LabelText("初始护盾百分值")]
public float initialShieldPercent = 1.0f;
#region 关卡引导
[HideInInspector] [LabelText("关卡进度")] public List<ProgressGuideData> progressGuideDatas = new();
[HideInInspector] [LabelText("立标数据")] public List<SetFlagGuideData> setFlagGuideDatas = new();
[HideInInspector] [LabelText("信息板数据")] public List<InfoPanelGuideData> infoPanelGuideDatas = new();
#endregion
#region 关卡AI广播
[HideInInspector]
[LabelText("关卡AI广播进度")]
public List<AIBroadcastData> listAIBroadcastData = new();
#endregion
/// <summary>
/// 刷新生成点位
/// </summary>
[HideInInspector] public List<int> refreshPoints = new List<int>();
[HideInInspector] public List<NPCInfo> npcInfos = new();
[HideInInspector] public List<NPCInfo> midNpcInfos = new();
[HideInInspector] public List<NPCInfo> selfNpcInfos = new();
[HideInInspector] public Dictionary<int, List<int>> npcGroupInfos = new();
/// <summary>
/// 阻挡攻击数据
/// </summary>
[HideInInspector] public List<MapData.BlockSphereInfo> BlockSphereInfos = new();
[Serializable]
public class CaptureInfo
{
[LabelText("占领点位")] public int CapturePoint;
[LabelText("占领时间")] public int CaptureProgress = 0;
}
[HideInInspector] public List<CaptureInfo> CapturePoints = new(8);
[HideInInspector] public List<int> flagStartPoints = new List<int>();
[HideInInspector] public List<int> flagEndPoints = new List<int>();
[HideInInspector] public List<int> fallbackSinglePoints = new List<int>();
[HideInInspector] public List<int> fallbackReusablePoints = new List<int>();
[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);
}
}
}
}