using System.Numerics;
using Robust.Shared.Random;
namespace Content.Server.NPC.Pathfinding;
public sealed partial class PathfindingSystem
{
///
/// Widens the path by the specified amount.
///
public HashSet GetWiden(WidenArgs args, Random random)
{
var tiles = new HashSet(args.Path.Count * 2);
var variance = (args.MaxWiden - args.MinWiden) / 2f + args.MinWiden;
var counter = 0;
foreach (var tile in args.Path)
{
counter++;
if (counter != args.TileSkip)
continue;
counter = 0;
var center = new Vector2(tile.X + 0.5f, tile.Y + 0.5f);
if (args.Square)
{
for (var x = -variance; x <= variance; x++)
{
for (var y = -variance; y <= variance; y++)
{
var neighbor = center + new Vector2(x, y);
tiles.Add(neighbor.Floored());
}
}
}
else
{
for (var x = -variance; x <= variance; x++)
{
for (var y = -variance; y <= variance; y++)
{
var offset = new Vector2(x, y);
if (offset.Length() > variance)
continue;
var neighbor = center + offset;
tiles.Add(neighbor.Floored());
}
}
}
variance += random.NextFloat(-args.Variance * args.TileSkip, args.Variance * args.TileSkip);
variance = Math.Clamp(variance, args.MinWiden, args.MaxWiden);
}
return tiles;
}
public record struct WidenArgs()
{
public bool Square = false;
///
/// How many tiles to skip between iterations., 1-in-n
///
public int TileSkip = 3;
///
/// Maximum amount to vary per tile.
///
public float Variance = 0.25f;
///
/// Minimum width.
///
public float MinWiden = 2f;
public float MaxWiden = 7f;
public required List Path;
}
}