Added configurable weapons.

This commit is contained in:
2026-01-03 21:49:27 -05:00
parent 79fd63c3ce
commit e8e31bb143
37 changed files with 332 additions and 88 deletions

View File

@@ -0,0 +1,36 @@
using AlienAttack.MonoGame.Things.Muzzles;
namespace AlienAttack.MonoGame.Things.Weapons;
public class ConfigurableWeapon(WeaponDef def, WeaponState state) : Weapon
{
public override int FireThreshold => state.FireThreshold;
public override void Fire(Sprite owner, SpriteUpdateContext context)
{
if (owner is not Player player) return;
foreach (var shot in def.Pattern.Shots)
{
// muzzle local -> world
var muzzleLocal = player.GetMuzzleLocal(shot.Muzzle); // make a fast lookup
var muzzleWorld = MuzzleMath.GetMuzzleWorld(player, muzzleLocal);
// speed upgrade
float vx = shot.Velocity.X * state.SpeedMultiplier;
float vy = shot.Velocity.Y * state.SpeedMultiplier;
// center bullet on muzzle + pattern offset
var pos = MuzzleMath.CenterBulletOn(muzzleWorld, def.Bullet.Width, def.Bullet.Height) + shot.Offset;
var bullet = def.Bullet.Create(pos.X, pos.Y, vx, vy, owner);
// optional: apply damage bonus generically
//bullet.Damage += state.DamageBonus;
context.SpawnSprite(bullet);
}
context.AudioManager.PlayPlayerFire(); // or use _def.FireSfxKey -> audio routing
}
}

View File

@@ -5,7 +5,7 @@ using System;
namespace AlienAttack.MonoGame.Things.Weapons;
internal record FireBulletContext
public record FireBulletContext
{
public Sprite Owner { get; init; }
public SpriteUpdateContext SpriteUpdateContext { get; init; }
@@ -24,7 +24,7 @@ public record Shot
public float YVelocity { get; init; }
}
internal record FireBulletFromMuzzleContext
public record FireBulletFromMuzzleContext
{
public Sprite Owner { get; init; }
public SpriteUpdateContext SpriteUpdateContext { get; init; }

View File

@@ -3,7 +3,7 @@ using AlienAttack.MonoGame.Things.Muzzles;
namespace AlienAttack.MonoGame.Things.Weapons;
internal class Minigun : Weapon
public class Minigun : Weapon
{
public override int FireThreshold => 15;
@@ -26,7 +26,7 @@ internal class Minigun : Weapon
}
}
internal abstract class MinigunSingle : Weapon
public abstract class MinigunSingle : Weapon
{
public override void Fire(Sprite owner, SpriteUpdateContext context)
{
@@ -50,23 +50,23 @@ internal abstract class MinigunSingle : Weapon
}
}
internal class MinigunSingleSlow : MinigunSingle
public class MinigunSingleSlow : MinigunSingle
{
public override int FireThreshold => 20;
}
internal class MinigunSingleAverage : MinigunSingle
public class MinigunSingleAverage : MinigunSingle
{
public override int FireThreshold => 15;
}
internal class MinigunSingleFast : MinigunSingle
public class MinigunSingleFast : MinigunSingle
{
public override int FireThreshold => 10;
}
internal abstract class MinigunDouble : Weapon
public abstract class MinigunDouble : Weapon
{
public override void Fire(Sprite owner, SpriteUpdateContext context)
{
@@ -91,23 +91,22 @@ internal abstract class MinigunDouble : Weapon
}
}
internal class MinigunDoubleSlow : MinigunDouble
public class MinigunDoubleSlow : MinigunDouble
{
public override int FireThreshold => 30;
}
internal class MinigunDoubleAverage : MinigunDouble
public class MinigunDoubleAverage : MinigunDouble
{
public override int FireThreshold => 20;
}
internal class MinigunDoubleFast : MinigunDouble
public class MinigunDoubleFast : MinigunDouble
{
public override int FireThreshold => 15;
}
internal abstract class MinigunTriple : Weapon
public abstract class MinigunTriple : Weapon
{
public override void Fire(Sprite owner, SpriteUpdateContext context)
{
@@ -133,23 +132,22 @@ internal abstract class MinigunTriple : Weapon
}
}
internal class MinigunTripleSlow : MinigunTriple
public class MinigunTripleSlow : MinigunTriple
{
public override int FireThreshold => 30;
}
internal class MinigunTripleAverage : MinigunTriple
public class MinigunTripleAverage : MinigunTriple
{
public override int FireThreshold => 20;
}
internal class MinigunTripleFast : MinigunTriple
public class MinigunTripleFast : MinigunTriple
{
public override int FireThreshold => 15;
}
internal abstract class MinigunTripleSpread : Weapon
public abstract class MinigunTripleSpread : Weapon
{
public override void Fire(Sprite owner, SpriteUpdateContext context)
{
@@ -175,18 +173,18 @@ internal abstract class MinigunTripleSpread : Weapon
}
}
internal class MinigunTripleSpreadSlow : MinigunTripleSpread
public class MinigunTripleSpreadSlow : MinigunTripleSpread
{
public override int FireThreshold => 30;
}
internal class MinigunTripleSpreadAverage : MinigunTripleSpread
public class MinigunTripleSpreadAverage : MinigunTripleSpread
{
public override int FireThreshold => 20;
}
internal class MinigunTripleSpreadFast : MinigunTripleSpread
public class MinigunTripleSpreadFast : MinigunTripleSpread
{
public override int FireThreshold => 15;
}

View File

@@ -0,0 +1,6 @@
using AlienAttack.MonoGame.Things.Muzzles;
using Microsoft.Xna.Framework;
namespace AlienAttack.MonoGame.Things.Weapons;
public readonly record struct Shot2(MuzzleId Muzzle, Vector2 Velocity, Vector2 Offset);

View File

@@ -0,0 +1,6 @@
namespace AlienAttack.MonoGame.Things.Weapons;
public sealed class ShotPattern
{
public required Shot2[] Shots { get; init; }
}

View File

@@ -0,0 +1,43 @@
using AlienAttack.MonoGame.Things.Muzzles;
using Microsoft.Xna.Framework;
namespace AlienAttack.MonoGame.Things.Weapons;
public static class ShotPatterns
{
public static readonly ShotPattern Single = new()
{
Shots =
[
new Shot2(MuzzleId.Center, new Vector2(0, -6), new Vector2(4, 0))
]
};
public static readonly ShotPattern Double = new()
{
Shots =
[
new Shot2(MuzzleId.Left, new Vector2(0, -6), new Vector2(4, 0)),
new Shot2(MuzzleId.Right, new Vector2(0, -6), new Vector2(4, 0))
]
};
public static readonly ShotPattern DoubleSpread = new()
{
Shots =
[
new Shot2(MuzzleId.Left, new Vector2(-1, -6), new Vector2(4, 0)),
new Shot2(MuzzleId.Right, new Vector2(1, -6), new Vector2(4, 0))
]
};
public static readonly ShotPattern TripleSpread = new()
{
Shots =
[
new Shot2(MuzzleId.Left, new Vector2(-1, -6), new Vector2(4, 0)),
new Shot2(MuzzleId.Center, new Vector2(0, -6), new Vector2(4, 0)),
new Shot2(MuzzleId.Right, new Vector2(1, -6), new Vector2(4, 0))
]
};
}

View File

@@ -1,12 +1,11 @@
using AlienAttack.MonoGame.Things.Bullets;
using AlienAttack.MonoGame.Things.Muzzles;
using Microsoft.Xna.Framework;
using System;
using System.Linq;
namespace AlienAttack.MonoGame.Things.Weapons;
internal abstract class Weapon : IWeapon
public abstract class Weapon : IWeapon
{
public abstract int FireThreshold { get; }
public int CurrentFireThreshold { get; private set; }

View File

@@ -0,0 +1,11 @@
using AlienAttack.MonoGame.Things.Bullets;
namespace AlienAttack.MonoGame.Things.Weapons;
public sealed class WeaponDef
{
public required string Name { get; init; }
public required ShotPattern Pattern { get; init; }
public required BulletDef Bullet { get; init; }
public required string FireSfxKey { get; init; } = "player_fire";
}

View File

@@ -0,0 +1,8 @@
namespace AlienAttack.MonoGame.Things.Weapons;
public sealed class WeaponState
{
public int FireThreshold { get; set; }
public float SpeedMultiplier { get; set; } = 1f;
public int DamageBonus { get; set; } = 0;
}