servicepoint-tanks/TanksServer/GameLogic/SpawnNewTanks.cs
2024-04-11 20:48:21 +02:00

54 lines
1.5 KiB
C#

namespace TanksServer.GameLogic;
internal sealed class SpawnNewTanks(
TankManager tanks,
MapService map,
SpawnQueue queue,
BulletManager bullets
) : ITickStep
{
public Task TickAsync()
{
if (!queue.TryDequeueNext(out var player))
return Task.CompletedTask;
tanks.Add(new Tank(player, ChooseSpawnPosition())
{
Rotation = Random.Shared.Next(0, 16)
});
return Task.CompletedTask;
}
private FloatPosition ChooseSpawnPosition()
{
Dictionary<TilePosition, double> candidates = [];
for (var x = 0; x < MapService.TilesPerRow; x++)
for (var y = 0; y < MapService.TilesPerColumn; y++)
{
var tile = new TilePosition(x, y);
if (map.IsCurrentlyWall(tile))
continue;
var tilePixelCenter = tile.GetPixelRelative(4, 4);
var minDistance = bullets.GetAll()
.Cast<IMapEntity>()
.Concat(tanks)
.Select(entity => Math.Sqrt(
Math.Pow(entity.Position.X - tilePixelCenter.X, 2) +
Math.Pow(entity.Position.Y - tilePixelCenter.Y, 2)))
.Aggregate(double.MaxValue, Math.Min);
candidates.Add(tile, minDistance);
}
var min = candidates.MaxBy(kvp => kvp.Value).Key;
return new FloatPosition(
min.X * MapService.TileSize,
min.Y * MapService.TileSize
);
}
}