2024-04-17 19:34:19 +02:00
|
|
|
namespace TanksServer.GameLogic;
|
|
|
|
|
|
|
|
internal sealed class MapEntityManager(
|
|
|
|
ILogger<MapEntityManager> logger,
|
2024-04-19 13:32:41 +02:00
|
|
|
IOptions<GameRules> options
|
2024-04-17 19:34:19 +02:00
|
|
|
)
|
|
|
|
{
|
2024-04-29 16:59:37 +02:00
|
|
|
private readonly GameRules _rules = options.Value;
|
2024-04-17 19:34:19 +02:00
|
|
|
private readonly HashSet<Bullet> _bullets = [];
|
|
|
|
private readonly HashSet<PowerUp> _powerUps = [];
|
2024-04-22 19:44:28 +02:00
|
|
|
private readonly Dictionary<Player, Tank> _playerTanks = [];
|
2024-04-19 13:32:41 +02:00
|
|
|
private readonly TimeSpan _bulletTimeout = TimeSpan.FromMilliseconds(options.Value.BulletTimeoutMs);
|
2024-04-17 19:34:19 +02:00
|
|
|
|
|
|
|
public IEnumerable<Bullet> Bullets => _bullets;
|
2024-04-22 19:59:41 +02:00
|
|
|
public IEnumerable<Tank> Tanks => _playerTanks.Values;
|
2024-04-17 19:34:19 +02:00
|
|
|
public IEnumerable<PowerUp> PowerUps => _powerUps;
|
|
|
|
|
2024-04-29 16:59:37 +02:00
|
|
|
public void SpawnBullet(Player tankOwner, FloatPosition position, double rotation, MagazineType type)
|
|
|
|
{
|
|
|
|
var speed = _rules.BulletSpeed * (type.HasFlag(MagazineType.Fast) ? 2 : 1);
|
|
|
|
_bullets.Add(new Bullet
|
2024-04-21 20:20:30 +02:00
|
|
|
{
|
|
|
|
Owner = tankOwner,
|
|
|
|
Position = position,
|
|
|
|
Rotation = rotation,
|
2024-04-29 16:59:37 +02:00
|
|
|
IsExplosive = type.HasFlag(MagazineType.Explosive),
|
2024-04-21 20:20:30 +02:00
|
|
|
Timeout = DateTime.Now + _bulletTimeout,
|
|
|
|
OwnerCollisionAfter = DateTime.Now + TimeSpan.FromSeconds(1),
|
2024-04-29 21:52:50 +02:00
|
|
|
Speed = speed,
|
|
|
|
IsSmart = type.HasFlag(MagazineType.Smart)
|
2024-04-21 20:20:30 +02:00
|
|
|
});
|
2024-04-29 16:59:37 +02:00
|
|
|
}
|
2024-04-17 19:34:19 +02:00
|
|
|
|
2024-04-22 19:44:28 +02:00
|
|
|
public void RemoveWhere(Predicate<Bullet> predicate) => _bullets.RemoveWhere(predicate);
|
2024-04-17 19:34:19 +02:00
|
|
|
|
2024-05-03 15:47:33 +02:00
|
|
|
public void SpawnTank(Player player, FloatPosition position)
|
2024-04-17 19:34:19 +02:00
|
|
|
{
|
2024-04-29 16:59:37 +02:00
|
|
|
var tank = new Tank
|
2024-04-17 19:34:19 +02:00
|
|
|
{
|
2024-04-29 16:59:37 +02:00
|
|
|
Owner = player,
|
2024-05-03 15:47:33 +02:00
|
|
|
Position = position,
|
2024-04-29 16:59:37 +02:00
|
|
|
Rotation = Random.Shared.NextDouble(),
|
|
|
|
Magazine = new Magazine(MagazineType.Basic, 0, _rules.MagazineSize)
|
2024-04-22 19:44:28 +02:00
|
|
|
};
|
|
|
|
_playerTanks[player] = tank;
|
2024-04-28 12:53:18 +02:00
|
|
|
logger.LogInformation("Tank added for player {}", player.Name);
|
2024-04-17 19:34:19 +02:00
|
|
|
}
|
|
|
|
|
2024-05-03 15:47:33 +02:00
|
|
|
public void SpawnPowerUp(FloatPosition position, PowerUpType type, MagazineType? magazineType)
|
2024-04-29 18:03:23 +02:00
|
|
|
{
|
2024-05-03 15:47:33 +02:00
|
|
|
var powerUp = new PowerUp
|
|
|
|
{
|
|
|
|
Position = position,
|
|
|
|
Type = type,
|
|
|
|
MagazineType = magazineType
|
|
|
|
};
|
|
|
|
_powerUps.Add(powerUp);
|
|
|
|
}
|
2024-04-17 19:34:19 +02:00
|
|
|
|
|
|
|
public void RemoveWhere(Predicate<PowerUp> predicate) => _powerUps.RemoveWhere(predicate);
|
|
|
|
|
|
|
|
public void Remove(Tank tank)
|
|
|
|
{
|
2024-04-28 12:53:18 +02:00
|
|
|
logger.LogInformation("Tank removed for player {}", tank.Owner.Name);
|
2024-04-22 19:44:28 +02:00
|
|
|
_playerTanks.Remove(tank.Owner);
|
2024-04-17 19:34:19 +02:00
|
|
|
}
|
|
|
|
|
2024-04-22 19:59:41 +02:00
|
|
|
public Tank? GetCurrentTankOfPlayer(Player player) => _playerTanks.GetValueOrDefault(player);
|
2024-04-17 19:34:19 +02:00
|
|
|
|
2024-05-03 15:47:33 +02:00
|
|
|
public IEnumerable<IMapEntity> AllEntities => Bullets
|
2024-04-22 19:59:41 +02:00
|
|
|
.Cast<IMapEntity>()
|
|
|
|
.Concat(Tanks)
|
|
|
|
.Concat(PowerUps);
|
2024-04-17 19:34:19 +02:00
|
|
|
}
|