PathfindingSystem.Widen.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System.Numerics;
  2. using Robust.Shared.Random;
  3. namespace Content.Server.NPC.Pathfinding;
  4. public sealed partial class PathfindingSystem
  5. {
  6. /// <summary>
  7. /// Widens the path by the specified amount.
  8. /// </summary>
  9. public HashSet<Vector2i> GetWiden(WidenArgs args, Random random)
  10. {
  11. var tiles = new HashSet<Vector2i>(args.Path.Count * 2);
  12. var variance = (args.MaxWiden - args.MinWiden) / 2f + args.MinWiden;
  13. var counter = 0;
  14. foreach (var tile in args.Path)
  15. {
  16. counter++;
  17. if (counter != args.TileSkip)
  18. continue;
  19. counter = 0;
  20. var center = new Vector2(tile.X + 0.5f, tile.Y + 0.5f);
  21. if (args.Square)
  22. {
  23. for (var x = -variance; x <= variance; x++)
  24. {
  25. for (var y = -variance; y <= variance; y++)
  26. {
  27. var neighbor = center + new Vector2(x, y);
  28. tiles.Add(neighbor.Floored());
  29. }
  30. }
  31. }
  32. else
  33. {
  34. for (var x = -variance; x <= variance; x++)
  35. {
  36. for (var y = -variance; y <= variance; y++)
  37. {
  38. var offset = new Vector2(x, y);
  39. if (offset.Length() > variance)
  40. continue;
  41. var neighbor = center + offset;
  42. tiles.Add(neighbor.Floored());
  43. }
  44. }
  45. }
  46. variance += random.NextFloat(-args.Variance * args.TileSkip, args.Variance * args.TileSkip);
  47. variance = Math.Clamp(variance, args.MinWiden, args.MaxWiden);
  48. }
  49. return tiles;
  50. }
  51. public record struct WidenArgs()
  52. {
  53. public bool Square = false;
  54. /// <summary>
  55. /// How many tiles to skip between iterations., 1-in-n
  56. /// </summary>
  57. public int TileSkip = 3;
  58. /// <summary>
  59. /// Maximum amount to vary per tile.
  60. /// </summary>
  61. public float Variance = 0.25f;
  62. /// <summary>
  63. /// Minimum width.
  64. /// </summary>
  65. public float MinWiden = 2f;
  66. public float MaxWiden = 7f;
  67. public required List<Vector2i> Path;
  68. }
  69. }