Fix assert failure when paths are generated that are exactly 256 nodes long, and we try to store
this in our silly uchar path length variable. For now we need to cap path lengths to 255 because of savegame compatibility. Also rewrote parts of the A* path handover code to get rid of some old cruft. Closes ticket:765 git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@7915 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
b549837969
commit
8e3fd76c3c
68
src/astar.c
68
src/astar.c
|
@ -21,13 +21,11 @@
|
|||
* A* based path finding
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef WZ_TESTING
|
||||
#include "lib/framework/frame.h"
|
||||
|
||||
#include "map.h"
|
||||
|
||||
#include "astar.h"
|
||||
#endif
|
||||
|
||||
static SDWORD astarOuter, astarRemove;
|
||||
|
||||
|
@ -318,7 +316,7 @@ static FP_NODE *fpathNewNode(SDWORD x, SDWORD y, SDWORD dist, FP_NODE *psRoute)
|
|||
|
||||
SDWORD fpathAStarRoute(MOVE_CONTROL *psMove, PATHJOB *psJob)
|
||||
{
|
||||
FP_NODE *psFound, *psCurr, *psNew, *psParent, *psNext;
|
||||
FP_NODE *psFound, *psCurr, *psNew;
|
||||
FP_NODE *psNearest, *psRoute;
|
||||
SDWORD dir, x,y, currDist;
|
||||
SDWORD retval = ASR_OK;
|
||||
|
@ -456,7 +454,27 @@ SDWORD fpathAStarRoute(MOVE_CONTROL *psMove, PATHJOB *psJob)
|
|||
|
||||
if (psRoute)
|
||||
{
|
||||
int index, count = psMove->numPoints;
|
||||
int count = 0; // calculated length of route
|
||||
|
||||
// Count length of route
|
||||
psCurr = psRoute;
|
||||
while (psCurr)
|
||||
{
|
||||
psCurr = psCurr->psRoute;
|
||||
count++;
|
||||
}
|
||||
|
||||
// TODO FIXME once we can change numPoints to something larger than uchar
|
||||
psMove->numPoints = MIN(255, count);
|
||||
|
||||
// Allocate memory
|
||||
psMove->asPath = calloc(sizeof(*psMove->asPath), count);
|
||||
ASSERT(psMove->asPath, "Out of memory");
|
||||
if (!psMove->asPath)
|
||||
{
|
||||
fpathHardTableReset();
|
||||
return ASR_FAILED;
|
||||
}
|
||||
|
||||
// get the route in the correct order
|
||||
// If as I suspect this is to reverse the list, then it's my suspicion that
|
||||
|
@ -466,42 +484,16 @@ SDWORD fpathAStarRoute(MOVE_CONTROL *psMove, PATHJOB *psJob)
|
|||
// The idea is impractical, because you can't guarentee that the target is
|
||||
// reachable. As I see it, this is the reason why psNearest got introduced.
|
||||
// -- Dennis L.
|
||||
psParent = NULL;
|
||||
for(psCurr=psRoute; psCurr; psCurr=psNext)
|
||||
{
|
||||
psNext = psCurr->psRoute;
|
||||
psCurr->psRoute = psParent;
|
||||
psParent = psCurr;
|
||||
count++;
|
||||
}
|
||||
ASSERT(count > 0, "Route has no nodes");
|
||||
if (count <= 0)
|
||||
{
|
||||
fpathHardTableReset();
|
||||
return ASR_FAILED;
|
||||
}
|
||||
psRoute = psParent;
|
||||
|
||||
psCurr = psRoute;
|
||||
psMove->asPath = realloc(psMove->asPath, sizeof(*psMove->asPath) * count);
|
||||
ASSERT(psMove->asPath, "Out of memory");
|
||||
if (!psMove->asPath)
|
||||
psMove->DestinationX = world_coord(psCurr->x);
|
||||
psMove->DestinationY = world_coord(psCurr->y);
|
||||
while (psCurr)
|
||||
{
|
||||
fpathHardTableReset();
|
||||
return ASR_FAILED;
|
||||
}
|
||||
index = psMove->numPoints;
|
||||
while (psCurr && index < count)
|
||||
{
|
||||
psMove->asPath[index].x = psCurr->x;
|
||||
psMove->asPath[index].y = psCurr->y;
|
||||
index++;
|
||||
ASSERT(psCurr->x < mapWidth && psCurr->y < mapHeight, "Bad route generated!");
|
||||
count--;
|
||||
psMove->asPath[count].x = psCurr->x;
|
||||
psMove->asPath[count].y = psCurr->y;
|
||||
psCurr = psCurr->psRoute;
|
||||
}
|
||||
psMove->numPoints = index;
|
||||
psMove->DestinationX = world_coord(psMove->asPath[index - 1].x);
|
||||
psMove->DestinationY = world_coord(psMove->asPath[index - 1].y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -587,6 +587,7 @@ static void fpathExecute(PATHJOB *psJob, PATHRESULT *psResult)
|
|||
FPATH_RETVAL retval = fpathAStarRoute(&psResult->sMove, psJob);
|
||||
|
||||
ASSERT(retval != ASR_OK || psResult->sMove.asPath, "Ok result but no path in result");
|
||||
ASSERT(retval == ASR_FAILED || psResult->sMove.numPoints > 0, "Ok result but no length of path in result");
|
||||
switch (retval)
|
||||
{
|
||||
case ASR_NEAREST:
|
||||
|
@ -607,7 +608,7 @@ static void fpathExecute(PATHJOB *psJob, PATHRESULT *psResult)
|
|||
psResult->retval = FPR_FAILED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case ASR_OK:
|
||||
objTrace(psJob->droidID, "Got route of length %d", psResult->sMove.numPoints);
|
||||
psResult->retval = FPR_OK;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue