SupaLidlGame/Items/Weapons/ProjectileSpawner.cs

109 lines
2.8 KiB
C#
Raw Permalink Normal View History

2023-08-05 23:50:08 -07:00
using Godot;
namespace SupaLidlGame.Items.Weapons;
public partial class ProjectileSpawner : Ranged
{
[Export]
public PackedScene Projectile { get; set; }
[ExportGroup("Projectile Overrides")]
2023-08-05 23:50:08 -07:00
[Export]
public bool ShouldOverrideProjectileDamage { get; set; } = true;
2023-08-08 00:54:00 -07:00
[Export]
public bool ShouldOverrideVelocity { get; set; } = true;
2023-08-05 23:50:08 -07:00
[Export]
public bool ShouldRotate { get; set; } = true;
[ExportGroup("Multishot")]
[Export]
public int ProjectileCount { get; set; } = 1;
[Export]
public float ProjectileAngleDeviation { get; set; }
2023-09-10 17:08:14 -07:00
private void SpawnProjectile(Scenes.Map map, Vector2 direction, float v = 1)
2023-08-05 23:50:08 -07:00
{
var projectile = map.SpawnEntity<Entities.Projectile>(Projectile);
projectile.Hitbox.Faction = Character.Faction;
projectile.Direction = direction;
2023-08-05 23:50:08 -07:00
projectile.GlobalPosition = GlobalPosition;
2023-08-14 14:07:57 -07:00
if (ShouldOverrideVelocity)
{
2023-09-10 17:08:14 -07:00
projectile.Speed = InitialVelocity * v;
2023-08-14 14:07:57 -07:00
}
2023-08-05 23:50:08 -07:00
if (ShouldRotate)
{
projectile.GlobalRotation = projectile.Direction.Angle();
}
if (ShouldOverrideProjectileDamage)
{
if (projectile.Hitbox is not null)
{
projectile.Hitbox.Damage = Damage;
}
}
2023-09-03 17:42:32 -07:00
projectile.Hitbox.Inflictor = Character;
projectile.Weapon = this;
2023-08-05 23:50:08 -07:00
if (projectile is Utils.ITarget target)
{
if (Character is Characters.NPC npc)
{
target.CharacterTarget = npc.FindBestTarget();
}
}
2023-08-14 14:07:57 -07:00
}
public override void Attack()
2023-09-10 17:08:14 -07:00
{
Attack(1);
}
public override void Attack(float velocityModifier)
{
2023-08-14 14:07:57 -07:00
Character.Inventory.EmitSignal("UsedItem", this);
var map = Utils.World.Instance.CurrentMap;
Vector2 target = Character.Target.Normalized();
2023-08-15 21:49:33 -07:00
if (CharacterRecoil > 0)
{
Character.ApplyImpulse(-target * CharacterRecoil);
}
// avoid unnecessary math if only spawning 1 projectile
if (ProjectileCount == 1)
{
2023-09-10 17:08:14 -07:00
SpawnProjectile(map, target, velocityModifier);
return;
}
// example: 4 projectiles =
// i = 0 -> 1.5 theta
// i = 1 -> 0.5 theta
// i = 2 -> -0.5 theta
// i = 3 -> -1.5 theta
// i = x -> -x * 0.5 theta + max dev
float theta = Mathf.DegToRad(ProjectileAngleDeviation);
// maaax angle deviation = ((projectile count - 1) / 2) thetas
float maxAngleDeviations = ((ProjectileCount - 1) / 2);
for (int i = 0; i < ProjectileCount; i++)
{
float curDeviation = -i + maxAngleDeviations;
2023-09-10 17:08:14 -07:00
SpawnProjectile(map,
target.Rotated(curDeviation * theta),
velocityModifier);
}
2023-08-05 23:50:08 -07:00
}
}