using Godot; public partial class ship : CharacterBody2D { public enum ShipType { FIGHTER, INTERCEPTOR, GUARDIAN } public enum ShipFaction {PLAYER, FRIENDLY, ENEMY, ACE} [Signal] public delegate void LaserShotEventHandler(Area2D laser); //[Export] //public Vector2 ScreenSize; [Export] public int Health { get; set; } [Export] public int MaxHealth { get; set; } [Export] public int MaxSpeed { get; set;} [Export] public int MainSpeed { get; set; } [Export] public int StrafeSpeed { get; set; } [Export] public float RotationSpeed { get; set; } [Export] public int Damage {get; set; } [Export] public float FireCooldown { get; set; } [Export] public ShipType Type; [Export] public ShipFaction Faction; [Export] public float StatModifier = 1f; protected Sprite2D Sprite = new Sprite2D(); protected Node2D LaserSpawn; protected float FireTimer = 0f; protected string SpritePath; protected int RotationDirection; protected readonly PackedScene LaserScene = GD.Load("res://scenes/entities/laser.tscn"); protected virtual void ShootLaser() { Laser laser = LaserScene.Instantiate(); laser.Position = LaserSpawn.GlobalPosition + -Transform.Y * 25f; laser.Shooter = this; laser.Rotation = Rotation; GetNode("LaserSFX").Play(); EmitSignal(SignalName.LaserShot, laser); } public void SetupVisual() { Sprite = GetNode("ShipSprite"); SpritePath = ""; // Have to initialise as "" because of switch statements if (Faction == ShipFaction.PLAYER) { switch (Type) { case ShipType.FIGHTER: SpritePath = "res://assets/Ships/Fighters/Player/Fighter/"; break; case ShipType.INTERCEPTOR: SpritePath = "res://assets/Ships/Fighters/Player/Interceptor/"; break; case ShipType.GUARDIAN: SpritePath = "res://assets/Ships/Fighters/Player/Guardian/"; break; } } else if (Faction == ShipFaction.FRIENDLY) { switch (Type) { case ShipType.FIGHTER: SpritePath = "res://assets/Ships/Fighters/Friendly/friendlyFighter.png/"; break; case ShipType.INTERCEPTOR: SpritePath = "res://assets/Ships/Fighters/Friendly/friendlyInterceptor.png/"; break; case ShipType.GUARDIAN: SpritePath = "res://assets/Ships/Fighters/Friendly/friendlyGuardian.png/"; break; } } else if (Faction == ShipFaction.ENEMY) { switch (Type) { case ShipType.FIGHTER: SpritePath = "res://assets/Ships/Fighters/Enemy/enemyFighter.png/"; break; case ShipType.INTERCEPTOR: SpritePath = "res://assets/Ships/Fighters/Enemy/enemyInterceptor.png/"; break; case ShipType.GUARDIAN: SpritePath = "res://assets/Ships/Fighters/Enemy/enemyGuardian.png/"; break; } } else if (Faction == ShipFaction.ACE) { switch (Type) { case ShipType.FIGHTER: SpritePath = "res://assets/Ships/Fighters/Ace/aceFighter.png/"; break; case ShipType.INTERCEPTOR: SpritePath = "res://assets/Ships/Fighters/Ace/aceInterceptor.png/"; break; case ShipType.GUARDIAN: SpritePath = "res://assets/Ships/Fighters/Ace/aceGuardian.png/"; break; } } if (Faction == ShipFaction.ENEMY || Faction == ShipFaction.FRIENDLY) { Sprite.RotationDegrees = 180; } else { Sprite.RotationDegrees = 0; } } protected void SetShipStats() { switch (Type) { case ShipType.FIGHTER: Health = (int)(100 * StatModifier); MaxSpeed = (int)(300 * StatModifier); MainSpeed = (int)(20 * StatModifier); StrafeSpeed = (int)(10 * StatModifier); RotationSpeed = 2f * StatModifier; MaxHealth = (int)(100 * StatModifier); Damage = (int)(30 * StatModifier); FireCooldown = 0.6f * StatModifier; break; case ShipType.INTERCEPTOR: Health = (int)(75 * StatModifier); MaxSpeed = (int)(450 * StatModifier); MainSpeed = (int)(35 * StatModifier); StrafeSpeed = (int)(15 * StatModifier); RotationSpeed = 4f * StatModifier; MaxHealth = (int)(75 * StatModifier); Damage = (int)(10 * StatModifier); FireCooldown = 0.3f * StatModifier; break; case ShipType.GUARDIAN: Health = (int)(200 * StatModifier); MaxSpeed = (int)(200 * StatModifier); MainSpeed = (int)(15 * StatModifier); StrafeSpeed = (int)(7 * StatModifier); RotationSpeed = 1.5f * StatModifier; MaxHealth = (int)(200 * StatModifier); Damage = (int)(50 * StatModifier); FireCooldown = 1.1f * StatModifier; break; } } public virtual void ShipDamage(int damage) { Health -= damage; if (Health <= 0) { Health = 0; Explode(); } //GD.Print(Name, " health: ", Health); GetNode("DamageSFX").Play(); } protected virtual void Explode() { //GD.Print(Name, " exploded"); QueueFree(); } public override void _Ready() { //ScreenSize = GetViewportRect().Size; LaserSpawn = GetNode("LaserSpawn"); } public override void _PhysicsProcess(double delta) { // Common movement logic for all ships Rotation += RotationDirection * RotationSpeed * (float)delta; Velocity.LimitLength(MaxSpeed); MoveAndSlide(); } }