diff --git a/Scripts/Enemy.cs b/Scripts/Enemy.cs index 37dd2f0f..1ccf6c68 100644 --- a/Scripts/Enemy.cs +++ b/Scripts/Enemy.cs @@ -12,6 +12,8 @@ public partial class Enemy : CharacterBody2D [Export] public float WalkSpeed = 2500f; + [Export] public float PlayerDisengageRange = 500f; + [Export] public Weapon EquippedWeapon; private float _currentHealth = 0f; @@ -20,6 +22,10 @@ public partial class Enemy : CharacterBody2D private NavigationAgent2D _navigationAgent; + private bool _isPlayerInRange = false; + + private Vector2? _lastPlayerPosition = null; + [Export] public bool NavigationEnabled { get; set; } = false; // Called when the node enters the scene tree for the first time. @@ -29,13 +35,13 @@ public partial class Enemy : CharacterBody2D _navigationAgent = GetNode("NavigationAgent2D"); - CallDeferred("Setup"); + //CallDeferred("Setup"); } - private void Setup() - { - - } + // private void Setup() + // { + // + // } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) @@ -45,10 +51,7 @@ public partial class Enemy : CharacterBody2D case EnemyState.Idle: break; - - case EnemyState.Primed: - // Have the raycast follow the player and shoot if visible - //HandlePlayerDetection(); + case EnemyState.Alert: break; //case EnemyState.Shooting: @@ -61,17 +64,29 @@ public partial class Enemy : CharacterBody2D public override void _PhysicsProcess(double delta) { - if (NavigationEnabled) + switch (_currentState) { - // Only do these actions if the enemy has been alerted - if (_currentState is EnemyState.Primed) - { - _navigationAgent.SetTargetPosition(_cachedPlayer.GlobalPosition); + case EnemyState.Idle: + HandlePlayerDetection(); + + break; + case EnemyState.Alert: + + // Update last known player position if it's in range + if (_isPlayerInRange) + { + _lastPlayerPosition = _cachedPlayer.GlobalPosition; + } + + if (_lastPlayerPosition.HasValue) + { + _navigationAgent.SetTargetPosition(_lastPlayerPosition.Value); + } var currentAgentPosition = GlobalPosition; var nextPathPosition = _navigationAgent.GetNextPathPosition(); - + var newVelocity = currentAgentPosition.DirectionTo(nextPathPosition) * (float)(WalkSpeed * delta); @@ -79,7 +94,10 @@ public partial class Enemy : CharacterBody2D if (_navigationAgent.IsNavigationFinished()) { // Shoot player - HandlePlayerDetection(); + Shoot(); + + // TODO: If player totally left the max range it should stop shooting and go back to idle + return; } @@ -95,7 +113,11 @@ public partial class Enemy : CharacterBody2D MoveAndSlide(); - } + break; + case EnemyState.Patrolling: + break; + default: + throw new ArgumentOutOfRangeException(); } } @@ -107,7 +129,7 @@ public partial class Enemy : CharacterBody2D private void HandlePlayerDetection() { - if (_cachedPlayer == null || _currentState is not EnemyState.Primed) + if (_cachedPlayer == null) { return; } @@ -119,17 +141,18 @@ public partial class Enemy : CharacterBody2D // { // _navigationAgent.SetTargetPosition(_cachedPlayer.GlobalPosition); // } - Shoot(); - + //Shoot(); + _currentState = EnemyState.Alert; } } private void Shoot() { - if (EquippedWeapon == null) return; + if (EquippedWeapon == null || !_lastPlayerPosition.HasValue) return; - EquippedWeapon.ShootDirection = (_cachedPlayer.GlobalPosition - this.GlobalPosition).Normalized(); + // Shoot at the player's last known position + EquippedWeapon.ShootDirection = (_lastPlayerPosition.Value - this.GlobalPosition).Normalized(); EquippedWeapon.Shoot(); @@ -176,19 +199,23 @@ public partial class Enemy : CharacterBody2D Debug.WriteLine("Enemy detection area Entered by interaction controller"); _cachedPlayer = player; - if (_currentState is EnemyState.Idle) - { - _currentState = EnemyState.Primed; - } + + _isPlayerInRange = true; + // if (_currentState is EnemyState.Idle) + // { + // _currentState = EnemyState.Primed; + // } } } private void _on_player_detection_area_exited(Area2D area) { - if (_currentState is EnemyState.Primed) - { - _currentState = EnemyState.Idle; - } + _isPlayerInRange = false; + + // if (_currentState is EnemyState.Primed) + // { + // _currentState = EnemyState.Idle; + // } } private void _on_damage_hitbox_area_entered(Area2D area) @@ -231,7 +258,7 @@ public partial class Enemy : CharacterBody2D private enum EnemyState { Idle, - Primed, + Alert, Patrolling } }