starfighter/MB_FYP/script/entities/ship.cs

217 lines
5.8 KiB
C#
Raw Permalink Normal View History

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]
2025-04-18 01:07:51 +00:00
public int Health { get; set; }
[Export]
2025-04-18 01:07:51 +00:00
public int MaxHealth { get; set; }
[Export]
2025-04-18 01:07:51 +00:00
public int MaxSpeed { get; set;}
[Export]
2025-04-18 01:07:51 +00:00
public int MainSpeed { get; set; }
[Export]
2025-04-18 01:07:51 +00:00
public int StrafeSpeed { get; set; }
[Export]
2025-04-18 01:07:51 +00:00
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<PackedScene>("res://scenes/entities/laser.tscn");
protected virtual void ShootLaser()
{
Laser laser = LaserScene.Instantiate<Laser>();
laser.Position = LaserSpawn.GlobalPosition + -Transform.Y * 25f;
laser.Shooter = this;
laser.Rotation = Rotation;
GetNode<AudioStreamPlayer2D>("LaserSFX").Play();
EmitSignal(SignalName.LaserShot, laser);
}
public void SetupVisual()
{
Sprite = GetNode<Sprite2D>("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)
{
2025-04-18 01:07:51 +00:00
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;
2025-04-18 01:07:51 +00:00
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<AudioStreamPlayer2D>("DamageSFX").Play();
}
protected virtual void Explode()
{
//GD.Print(Name, " exploded");
QueueFree();
}
public override void _Ready()
{
//ScreenSize = GetViewportRect().Size;
LaserSpawn = GetNode<Node2D>("LaserSpawn");
}
public override void _PhysicsProcess(double delta)
{
// Common movement logic for all ships
Rotation += RotationDirection * RotationSpeed * (float)delta;
Velocity.LimitLength(MaxSpeed);
MoveAndSlide();
}
}