servicepoint-tanks/tanks-backend/TanksServer/GameLogic/CollectPowerUp.cs
2024-05-08 00:29:33 +02:00

80 lines
2.4 KiB
C#

using System.Diagnostics;
namespace TanksServer.GameLogic;
internal sealed class CollectPowerUp : ITickStep
{
private readonly Predicate<PowerUp> _collectPredicate;
private readonly GameRules _rules;
private readonly MapEntityManager _entityManager;
public CollectPowerUp(MapEntityManager entityManager,
IOptions<GameRules> options)
{
_entityManager = entityManager;
_rules = options.Value;
_collectPredicate = b => TryCollect(b, entityManager.Tanks);
}
public ValueTask TickAsync(TimeSpan delta)
{
_entityManager.RemoveWhere(_collectPredicate);
return ValueTask.CompletedTask;
}
private bool TryCollect(PowerUp powerUp, IEnumerable<Tank> tanks)
{
var position = powerUp.Position;
foreach (var tank in tanks)
{
var (topLeft, bottomRight) = tank.Bounds;
if (position.X < topLeft.X || position.X > bottomRight.X ||
position.Y < topLeft.Y || position.Y > bottomRight.Y)
continue;
// now the tank overlaps the power up by at least 0.5 tiles
ApplyPowerUpEffect(powerUp, tank);
tank.Owner.Scores.PowerUpsCollected++;
return true;
}
return false;
}
private void ApplyPowerUpEffect(PowerUp powerUp, Tank tank)
{
switch (powerUp.Type)
{
case PowerUpType.MagazineSize:
tank.MaxBullets = (byte)int.Clamp(tank.MaxBullets + 1, 1, 32);
break;
case PowerUpType.BulletAcceleration:
tank.BulletStats = tank.BulletStats with
{
Acceleration = tank.BulletStats.Acceleration * _rules.BulletAccelerationUpgradeStrength
};
break;
case PowerUpType.ExplosiveBullets:
tank.BulletStats = tank.BulletStats with { Explosive = true };
break;
case PowerUpType.SmartBullets:
tank.BulletStats = tank.BulletStats with { Smart = true };
break;
case PowerUpType.BulletSpeed:
tank.BulletStats = tank.BulletStats with
{
Speed = tank.BulletStats.Speed * _rules.BulletSpeedUpgradeStrength
};
break;
default:
throw new NotImplementedException($"unknown type {powerUp.Type}");
}
}
}