Rework pathfinding to use Vector2, form formations
This commit is contained in:
@@ -14,11 +14,28 @@ static i32 dst(TilePosition a, TilePosition b) {
|
||||
return 14 * dstX + 10 * (dstY - dstX);
|
||||
}
|
||||
|
||||
static PathData *pushPathWaypoint(PathData *pathData, Position waypoint, BzObjectPool *pathPool) {
|
||||
if (pathData->numWaypoints + 1 > PATH_DATA_SIZE) {
|
||||
PathData *newPathData = bzObjectPool(pathPool);
|
||||
BZ_ASSERT(newPathData);
|
||||
newPathData->numWaypoints = 0;
|
||||
newPathData->next = pathData;
|
||||
pathData = newPathData;
|
||||
}
|
||||
pathData->waypoints[pathData->numWaypoints++] = waypoint;
|
||||
return pathData;
|
||||
}
|
||||
|
||||
bool findPath(const PathfindingDesc *desc) {
|
||||
BZ_ASSERT(desc->map);
|
||||
BzTileMap *map = desc->map;
|
||||
BZ_ASSERT(desc->start.x >= 0 && desc->start.x < map->width);
|
||||
BZ_ASSERT(desc->start.y >= 0 && desc->start.y < map->height);
|
||||
|
||||
TilePosition start = {0}, target = {0};
|
||||
bzTileMapPosToTile(map, desc->start, &start.x, &start.y);
|
||||
bzTileMapPosToTile(map, desc->target, &target.x, &target.y);
|
||||
BZ_ASSERT(start.x >= 0 && start.x < map->width);
|
||||
BZ_ASSERT(start.y >= 0 && start.y < map->height);
|
||||
|
||||
typedef struct Visited {
|
||||
bool visited : 1;
|
||||
i8 x : 3;
|
||||
@@ -30,21 +47,22 @@ bool findPath(const PathfindingDesc *desc) {
|
||||
if (!openSet) openSet = bzHeapCreate(PathNode, map->width * map->height);
|
||||
else bzHeapClear(openSet);
|
||||
|
||||
i32 toTargetCost = dst(desc->start, desc->target);
|
||||
|
||||
i32 toTargetCost = dst(start, target);
|
||||
bzHeapPush(openSet, (PathNode) {
|
||||
.weight=toTargetCost,
|
||||
.gCost=0,
|
||||
.hCost=toTargetCost,
|
||||
.visited=false,
|
||||
.pos=desc->start
|
||||
.pos=start
|
||||
});
|
||||
|
||||
bool foundPath = false;
|
||||
|
||||
while (!bzHeapIsEmpty(openSet)) {
|
||||
PathNode node = bzHeapPop(openSet);
|
||||
if (node.pos.x == desc->target.x &&
|
||||
node.pos.y == desc->target.y) {
|
||||
if (node.pos.x == target.x &&
|
||||
node.pos.y == target.y) {
|
||||
// Found path
|
||||
foundPath = true;
|
||||
break;
|
||||
@@ -69,7 +87,7 @@ bool findPath(const PathfindingDesc *desc) {
|
||||
TilePosition curPos = {x, y};
|
||||
i32 gCost = node.gCost + dst(node.pos, curPos);
|
||||
//if (gCost >= node.gCost) continue;
|
||||
toTargetCost = dst(curPos, desc->target);
|
||||
toTargetCost = dst(curPos, target);
|
||||
|
||||
curClosed->x = (i8) (curPos.x - node.pos.x);
|
||||
curClosed->y = (i8) (curPos.y - node.pos.y);
|
||||
@@ -87,31 +105,25 @@ bool findPath(const PathfindingDesc *desc) {
|
||||
|
||||
i32 pathLen = 0;
|
||||
if (foundPath && desc->outPath) {
|
||||
TilePosition pos = desc->target;
|
||||
TilePosition pos = target;
|
||||
Path *out = desc->outPath;
|
||||
out->curWaypoint = 0;
|
||||
BZ_ASSERT(desc->pool);
|
||||
PathData *pathData = bzObjectPool(desc->pool);
|
||||
pathData->numWaypoints = 0;
|
||||
pathData->next = NULL;
|
||||
i32 numWaypoints = 0;
|
||||
|
||||
pathData = pushPathWaypoint(pathData, desc->target, desc->pool);
|
||||
|
||||
// Write path
|
||||
// TODO: Write end pos
|
||||
while (pos.x != desc->start.x || pos.y != desc->start.y) {
|
||||
while (pos.x != start.x || pos.y != start.y) {
|
||||
Position waypoint = {
|
||||
pos.x * map->tileWidth + map->tileWidth * 0.5f,
|
||||
pos.y * map->tileHeight + map->tileHeight * 0.5f
|
||||
};
|
||||
|
||||
if (pathData->numWaypoints + 1 > PATH_DATA_SIZE) {
|
||||
PathData *newPathData = bzObjectPool(desc->pool);
|
||||
newPathData->numWaypoints = 0;
|
||||
newPathData->next = pathData;
|
||||
pathData = newPathData;
|
||||
numWaypoints = 0;
|
||||
}
|
||||
pathData->waypoints[numWaypoints++] = waypoint;
|
||||
pathData->numWaypoints = numWaypoints;
|
||||
if (pathLen != 0)
|
||||
pathData = pushPathWaypoint(pathData, waypoint, desc->pool);
|
||||
|
||||
Visited visit = closedSet[pos.y * map->width + pos.x];
|
||||
BZ_ASSERT(visit.x != 0 || visit.y != 0);
|
||||
|
||||
Reference in New Issue
Block a user