* 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
75 lines
2.1 KiB
C#
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);
|
|
}
|