Files
tbd-station-14/Content.Server/NPC/Pathfinding/PathfindingSystem.Line.cs
metalgearsloth a2f99cc69e VGRoid support (#27659)
* Dungeon spawn support for grid spawns

* Recursive dungeons working

* Mask approach working

* zack

* More work

* Fix recursive dungeons

* Heap of work

* weh

* the cud

* rar

* Job

* weh

* weh

* weh

* Master merges

* orch

* weh

* vgroid most of the work

* Tweaks

* Tweaks

* weh

* do do do do do do

* Basic layout

* Ore spawning working

* Big breaking changes

* Mob gen working

* weh

* Finalising

* emo

* More finalising

* reverty

* Reduce distance
2024-07-03 22:23:11 +10:00

75 lines
2.1 KiB
C#

namespace Content.Server.NPC.Pathfinding;
public sealed partial class PathfindingSystem
{
public void GridCast(Vector2i start, Vector2i end, Vector2iCallback callback)
{
// https://gist.github.com/Pyr3z/46884d67641094d6cf353358566db566
// declare all locals at the top so it's obvious how big the footprint is
int dx, dy, xinc, yinc, side, i, error;
// starting cell is always returned
if (!callback(start))
return;
xinc = (end.X < start.X) ? -1 : 1;
yinc = (end.Y < start.Y) ? -1 : 1;
dx = xinc * (end.X - start.X);
dy = yinc * (end.Y - start.Y);
var ax = start.X;
var ay = start.Y;
if (dx == dy) // Handle perfect diagonals
{
// I include this "optimization" for more aesthetic reasons, actually.
// While Bresenham's Line can handle perfect diagonals just fine, it adds
// additional cells to the line that make it not a perfect diagonal
// anymore. So, while this branch is ~twice as fast as the next branch,
// the real reason it is here is for style.
// Also, there *is* the reason of performance. If used for cell-based
// raycasts, for example, then perfect diagonals will check half as many
// cells.
while (dx --> 0)
{
ax += xinc;
ay += yinc;
if (!callback(new Vector2i(ax, ay)))
return;
}
return;
}
// Handle all other lines
side = -1 * ((dx == 0 ? yinc : xinc) - 1);
i = dx + dy;
error = dx - dy;
dx *= 2;
dy *= 2;
while (i --> 0)
{
if (error > 0 || error == side)
{
ax += xinc;
error -= dy;
}
else
{
ay += yinc;
error += dx;
}
if (!callback(new Vector2i(ax, ay)))
return;
}
}
public delegate bool Vector2iCallback(Vector2i index);
}