using Godot; using System; public partial class Wretched : CharacterBody2D { [Signal] public delegate void KilledEventHandler(); public enum State { Waiting, Moving, Attack } public enum SideFace { Left, Up, Right, Down } [Export] public SideFace Facing = SideFace.Down; [Export] public float MovingSpeed = 32f; [Export] public bool IsAlive = true; public State CurrentState { get => _state; private set { _state = value; _timeSinceState = 0; switch (_state) { case State.Waiting: break; case State.Moving: break; case State.Attack: break; } } } private State _state; private float _timeSinceState; private AnimatedSprite2D _sprite; private NavigationAgent2D _nav; private bool _isActivated; public override void _Ready() { _sprite = (AnimatedSprite2D)FindChild("AnimatedSprite2D"); _nav = (NavigationAgent2D)FindChild("NavigationAgent2D"); _nav.VelocityComputed += OnNavVelocityCompute; CurrentState = State.Waiting; var animationName = "NonActivatedSide"; switch (Facing) { case SideFace.Left: _sprite.FlipH = true; break; case SideFace.Right: break; case SideFace.Up: animationName = "NonActivatedUp"; break; case SideFace.Down: animationName = "NonActivatedDown"; break; } _sprite.Play(animationName); _sprite.Stop(); } public override void _Process(double delta) { } public override void _PhysicsProcess(double delta) { if (!IsAlive) return; _timeSinceState += (float)delta; switch (_state) { case State.Attack: break; case State.Waiting: break; case State.Moving: _nav.TargetPosition = Player.Instance.Position; var direction = (_nav.GetNextPathPosition() - Position).Normalized(); var animationName = "ActivatedSide"; if (Velocity.Y > 0.001f) animationName = "ActivatedDown"; else if (Velocity.Y < 0.001f) animationName = "ActivatedUp"; if (Mathf.Abs(Velocity.X) >= Mathf.Abs(Velocity.Y)) animationName = "ActivatedSide"; _sprite.FlipH = Velocity.X < 0.001f && animationName == "ActivatedSide"; _sprite.Play(animationName); _nav.Velocity = direction * MovingSpeed; MoveAndSlide(); break; } CheckIfLitUp(); } private void _OnLightEntered(Area2D area) { if (area.GetParentOrNull() is null) return; _isActivated = true; } private void _OnPlayerCollision(Node2D body) { if (body is not Player player) return; if (CurrentState is State.Waiting) return; player.Kill(this); } void CheckIfLitUp() { if (!_isActivated) { CurrentState = State.Waiting; return; } if (CurrentState is State.Moving or State.Attack) return; CurrentState = State.Moving; } public void Kill(Node2D killer) { if (!IsAlive) return; GD.Print($"{this.Name} was killed by {killer.Name}"); IsAlive = false; EmitSignal(SignalName.Killed); QueueFree(); // TODO } private void OnNavVelocityCompute(Vector2 safeVelocity) { Velocity = safeVelocity; } }