Enemy strafing

This commit is contained in:
MaddoScientisto 2025-03-23 18:22:12 +01:00
commit b35772f519
6 changed files with 112 additions and 16 deletions

View file

@ -17,10 +17,18 @@ public partial class Shooting : EnemyStateBase
[Export]
public GenericDamageReceiver DamageReceiver { get; private set; }
[Export]
public NavigationMovementModule NavigationModule { get; private set; }
[Export] public float MaxStrafeDistance { get; private set; } = 64f;
[Export] public float MinStrafeDistance { get; private set; } = 16f;
[Export] public Weapon EquippedWeapon;
private bool _isPlayerInRange = false;
private Vector2? _currentStrafeTarget = null;
public override void EnterState()
{
base.EnterState();
@ -35,6 +43,8 @@ public partial class Shooting : EnemyStateBase
DamageReceiver.HealthProvider.ResourceDepleted += HealthProviderOnResourceDepleted;
EquippedWeapon.WeaponData = StorageModule.Root.EnemyResource.Weapon;
_currentStrafeTarget = null;
// PlayerDetection.SetRange(StorageModule.Root.EnemyResource.PlayerDetectionRange);
//
// _isPlayerInRange = PlayerDetection.IsPlayerInRange(StorageModule.Root.EnemyResource.PlayerDetectionRange);
@ -67,6 +77,9 @@ public partial class Shooting : EnemyStateBase
PlayerDetection.PlayerOutOfRange -= PlayerDetectionOnPlayerOutOfRange;
DamageReceiver.HealthProvider.ResourceDepleted -= HealthProviderOnResourceDepleted;
_currentStrafeTarget = null;
DamageReceiver.ChangeState(false);
}
@ -79,14 +92,62 @@ public partial class Shooting : EnemyStateBase
{
// SHOOT
Shoot();
// Check if a strafe position is needed
if (!_currentStrafeTarget.HasValue || NavigationModule.IsNavigationFinished())
{
_currentStrafeTarget = CalculateStrafePosition();
}
}
else
{
StateMachine.SetState(EnemyState.Alert);
return;
}
// Strafe
if (_currentStrafeTarget.HasValue)
{
NavigationModule.SetTarget(_currentStrafeTarget.Value);
NavigationModule.Move();
}
}
private Vector2? CalculateStrafePosition()
{
Vector2 playerPos = PlayerDetection.LastKnownPlayerPosition.Value;
Vector2 enemyPos = MainObject.GlobalPosition;
// Calculate direction to player
Vector2 directionToPlayer = (playerPos - enemyPos).Normalized();
// Get perpendicular vectors (left and right strafing directions)
Vector2 leftStrafe = directionToPlayer.Rotated(-Mathf.Pi / 2);
Vector2 rightStrafe = directionToPlayer.Rotated(Mathf.Pi / 2);
// Randomly decide left or right first
bool tryLeftFirst = GD.Randf() < 0.5f;
for (float factor = 1f; factor > 0.25f; factor *= 0.75f)
{
float strafeDistance = Mathf.Lerp(MinStrafeDistance, MaxStrafeDistance, factor);
Vector2 newPos = enemyPos + (tryLeftFirst ? leftStrafe : rightStrafe) * strafeDistance;
if (NavigationModule.IsNavigable(newPos) && PlayerDetection.HasLineOfSight(newPos, playerPos))
{
return newPos;
}
}
for (float factor = 1f; factor > 0.25f; factor *= 0.75f)
{
float strafeDistance = Mathf.Lerp(MinStrafeDistance, MaxStrafeDistance, factor);
Vector2 newPos = enemyPos + (tryLeftFirst ? rightStrafe : leftStrafe) * strafeDistance;
if (NavigationModule.IsNavigable(newPos) && PlayerDetection.HasLineOfSight(newPos, playerPos))
{
return newPos;
}
}
return null; // No valid strafe position found
}
private void Shoot()