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