86 lines
2.8 KiB
C#
86 lines
2.8 KiB
C#
using AlienAttack.MonoGame.Things.Bullets;
|
|
using AlienAttack.MonoGame.Things.Muzzles;
|
|
using Microsoft.Xna.Framework;
|
|
using System.Linq;
|
|
|
|
namespace AlienAttack.MonoGame.Things.Weapons;
|
|
|
|
public abstract class Weapon : IWeapon
|
|
{
|
|
public abstract int FireThreshold { get; }
|
|
public int CurrentFireThreshold { get; private set; }
|
|
|
|
public void UpdateFireThreshold()
|
|
{
|
|
if (CurrentFireThreshold > 0)
|
|
CurrentFireThreshold--;
|
|
}
|
|
|
|
public bool TryFire(Sprite owner, SpriteUpdateContext context)
|
|
{
|
|
if (CurrentFireThreshold > 0)
|
|
return false;
|
|
|
|
Fire(owner, context);
|
|
CurrentFireThreshold = FireThreshold;
|
|
|
|
return true;
|
|
}
|
|
|
|
public abstract void Fire(Sprite owner, SpriteUpdateContext context);
|
|
|
|
protected static void FireBullet(FireBulletContext context)
|
|
{
|
|
var (x, y) = ComputeAnchorPosition(context);
|
|
|
|
foreach (Shot shot in context.Shots)
|
|
{
|
|
Bullet bullet = context.Factory(x + shot.OffsetX, y + shot.OffsetY, shot.XVelocity, shot.YVelocity, context.Owner);
|
|
context.SpriteUpdateContext.SpawnSprite(bullet);
|
|
}
|
|
}
|
|
|
|
private static (float x, float y) ComputeAnchorPosition(FireBulletContext context)
|
|
{
|
|
Sprite owner = context.Owner;
|
|
int bw = context.BulletWidth;
|
|
int bh = context.BulletHeight;
|
|
Anchor anchor = context.Anchor;
|
|
|
|
float left = owner.XPosition;
|
|
float top = owner.YPosition;
|
|
float right = owner.XPosition + owner.BoundBox.Width;
|
|
float bottom = owner.YPosition + owner.BoundBox.Height;
|
|
|
|
return anchor switch
|
|
{
|
|
Anchor.TopLeft => (left, top - bh),
|
|
Anchor.TopCenter => (left + (owner.BoundBox.Width - bw) / 2f, top - bh),
|
|
Anchor.TopRight => (right - bw, top - bh),
|
|
|
|
Anchor.Center => (left + (owner.BoundBox.Width - bw) / 2f, top + (owner.BoundBox.Height - bh) / 2f),
|
|
|
|
Anchor.BottomLeft => (left, bottom),
|
|
Anchor.BottomCenter => (left + (owner.BoundBox.Width - bw) / 2f, bottom),
|
|
Anchor.BottomRight => (right - bw, bottom),
|
|
|
|
_ => (left, top)
|
|
};
|
|
}
|
|
|
|
protected static void FireFromMuzzle(FireBulletFromMuzzleContext context)
|
|
{
|
|
if (context.Owner is not Player player)
|
|
return;
|
|
|
|
foreach (MuzzleShot shot in context.Shots)
|
|
{
|
|
var m = player.Muzzles.First(x => x.Id == shot.Muzzle).LocalPx;
|
|
Vector2 worldMuzzle = MuzzleMath.GetMuzzleWorld(player, m);
|
|
Vector2 bulletPos = MuzzleMath.CenterBulletOn(worldMuzzle, context.BulletWidth, context.BulletHeight) + context.ExtraOffset;
|
|
|
|
Bullet bullet = context.Factory(bulletPos.X, bulletPos.Y, shot.XVelocity, shot.YVelocity, context.Owner);
|
|
context.SpriteUpdateContext.SpawnSprite(bullet);
|
|
}
|
|
}
|
|
} |