using Cirno.Scripts.Components.Actors; using Cirno.Scripts.Enums; using Godot; namespace Cirno.Scripts.Components.FSM.Enemy.Turret; public partial class TurretAlert : EnemyStateBase { public override EnemyState StateId => EnemyState.Alert; [Export] public EnemyStorageModule StorageModule { get; private set; } [Export] public PlayerDetectionModule PlayerDetection { get; private set; } [Export] public GenericDamageReceiver DamageReceiver { get; private set; } private bool _isPlayerInRange = false; public override void EnterState() { base.EnterState(); PlayerDetection.SetRange(StorageModule.Root.EnemyResource.PlayerDetectionRange); PlayerDetection.PlayerInRange += PlayerDetectionOnPlayerInRange; PlayerDetection.PlayerOutOfRange += PlayerDetectionOnPlayerOutOfRange; DamageReceiver.ChangeState(true); DamageReceiver.HealthProvider.ResourceDepleted += HealthProviderOnResourceDepleted; } private void HealthProviderOnResourceDepleted() { ChangeState(EnemyState.Dead); } private void PlayerDetectionOnPlayerOutOfRange() { _isPlayerInRange = false; } public override void ExitState() { base.ExitState(); PlayerDetection.PlayerInRange -= PlayerDetectionOnPlayerInRange; PlayerDetection.PlayerOutOfRange -= PlayerDetectionOnPlayerOutOfRange; DamageReceiver.HealthProvider.ResourceDepleted -= HealthProviderOnResourceDepleted; DamageReceiver.ChangeState(false); } private void PlayerDetectionOnPlayerInRange() { } public override void PhysicsProcessState(double delta) { base.PhysicsProcessState(delta); if (PlayerDetection.IsPlayerInRange(StorageModule.Root.EnemyResource.ViewRange) && PlayerDetection.IsPlayerInSight()) { StateMachine.SetState(EnemyState.Shooting); return; } // if player is outside disengage range, change to idle (later on, search) if (this.GlobalPosition.DistanceTo(GameManager.Instance.PlayerPosition.Value) >= StorageModule.Root.EnemyResource.PlayerDisengageRange) { StateMachine.SetState(EnemyState.Idle); return; } // Set facing direction towards player if (PlayerDetection.LastKnownPlayerPosition.HasValue) { StorageModule.FacingDirection = (PlayerDetection.LastKnownPlayerPosition.Value - MainObject.GlobalPosition).Normalized(); //MainObject.Velocity.SnapToCardinal().Normalized(); StorageModule.AimingDirection = StorageModule.FacingDirection; } } public override void ProcessState(double delta) { base.ProcessState(delta); } }