diff --git a/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj b/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj index 9a963c3..d171c69 100644 --- a/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj +++ b/DungeonShooting_ExcelTool/DungeonShooting_ExcelTool.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net7.0 enable enable diff --git a/DungeonShooting_ExcelTool/ExcelGenerator.cs b/DungeonShooting_ExcelTool/ExcelGenerator.cs index b400039..d76af05 100644 --- a/DungeonShooting_ExcelTool/ExcelGenerator.cs +++ b/DungeonShooting_ExcelTool/ExcelGenerator.cs @@ -578,9 +578,20 @@ return false; } - return cell.BooleanCellValue; + if (cell.CellType == CellType.Boolean) + { + return cell.BooleanCellValue; + } + + var value = cell.StringCellValue; + if (string.IsNullOrWhiteSpace(value)) + { + return false; + } + + return bool.Parse(value); } - + private static MappingData ConvertToType(string str, int depth = 0) { if (Regex.IsMatch(str, "^\\w+$")) diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json index df88148..98c2130 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.deps.json @@ -1,12 +1,12 @@ { "runtimeTarget": { - "name": ".NETCoreApp,Version=v6.0/win-x64", + "name": ".NETCoreApp,Version=v7.0/win-x64", "signature": "" }, "compilationOptions": {}, "targets": { - ".NETCoreApp,Version=v6.0": {}, - ".NETCoreApp,Version=v6.0/win-x64": { + ".NETCoreApp,Version=v7.0": {}, + ".NETCoreApp,Version=v7.0/win-x64": { "DungeonShooting_ExcelTool/1.0.0": { "dependencies": { "NPOI": "2.6.0" diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll index d8ba4b8..f91239a 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.dll Binary files differ diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe index bb1931a..9c2c323 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.exe Binary files differ diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb index a963cf3..86422eb 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.pdb Binary files differ diff --git a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json index e7b3b03..398903e 100644 --- a/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json +++ b/DungeonShooting_Godot/excel/DungeonShooting_ExcelTool.runtimeconfig.json @@ -1,9 +1,9 @@ { "runtimeOptions": { - "tfm": "net6.0", + "tfm": "net7.0", "framework": { "name": "Microsoft.NETCore.App", - "version": "6.0.0" + "version": "7.0.0" }, "configProperties": { "System.Reflection.Metadata.MetadataUpdater.IsSupported": false diff --git a/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx b/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx index 0dc2ea0..737ead8 100644 --- a/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/ActivityObject.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx new file mode 100644 index 0000000..80efe6f --- /dev/null +++ b/DungeonShooting_Godot/excel/excelFile/AiAttackAttr.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx index 31ff6a4..8aad412 100644 --- a/DungeonShooting_Godot/excel/excelFile/Sound.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/Sound.xlsx Binary files differ diff --git a/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx b/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx index 494a8e2..07cf38d 100644 --- a/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx +++ b/DungeonShooting_Godot/excel/excelFile/Weapon.xlsx Binary files differ diff --git a/DungeonShooting_Godot/resource/config/AiAttackAttr.json b/DungeonShooting_Godot/resource/config/AiAttackAttr.json new file mode 100644 index 0000000..9505e7d --- /dev/null +++ b/DungeonShooting_Godot/resource/config/AiAttackAttr.json @@ -0,0 +1,42 @@ +[ + { + "Id": "0001", + "Remark": "", + "FiringStand": true, + "LockingTime": 0.5, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0002", + "Remark": "", + "FiringStand": true, + "LockingTime": 2, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0003", + "Remark": "", + "FiringStand": true, + "LockingTime": 1, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0004", + "Remark": "", + "FiringStand": true, + "LockingTime": 0.7, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + }, + { + "Id": "0005", + "Remark": "", + "FiringStand": true, + "LockingTime": 1.5, + "BulletSpeedScale": 0.35, + "AmmoConsumptionProbability": 0 + } +] \ No newline at end of file diff --git a/DungeonShooting_Godot/resource/config/Weapon.json b/DungeonShooting_Godot/resource/config/Weapon.json index 57bbf71..8bea3fb 100644 --- a/DungeonShooting_Godot/resource/config/Weapon.json +++ b/DungeonShooting_Godot/resource/config/Weapon.json @@ -88,9 +88,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0002", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0002", @@ -181,9 +179,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0001" }, { "Id": "0003", @@ -275,9 +271,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0004", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0004", @@ -369,9 +363,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.4, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0002" }, { "Id": "0005", @@ -462,9 +454,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0006", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0006", @@ -555,9 +545,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 1, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0003" }, { "Id": "0007", @@ -645,9 +633,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0008", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0008", @@ -735,9 +721,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.7, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0004" }, { "Id": "0009", @@ -828,9 +812,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0010", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0010", @@ -921,9 +903,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 1.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0005" }, { "Id": "0011", @@ -1014,9 +994,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0012", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0012", @@ -1107,9 +1085,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0005" }, { "Id": "0013", @@ -1200,9 +1176,7 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "0014", - "AiTargetLockingTime": 0, - "AiBulletSpeedScale": 0, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "" }, { "Id": "0014", @@ -1293,8 +1267,6 @@ "BeLoadedSoundDelayTime": 0, "__OtherSoundMap": null, "__AiUseAttribute": "", - "AiTargetLockingTime": 0.5, - "AiBulletSpeedScale": 0.5, - "AiAmmoConsumptionProbability": 0 + "__AiAttackAttr": "0005" } ] \ No newline at end of file diff --git a/DungeonShooting_Godot/src/config/ExcelConfig.cs b/DungeonShooting_Godot/src/config/ExcelConfig.cs index b0abf46..6416ead 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig.cs @@ -17,6 +17,15 @@ public static Dictionary ActivityObject_Map { get; private set; } /// + /// AiAttackAttr.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同 + /// + public static List AiAttackAttr_List { get; private set; } + /// + /// AiAttackAttr.xlsx表数据集合, 里 Map 形式存储, key 为 Id + /// + public static Dictionary AiAttackAttr_Map { get; private set; } + + /// /// Sound.xlsx表数据集合, 以 List 形式存储, 数据顺序与 Excel 表相同 /// public static List Sound_List { get; private set; } @@ -45,6 +54,7 @@ _init = true; _InitActivityObjectConfig(); + _InitAiAttackAttrConfig(); _InitSoundConfig(); _InitWeaponConfig(); @@ -68,6 +78,24 @@ throw new Exception("初始化表'ActivityObject'失败!"); } } + private static void _InitAiAttackAttrConfig() + { + try + { + var text = _ReadConfigAsText("res://resource/config/AiAttackAttr.json"); + AiAttackAttr_List = JsonSerializer.Deserialize>(text); + AiAttackAttr_Map = new Dictionary(); + foreach (var item in AiAttackAttr_List) + { + AiAttackAttr_Map.Add(item.Id, item); + } + } + catch (Exception e) + { + GD.PrintErr(e.ToString()); + throw new Exception("初始化表'AiAttackAttr'失败!"); + } + } private static void _InitSoundConfig() { try @@ -150,6 +178,11 @@ item.AiUseAttribute = Weapon_Map[item.__AiUseAttribute]; } + if (!string.IsNullOrEmpty(item.__AiAttackAttr)) + { + item.AiAttackAttr = AiAttackAttr_Map[item.__AiAttackAttr]; + } + } catch (Exception e) { diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs new file mode 100644 index 0000000..54483ea --- /dev/null +++ b/DungeonShooting_Godot/src/config/ExcelConfig_AiAttackAttr.cs @@ -0,0 +1,64 @@ +using System.Text.Json.Serialization; +using System.Collections.Generic; + +namespace Config; + +public static partial class ExcelConfig +{ + public class AiAttackAttr + { + /// + /// Id + /// + [JsonInclude] + public string Id; + + /// + /// 备注 + /// + [JsonInclude] + public string Remark; + + /// + /// 开火时是否站立不动 + /// + [JsonInclude] + public bool FiringStand; + + /// + /// Ai属性
+ /// 目标锁定时间, 也就是瞄准目标多久才会开火, (单位: 秒) + ///
+ [JsonInclude] + public float LockingTime; + + /// + /// Ai属性
+ /// Ai使用该武器发射的子弹速度缩放比 + ///
+ [JsonInclude] + public float BulletSpeedScale; + + /// + /// Ai属性
+ /// Ai使用该武器消耗弹药的概率, (0 - 1) + ///
+ [JsonInclude] + public float AmmoConsumptionProbability; + + /// + /// 返回浅拷贝出的新对象 + /// + public AiAttackAttr Clone() + { + var inst = new AiAttackAttr(); + inst.Id = Id; + inst.Remark = Remark; + inst.FiringStand = FiringStand; + inst.LockingTime = LockingTime; + inst.BulletSpeedScale = BulletSpeedScale; + inst.AmmoConsumptionProbability = AmmoConsumptionProbability; + return inst; + } + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs b/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs index 2496449..c9dd584 100644 --- a/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs +++ b/DungeonShooting_Godot/src/config/ExcelConfig_Weapon.cs @@ -392,25 +392,10 @@ public Weapon AiUseAttribute; /// - /// Ai属性
- /// 目标锁定时间, 也就是瞄准目标多久才会开火, (单位: 秒) + /// Ai使用该武器开火时的一些额外配置属性
+ /// 玩家使用的武器不需要填写该字段 ///
- [JsonInclude] - public float AiTargetLockingTime; - - /// - /// Ai属性
- /// Ai使用该武器发射的子弹速度缩放比 - ///
- [JsonInclude] - public float AiBulletSpeedScale; - - /// - /// Ai属性
- /// Ai使用该武器消耗弹药的概率, (0 - 1) - ///
- [JsonInclude] - public float AiAmmoConsumptionProbability; + public AiAttackAttr AiAttackAttr; /// /// 返回浅拷贝出的新对象 @@ -480,9 +465,7 @@ inst.BeLoadedSoundDelayTime = BeLoadedSoundDelayTime; inst.OtherSoundMap = OtherSoundMap; inst.AiUseAttribute = AiUseAttribute; - inst.AiTargetLockingTime = AiTargetLockingTime; - inst.AiBulletSpeedScale = AiBulletSpeedScale; - inst.AiAmmoConsumptionProbability = AiAmmoConsumptionProbability; + inst.AiAttackAttr = AiAttackAttr; return inst; } } @@ -509,5 +492,8 @@ [JsonInclude] public string __AiUseAttribute; + [JsonInclude] + public string __AiAttackAttr; + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs index 022a983..0cf2a33 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/Bullet.cs @@ -80,7 +80,7 @@ } else { - FlySpeed = speed * weapon.AiUseAttribute.AiBulletSpeedScale; + FlySpeed = speed * weapon.AiUseAttribute.AiAttackAttr.BulletSpeedScale; } MaxDistance = maxDistance; Position = position; diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackEnum.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackEnum.cs deleted file mode 100644 index f8e8b89..0000000 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackEnum.cs +++ /dev/null @@ -1,43 +0,0 @@ - -/// -/// 调用 Enemy.EnemyAttack() 函数返回的结果 -/// -public enum AiAttackEnum -{ - /// - /// 未触发 EnemyAttack() - /// - None, - /// - /// 触发切换武器 - /// - ExchangeWeapon, - /// - /// 没有弹药了 - /// - NoAmmo, - /// - /// 换弹中 - /// - Reloading, - /// - /// 触发换弹 - /// - TriggerReload, - /// - /// 没有武器 - /// - NoWeapon, - /// - /// 正在锁定目标中 - /// - LockingTime, - /// - /// 攻击间隙时间 - /// - AttackInterval, - /// - /// 成功触发攻击 - /// - Attack, -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs new file mode 100644 index 0000000..62bc132 --- /dev/null +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/AiAttackState.cs @@ -0,0 +1,43 @@ + +/// +/// 调用 Enemy.EnemyAttack() 函数返回的结果 +/// +public enum AiAttackState +{ + /// + /// 未触发 EnemyAttack() + /// + None, + /// + /// 触发切换武器 + /// + ExchangeWeapon, + /// + /// 没有弹药了 + /// + NoAmmo, + /// + /// 换弹中 + /// + Reloading, + /// + /// 触发换弹 + /// + TriggerReload, + /// + /// 没有武器 + /// + NoWeapon, + /// + /// 正在锁定目标中 + /// + LockingTime, + /// + /// 攻击间隙时间 + /// + AttackInterval, + /// + /// 成功触发攻击 + /// + Attack, +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs index 1e4fa21..37bbf3f 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/Enemy.cs @@ -53,7 +53,12 @@ /// 导航代理中点 /// public Marker2D NavigationPoint { get; private set; } - + + /// + /// Ai攻击状态, 调用 EnemyAttack() 函数后会刷新 + /// + public AiAttackState AttackState { get; private set; } + //锁定目标时间 private float _lockTargetTime = 0; @@ -292,22 +297,19 @@ } /// - /// Ai触发的攻击, 返回是否成功触发 Attack() 函数 + /// Ai触发的攻击 /// - public AiAttackEnum EnemyAttack(float delta) + public void EnemyAttack() { - AiAttackEnum flag; var weapon = WeaponPack.ActiveItem; if (weapon != null) { - flag = weapon.AiTriggerAttack(); + AttackState = weapon.AiTriggerAttackState(); } else //没有武器 { - flag = AiAttackEnum.NoWeapon; + AttackState = AiAttackState.NoWeapon; } - - return flag; } /// diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs index 424de97..be7c306 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiFollowUpState.cs @@ -15,8 +15,6 @@ //导航目标点刷新计时器 private float _navigationUpdateTimer = 0; private float _navigationInterval = 0.3f; - //Ai攻击状态 - private AiAttackEnum _attackEnum; public AiFollowUpState() : base(AiStateEnum.AiFollowUp) { @@ -77,7 +75,7 @@ if (!Master.NavigationAgent2D.IsNavigationFinished()) { - if (_attackEnum != AiAttackEnum.LockingTime && _attackEnum != AiAttackEnum.Attack) + if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack) { //计算移动 var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); @@ -108,12 +106,13 @@ IsInView = false; } - if (IsInView) + //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 + if (IsInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) { if (inAttackRange) //在攻击范围内 { //发起攻击 - _attackEnum = Master.EnemyAttack(delta); + Master.EnemyAttack(); //距离够近, 可以切换到环绕模式 if (Master.GlobalPosition.DistanceSquaredTo(playerPos) <= Mathf.Pow(Utils.GetConfigRangeStart(weapon.Attribute.BulletDistanceRange), 2) * 0.7f) @@ -122,7 +121,7 @@ } } } - else + else //不在视野中 { ChangeState(AiStateEnum.AiTailAfter); } diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs index 9b50208..ec11954 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiSurroundState.cs @@ -25,8 +25,6 @@ private Vector2 _prevPos; //卡在一个位置的时间 private float _lockTimer; - //Ai攻击状态 - private AiAttackEnum _attackEnum; public AiSurroundState() : base(AiStateEnum.AiSurround) { @@ -38,7 +36,6 @@ _isMoveOver = true; _pauseTimer = 0; _moveFlag = false; - _attackEnum = AiAttackEnum.None; } public override void Process(float delta) @@ -73,7 +70,8 @@ IsInView = false; } - if (IsInView) + //在视野中, 或者锁敌状态下, 或者攻击状态下, 继续保持原本逻辑 + if (IsInView || Master.AttackState == AiAttackState.LockingTime || Master.AttackState == AiAttackState.Attack) { if (_pauseTimer >= 0) { @@ -123,7 +121,7 @@ } else { - if (_attackEnum != AiAttackEnum.LockingTime && _attackEnum != AiAttackEnum.Attack) + if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack) { //计算移动 var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); @@ -158,7 +156,7 @@ else { //发起攻击 - _attackEnum = Master.EnemyAttack(delta); + Master.EnemyAttack(); } } } diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs index 455e4ae..6b04b6a 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/state/AiTailAfterState.cs @@ -63,11 +63,19 @@ if (!Master.NavigationAgent2D.IsNavigationFinished()) { - //计算移动 - var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); - Master.AnimatedSprite.Play(AnimatorNames.Run); - Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * - Master.RoleState.MoveSpeed; + if (Master.AttackState != AiAttackState.LockingTime && Master.AttackState != AiAttackState.Attack) + { + //计算移动 + var nextPos = Master.NavigationAgent2D.GetNextPathPosition(); + Master.AnimatedSprite.Play(AnimatorNames.Run); + Master.BasisVelocity = (nextPos - Master.GlobalPosition - Master.NavigationPoint.Position).Normalized() * + Master.RoleState.MoveSpeed; + } + else + { + Master.AnimatedSprite.Play(AnimatorNames.Idle); + Master.BasisVelocity = Vector2.Zero; + } } else { diff --git a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs index 1cc974a..94a9203 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/Weapon.cs @@ -938,7 +938,7 @@ //减子弹数量 if (_playerWeaponAttribute != _weaponAttribute) //Ai使用该武器, 有一定概率不消耗弹药 { - if (Utils.Random.RandomRangeFloat(0, 1) < _weaponAttribute.AiAmmoConsumptionProbability) //触发消耗弹药 + if (Utils.Random.RandomRangeFloat(0, 1) < _weaponAttribute.AiAttackAttr.AmmoConsumptionProbability) //触发消耗弹药 { CurrAmmo -= UseAmmoCount(); } @@ -1905,48 +1905,116 @@ //-------------------------------- Ai相关 ----------------------------- - public AiAttackEnum AiTriggerAttack() + /// + /// Ai 调用, 刷新 Ai 攻击状态并返回, 并不会调用相应的函数 + /// + public AiAttackState AiRefreshAttackState() { - AiAttackEnum flag; + AiAttackState flag; if (IsTotalAmmoEmpty()) //当前武器弹药打空 { //切换到有子弹的武器 var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty()); if (index != -1) { - flag = AiAttackEnum.ExchangeWeapon; - Master.WeaponPack.ExchangeByIndex(index); + flag = AiAttackState.ExchangeWeapon; } else //所有子弹打光 { - flag = AiAttackEnum.NoAmmo; + flag = AiAttackState.NoAmmo; } } else if (Reloading) //换弹中 { - flag = AiAttackEnum.TriggerReload; + flag = AiAttackState.TriggerReload; } else if (IsAmmoEmpty()) //弹夹已经打空 { - flag = AiAttackEnum.Reloading; - Reload(); + flag = AiAttackState.Reloading; } else if (_continuousCount >= 1) //连发中 { - flag = AiAttackEnum.Attack; + flag = AiAttackState.Attack; } else if (IsAttackIntervalTime()) //开火间隙 { - flag = AiAttackEnum.AttackInterval; + flag = AiAttackState.AttackInterval; } else { var enemy = (Enemy)Master; - if (enemy.GetLockTargetTime() >= Attribute.AiTargetLockingTime) //正常射击 + if (enemy.GetLockTargetTime() >= Attribute.AiAttackAttr.LockingTime) //正常射击 { if (GetDelayedAttackTime() > 0) { - flag = AiAttackEnum.Attack; + flag = AiAttackState.Attack; + } + else + { + if (Attribute.ContinuousShoot) //连发 + { + flag = AiAttackState.Attack; + } + else //单发 + { + flag = AiAttackState.Attack; + } + } + } + else //锁定时间没到 + { + flag = AiAttackState.LockingTime; + } + } + + return flag; + } + + /// + /// Ai调用, 触发扣动扳机, 并返回攻击状态 + /// + public AiAttackState AiTriggerAttackState() + { + AiAttackState flag; + if (IsTotalAmmoEmpty()) //当前武器弹药打空 + { + //切换到有子弹的武器 + var index = Master.WeaponPack.FindIndex((we, i) => !we.IsTotalAmmoEmpty()); + if (index != -1) + { + flag = AiAttackState.ExchangeWeapon; + Master.WeaponPack.ExchangeByIndex(index); + } + else //所有子弹打光 + { + flag = AiAttackState.NoAmmo; + } + } + else if (Reloading) //换弹中 + { + flag = AiAttackState.TriggerReload; + } + else if (IsAmmoEmpty()) //弹夹已经打空 + { + flag = AiAttackState.Reloading; + Reload(); + } + else if (_continuousCount >= 1) //连发中 + { + flag = AiAttackState.Attack; + } + else if (IsAttackIntervalTime()) //开火间隙 + { + flag = AiAttackState.AttackInterval; + } + else + { + var enemy = (Enemy)Master; + if (enemy.GetLockTargetTime() >= Attribute.AiAttackAttr.LockingTime) //正常射击 + { + if (GetDelayedAttackTime() > 0) + { + flag = AiAttackState.Attack; enemy.Attack(); if (_attackFlag) { @@ -1957,7 +2025,7 @@ { if (Attribute.ContinuousShoot) //连发 { - flag = AiAttackEnum.Attack; + flag = AiAttackState.Attack; enemy.Attack(); if (_attackFlag) { @@ -1966,7 +2034,7 @@ } else //单发 { - flag = AiAttackEnum.Attack; + flag = AiAttackState.Attack; enemy.Attack(); if (_attackFlag) { @@ -1977,7 +2045,7 @@ } else //锁定时间没到 { - flag = AiAttackEnum.LockingTime; + flag = AiAttackState.LockingTime; } } diff --git a/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs b/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs index c5c36bd..d1f398d 100644 --- a/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs +++ b/DungeonShooting_Godot/src/game/activity/weapon/gun/Gun.cs @@ -29,17 +29,18 @@ ShootBullet(fireRotation, Attribute.BulletId); } - protected override void OnRemove(Role master) - { - base.OnRemove(master); - - if (master.IsDie && master.IsEnemyWithPlayer()) - { - this.CallDelay(0, () => - { - Debug.Log("敌人扔掉武器触发攻击"); - Trigger(master); - }); - } - } + // 测试用, 敌人被消灭时触发手上武器开火 + // protected override void OnRemove(Role master) + // { + // base.OnRemove(master); + // + // if (master.IsDie && master.IsEnemyWithPlayer()) + // { + // this.CallDelay(0, () => + // { + // Debug.Log("敌人扔掉武器触发攻击"); + // Trigger(master); + // }); + // } + // } } \ No newline at end of file