using Godot; using RogueTank.Combat; using RogueTank.Util; namespace RogueTank.Actors; public partial class EnemyTank : CharacterBody2D, IDamageable { [Signal] public delegate void DiedEventHandler(EnemyTank who); public float MoveSpeed { get; set; } = 110f; public float MaxHp { get; set; } = 30f; public float Hp { get; private set; } = 30f; public float ContactDamage { get; set; } = 8f; public Node2D? Target { get; set; } private Sprite2D _sprite = null!; public override void _Ready() { Hp = MaxHp; _sprite = new Sprite2D { Texture = PixelArt.MakeTankTexture(16, new Color(0.75f, 0.2f, 0.2f), new Color(0.95f, 0.7f, 0.2f)), Centered = true, TextureFilter = CanvasItem.TextureFilterEnum.Nearest }; AddChild(_sprite); var col = new CollisionShape2D { Shape = new CircleShape2D { Radius = 7f } }; AddChild(col); } public override void _PhysicsProcess(double delta) { if (Target == null || !IsInstanceValid(Target)) { Velocity = Vector2.Zero; MoveAndSlide(); return; } var dir = (Target.GlobalPosition - GlobalPosition); if (dir.Length() > 1f) dir = dir.Normalized(); Velocity = dir * MoveSpeed; Rotation = Velocity.Angle(); MoveAndSlide(); // crude contact damage if (Target is PlayerTank p) { var dist = (p.GlobalPosition - GlobalPosition).Length(); if (dist < 14f) p.TakeDamage(ContactDamage * (float)delta); } } public void TakeDamage(float amount) { Hp -= amount; if (Hp <= 0f) { EmitSignal(SignalName.Died, this); QueueFree(); } } }