Newer
Older
DungeonShooting / DungeonShooting_Godot / src / game / activity / role / enemy / Enemy.cs
@小李xl 小李xl on 28 Mar 2024 6 KB 调整角色出生位置
  1.  
  2. using System;
  3. using System.Collections.Generic;
  4. using Config;
  5. using AiState;
  6. using Godot;
  7.  
  8. /// <summary>
  9. /// 敌人,可以携带武器
  10. /// </summary>
  11. [Tool]
  12. public partial class Enemy : AiRole
  13. {
  14. /// <summary>
  15. /// 敌人属性
  16. /// </summary>
  17. private ExcelConfig.EnemyBase _enemyAttribute;
  18.  
  19. private static bool _init = false;
  20. private static Dictionary<string, ExcelConfig.EnemyBase> _enemyAttributeMap =
  21. new Dictionary<string, ExcelConfig.EnemyBase>();
  22. /// <summary>
  23. /// 初始化敌人属性数据
  24. /// </summary>
  25. public static void InitEnemyAttribute()
  26. {
  27. if (_init)
  28. {
  29. return;
  30. }
  31.  
  32. _init = true;
  33. foreach (var enemyAttr in ExcelConfig.EnemyBase_List)
  34. {
  35. if (enemyAttr.Activity != null)
  36. {
  37. if (!_enemyAttributeMap.TryAdd(enemyAttr.Activity.Id, enemyAttr))
  38. {
  39. Debug.LogError("发现重复注册的敌人属性: " + enemyAttr.Id);
  40. }
  41. }
  42. }
  43. }
  44.  
  45. /// <summary>
  46. /// 根据 ActivityBase.Id 获取对应敌人的属性数据
  47. /// </summary>
  48. public static ExcelConfig.EnemyBase GetEnemyAttribute(string itemId)
  49. {
  50. if (itemId == null)
  51. {
  52. return null;
  53. }
  54. if (_enemyAttributeMap.TryGetValue(itemId, out var attr))
  55. {
  56. return attr;
  57. }
  58.  
  59. throw new Exception($"敌人'{itemId}'没有在 EnemyBase 表中配置属性数据!");
  60. }
  61. public override void OnInit()
  62. {
  63. base.OnInit();
  64.  
  65. AttackLayer = PhysicsLayer.Obstacle | PhysicsLayer.Player;
  66. EnemyLayer = PhysicsLayer.Player;
  67. Camp = CampEnum.Camp2;
  68.  
  69. RoleState.MoveSpeed = 20;
  70.  
  71. MaxHp = 20;
  72. Hp = 20;
  73. }
  74.  
  75. protected override RoleState OnCreateRoleState()
  76. {
  77. var roleState = new RoleState();
  78. var enemyBase = GetEnemyAttribute(ActivityBase.Id).Clone();
  79. _enemyAttribute = enemyBase;
  80.  
  81. MaxHp = enemyBase.Hp;
  82. Hp = enemyBase.Hp;
  83. roleState.CanPickUpWeapon = enemyBase.CanPickUpWeapon;
  84. roleState.MoveSpeed = enemyBase.MoveSpeed;
  85. roleState.Acceleration = enemyBase.Acceleration;
  86. roleState.Friction = enemyBase.Friction;
  87. ViewRange = enemyBase.ViewRange;
  88. TailAfterViewRange = enemyBase.TailAfterViewRange;
  89. BackViewRange = enemyBase.BackViewRange;
  90. AttackInterval = enemyBase.AttackInterval;
  91. roleState.Gold = Mathf.Max(0, Utils.Random.RandomConfigRange(enemyBase.Gold));
  92. return roleState;
  93. }
  94.  
  95. public override void EnterTree()
  96. {
  97. if (!World.Enemy_InstanceList.Contains(this))
  98. {
  99. World.Enemy_InstanceList.Add(this);
  100. }
  101. }
  102.  
  103. public override void ExitTree()
  104. {
  105. World.Enemy_InstanceList.Remove(this);
  106. }
  107.  
  108. protected override void OnDie()
  109. {
  110. var effPos = Position + new Vector2(0, -Altitude);
  111. //血液特效
  112. var blood = ObjectManager.GetPoolItem<AutoDestroyParticles>(ResourcePath.prefab_effect_enemy_EnemyBlood0001_tscn);
  113. blood.Position = effPos - new Vector2(0, 12);
  114. blood.AddToActivityRoot(RoomLayerEnum.NormalLayer);
  115. blood.PlayEffect();
  116. var realVelocity = GetRealVelocity();
  117. //创建敌人碎片
  118. var count = Utils.Random.RandomRangeInt(3, 6);
  119. for (var i = 0; i < count; i++)
  120. {
  121. var debris = Create(Ids.Id_enemy_dead0001);
  122. debris.PutDown(effPos, RoomLayerEnum.NormalLayer);
  123. debris.MoveController.AddForce(Velocity + realVelocity);
  124. }
  125. //派发敌人死亡信号
  126. EventManager.EmitEvent(EventEnum.OnEnemyDie, this);
  127. base.OnDie();
  128. }
  129.  
  130. protected override void Process(float delta)
  131. {
  132. base.Process(delta);
  133. if (IsDie)
  134. {
  135. return;
  136. }
  137. //看向目标
  138. if (LookTarget != null && MountLookTarget)
  139. {
  140. var pos = LookTarget.Position;
  141. LookPosition = pos;
  142. //脸的朝向
  143. var gPos = Position;
  144. if (pos.X > gPos.X && Face == FaceDirection.Left)
  145. {
  146. Face = FaceDirection.Right;
  147. }
  148. else if (pos.X < gPos.X && Face == FaceDirection.Right)
  149. {
  150. Face = FaceDirection.Left;
  151. }
  152. //枪口跟随目标
  153. MountPoint.SetLookAt(pos);
  154. }
  155.  
  156. if (RoleState.CanPickUpWeapon)
  157. {
  158. //拾起武器操作
  159. DoPickUpWeapon();
  160. }
  161. }
  162.  
  163. public override bool IsAllWeaponTotalAmmoEmpty()
  164. {
  165. if (!_enemyAttribute.CanPickUpWeapon)
  166. {
  167. return false;
  168. }
  169. return base.IsAllWeaponTotalAmmoEmpty();
  170. }
  171.  
  172. protected override void OnHit(ActivityObject target, int damage, float angle, bool realHarm)
  173. {
  174. //受到伤害
  175. var state = StateController.CurrState;
  176. if (state == AIStateEnum.AiNormal)
  177. {
  178. LookTarget = target;
  179. //判断是否进入通知状态
  180. if (World.Enemy_InstanceList.FindIndex(enemy =>
  181. enemy != this && !enemy.IsDie && enemy.AffiliationArea == AffiliationArea &&
  182. enemy.StateController.CurrState == AIStateEnum.AiNormal) != -1)
  183. {
  184. //进入惊讶状态, 然后再进入通知状态
  185. StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiNotify);
  186. }
  187. else
  188. {
  189. //进入惊讶状态, 然后再进入跟随状态
  190. StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter);
  191. }
  192. }
  193. else if (state == AIStateEnum.AiLeaveFor)
  194. {
  195. LookTarget = target;
  196. StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiTailAfter);
  197. }
  198. else if (state == AIStateEnum.AiFindAmmo)
  199. {
  200. if (LookTarget == null)
  201. {
  202. LookTarget = target;
  203. var findAmmo = (AiFindAmmoState)StateController.CurrStateBase;
  204. StateController.ChangeState(AIStateEnum.AiAstonished, AIStateEnum.AiFindAmmo, findAmmo.TargetWeapon);
  205. }
  206. }
  207. }
  208.  
  209. /// <summary>
  210. /// 从标记出生时调用, 预加载波不会调用
  211. /// </summary>
  212. public virtual void OnBornFromMark()
  213. {
  214. //罚站 0.7 秒
  215. StateController.Enable = false;
  216. this.CallDelay(0.7f, () => StateController.Enable = true);
  217. }
  218. }