using Cirno.Scripts; using Godot; using System; using System.Diagnostics; public partial class Enemy : Area2D, IDestructible { private InteractionController _cachedPlayer; private EnemyState _currentState = EnemyState.Idle; [Export] public PackedScene BulletScene { get; set; } [Export] public float Health = 4f; [Export] public double RateOfFire = 0.4f; private float _currentHealth = 0f; private bool _isDestroyed = false; private Timer _cooldownTimer; // Called when the node enters the scene tree for the first time. public override void _Ready() { _currentHealth = Health; _cooldownTimer = GetNode("./ShootTimer"); } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { switch (_currentState) { case EnemyState.Idle: break; case EnemyState.Primed: // Have the raycast follow the player and shoot if visible //HandlePlayerDetection(); break; //case EnemyState.Shooting: // Shoot //break; default: break; } } public override void _PhysicsProcess(double delta) { HandlePlayerDetection(); } private void HandlePlayerDetection() { if (_cachedPlayer == null || _currentState is not EnemyState.Primed) { return; } if (_cooldownTimer.IsStopped() && IsPlayerInSight()) { // SHOOT var bullet = this.CreateChild(BulletScene); // var bullet = BulletScene.Instantiate(); // Owner.AddChild(bullet); // bullet.Transform = this.GlobalTransform; // bullet.Position = this.Position; bullet.SetDirection((_cachedPlayer.GlobalPosition - this.GlobalPosition).Normalized()); _cooldownTimer.Start(RateOfFire); } } private bool IsPlayerInSight() { var spaceState = GetWorld2D().DirectSpaceState; var query = PhysicsRayQueryParameters2D.Create(this.GlobalPosition, _cachedPlayer.GlobalPosition, CollisionMask, new Godot.Collections.Array { GetRid() }); var result = spaceState.IntersectRay(query); // If count is 0 then the player is in sight, otherwise there is level geometry in the way return result.Count == 0; // if (result.Count > 0) // GD.Print("Hit at point: ", result["position"]); } private void _on_player_detection_area_entered(Area2D area) { // Assume area is player for now if (area is InteractionController player) { Debug.WriteLine("Enemy detection area Entered by interaction controller"); _cachedPlayer = player; 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; } } // Bullets collision private void _on_area_entered(Area2D area) { } public void Hit(float damage) { if (_isDestroyed) return; _currentHealth -= damage; if (!(_currentHealth <= 0)) return; _isDestroyed = true; Explode(); } private void Explode() { Debug.WriteLine("Ded"); //CreateParticles(); //CreateDebris(); QueueFree(); } public bool IsDestroyed() { return _isDestroyed; } private enum EnemyState { Idle, Primed } }