Remove the limit on how long a path can be, remove the attack wall hack, and remove
the line of sight optimization of paths. Experimental changes, so please do not backport. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@4964 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
ab90207cc0
commit
1a42ffda05
62
src/action.c
62
src/action.c
|
@ -988,68 +988,6 @@ static void actionHomeBasePos(SDWORD player, SDWORD *px, SDWORD *py)
|
|||
*py = getLandingY(player);
|
||||
}
|
||||
|
||||
|
||||
// tell the action system of a potential location for walls blocking routing
|
||||
BOOL actionRouteBlockingPos(DROID *psDroid, SDWORD tx, SDWORD ty)
|
||||
{
|
||||
SDWORD i,j;
|
||||
MAPTILE *psTile;
|
||||
STRUCTURE *psWall;
|
||||
|
||||
CHECK_DROID(psDroid);
|
||||
|
||||
if (vtolDroid(psDroid) ||
|
||||
((psDroid->order != DORDER_MOVE) &&
|
||||
(psDroid->order != DORDER_SCOUT)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// see if there is a wall to attack around the location
|
||||
psWall = NULL;
|
||||
for(i= tx -1; i <= tx + 1; i++)
|
||||
{
|
||||
for(j= ty -1; j <= ty + 1; j++)
|
||||
{
|
||||
if (tileOnMap(i,j))
|
||||
{
|
||||
psTile = mapTile(i,j);
|
||||
if (TileHasWall(psTile))
|
||||
{
|
||||
psWall = getTileStructure((UDWORD)i,(UDWORD)j);
|
||||
//Watermelon:fixes AI try to destroy ally's wall bug
|
||||
if (psWall->player != psDroid->player &&
|
||||
!aiCheckAlliances(psWall->player, psDroid->player))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
psWall = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (psWall != NULL)
|
||||
{
|
||||
if (psDroid->order == DORDER_MOVE)
|
||||
{
|
||||
psDroid->order = DORDER_MOVE_ATTACKWALL;
|
||||
}
|
||||
else if (psDroid->order == DORDER_SCOUT)
|
||||
{
|
||||
psDroid->order = DORDER_SCOUT_ATTACKWALL;
|
||||
}
|
||||
setDroidTarget(psDroid, (BASE_OBJECT *)psWall);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define VTOL_ATTACK_AUDIO_DELAY (3*GAME_TICKS_PER_SEC)
|
||||
|
||||
// Update the action state for a droid
|
||||
|
|
|
@ -140,9 +140,6 @@ BOOL actionDroidOnBuildPos(DROID *psDroid, SDWORD x, SDWORD y, BASE_STATS *psSta
|
|||
return to base*/
|
||||
extern void moveToRearm(DROID *psDroid);
|
||||
|
||||
// tell the action system of a potential location for walls blocking routing
|
||||
extern BOOL actionRouteBlockingPos(DROID *psDroid, SDWORD x, SDWORD y);
|
||||
|
||||
// choose a landing position for a VTOL when it goes to rearm
|
||||
extern BOOL actionVTOLLandingPos(DROID *psDroid, UDWORD *px, UDWORD *py);
|
||||
|
||||
|
|
59
src/astar.c
59
src/astar.c
|
@ -363,47 +363,11 @@ BOOL fpathTileLOS(SDWORD x1,SDWORD y1, SDWORD x2,SDWORD y2)
|
|||
return !obstruction;
|
||||
}
|
||||
|
||||
// Optimise the route
|
||||
static void fpathOptimise(FP_NODE *psRoute)
|
||||
{
|
||||
FP_NODE *psCurr, *psSearch, *psTest;
|
||||
BOOL los;
|
||||
|
||||
ASSERT( psRoute != NULL,
|
||||
"fpathOptimise: NULL route pointer" );
|
||||
|
||||
psCurr = psRoute;
|
||||
do
|
||||
{
|
||||
// work down the route looking for a failed LOS
|
||||
los = true;
|
||||
psSearch = psCurr->psRoute;
|
||||
while (psSearch)
|
||||
{
|
||||
psTest = psSearch->psRoute;
|
||||
if (psTest)
|
||||
{
|
||||
los = fpathTileLOS(psCurr->x,psCurr->y, psTest->x,psTest->y);
|
||||
}
|
||||
if (!los)
|
||||
{
|
||||
break;
|
||||
}
|
||||
psSearch = psTest;
|
||||
}
|
||||
|
||||
// store the previous successful point
|
||||
psCurr->psRoute = psSearch;
|
||||
psCurr = psSearch;
|
||||
} while (psCurr);
|
||||
}
|
||||
|
||||
SDWORD fpathAStarRoute(SDWORD routeMode, ASTAR_ROUTE *psRoutePoints, SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy, PROPULSION_TYPE propulsion)
|
||||
SDWORD fpathAStarRoute(SDWORD routeMode, MOVE_CONTROL *psMove, SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
FP_NODE *psFound, *psCurr, *psNew, *psParent, *psNext;
|
||||
static FP_NODE *psNearest, *psRoute;
|
||||
SDWORD dir, x,y, currDist;
|
||||
SDWORD index;
|
||||
SDWORD retval;
|
||||
const int tileSX = map_coord(sx);
|
||||
const int tileSY = map_coord(sy);
|
||||
|
@ -558,8 +522,7 @@ static FP_NODE *psNearest, *psRoute;
|
|||
|
||||
if (psRoute)
|
||||
{
|
||||
// optimise the route if one was found
|
||||
fpathOptimise(psRoute);
|
||||
int index, count = psMove->numPoints;
|
||||
|
||||
// get the route in the correct order
|
||||
// If as I suspect this is to reverse the list, then it's my suspicion that
|
||||
|
@ -575,21 +538,23 @@ static FP_NODE *psNearest, *psRoute;
|
|||
psNext = psCurr->psRoute;
|
||||
psCurr->psRoute = psParent;
|
||||
psParent = psCurr;
|
||||
count++;
|
||||
}
|
||||
psRoute = psParent;
|
||||
|
||||
psCurr = psRoute;
|
||||
index = psRoutePoints->numPoints;
|
||||
while (psCurr && index < TRAVELSIZE)
|
||||
psMove->asPath = realloc(psMove->asPath, sizeof(*psMove->asPath) * count);
|
||||
index = psMove->numPoints;
|
||||
while (psCurr && index < count)
|
||||
{
|
||||
psRoutePoints->asPos[index].x = psCurr->x;
|
||||
psRoutePoints->asPos[index].y = psCurr->y;
|
||||
index += 1;
|
||||
psMove->asPath[index].x = psCurr->x;
|
||||
psMove->asPath[index].y = psCurr->y;
|
||||
index++;
|
||||
psCurr = psCurr->psRoute;
|
||||
}
|
||||
psRoutePoints->numPoints = index;
|
||||
psRoutePoints->finalX = psRoutePoints->asPos[index-1].x;
|
||||
psRoutePoints->finalY = psRoutePoints->asPos[index-1].y;
|
||||
psMove->numPoints = index;
|
||||
psMove->DestinationX = psMove->asPath[index - 1].x;
|
||||
psMove->DestinationY = psMove->asPath[index - 1].y;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
12
src/astar.h
12
src/astar.h
|
@ -34,16 +34,6 @@
|
|||
*/
|
||||
#define FPATH_LOOP_LIMIT 600
|
||||
|
||||
/** The buffer to store a route in
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
typedef struct _astar_route
|
||||
{
|
||||
Vector2i asPos[TRAVELSIZE];
|
||||
SDWORD finalX, finalY, numPoints;
|
||||
} ASTAR_ROUTE;
|
||||
|
||||
// counters for A*
|
||||
extern int astarInner;
|
||||
|
||||
|
@ -81,7 +71,7 @@ enum
|
|||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
SDWORD fpathAStarRoute(SDWORD routeMode, ASTAR_ROUTE *psRoutePoints, SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy, PROPULSION_TYPE propulsion);
|
||||
SDWORD fpathAStarRoute(SDWORD routeMode, MOVE_CONTROL *psMove, SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy, PROPULSION_TYPE propulsion);
|
||||
|
||||
/** Check LOS (Line Of Sight) between two tiles
|
||||
*/
|
||||
|
|
|
@ -2858,6 +2858,7 @@ DROID* buildDroid(DROID_TEMPLATE *pTemplate, UDWORD x, UDWORD y, UDWORD player,
|
|||
ASSERT(!"out of memory", "Cannot get the memory for the unit");
|
||||
return NULL;
|
||||
}
|
||||
psDroid->sMove.asPath = NULL;
|
||||
|
||||
//fill in other details
|
||||
|
||||
|
|
90
src/fpath.c
90
src/fpath.c
|
@ -200,6 +200,7 @@ void fpathSetDirectRoute(DROID* psDroid, SDWORD targetX, SDWORD targetY)
|
|||
|
||||
psMoveCntl = &psDroid->sMove;
|
||||
|
||||
psMoveCntl->asPath = realloc(psMoveCntl->asPath, sizeof(*psMoveCntl->asPath));
|
||||
psMoveCntl->DestinationX = targetX;
|
||||
psMoveCntl->DestinationY = targetY;
|
||||
psMoveCntl->numPoints = 1;
|
||||
|
@ -207,68 +208,6 @@ void fpathSetDirectRoute(DROID* psDroid, SDWORD targetX, SDWORD targetY)
|
|||
psMoveCntl->asPath[0].y = map_coord(targetY);
|
||||
}
|
||||
|
||||
/** Append an astar route onto a move-control route
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
static void fpathAppendRoute( MOVE_CONTROL *psMoveCntl, ASTAR_ROUTE *psAStarRoute )
|
||||
{
|
||||
SDWORD mi, ai;
|
||||
|
||||
mi = psMoveCntl->numPoints;
|
||||
ai = 0;
|
||||
while ((mi < TRAVELSIZE) && (ai < psAStarRoute->numPoints))
|
||||
{
|
||||
psMoveCntl->asPath[mi].x = (UBYTE)(psAStarRoute->asPos[ai].x);
|
||||
psMoveCntl->asPath[mi].y = (UBYTE)(psAStarRoute->asPos[ai].y);
|
||||
|
||||
ai += 1;
|
||||
mi += 1;
|
||||
}
|
||||
|
||||
psMoveCntl->numPoints = (UBYTE)(psMoveCntl->numPoints + ai);
|
||||
psMoveCntl->DestinationX = world_coord(psAStarRoute->finalX) + TILE_UNITS/2;
|
||||
psMoveCntl->DestinationY = world_coord(psAStarRoute->finalY) + TILE_UNITS/2;
|
||||
}
|
||||
|
||||
/** Check if a new route is closer to the target than the one stored in the
|
||||
* droid
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
static BOOL fpathRouteCloser(MOVE_CONTROL *psMoveCntl, ASTAR_ROUTE *psAStarRoute, SDWORD tx,SDWORD ty)
|
||||
{
|
||||
SDWORD xdiff,ydiff, prevDist, nextDist;
|
||||
|
||||
if (psAStarRoute->numPoints == 0)
|
||||
{
|
||||
// no route to copy do nothing
|
||||
return false;
|
||||
}
|
||||
|
||||
if (psMoveCntl->numPoints == 0)
|
||||
{
|
||||
// no previous route - this has to be better
|
||||
return true;
|
||||
}
|
||||
|
||||
// see which route is closest to the final destination
|
||||
xdiff = world_coord(psMoveCntl->asPath[psMoveCntl->numPoints - 1].x) + TILE_UNITS/2 - tx;
|
||||
ydiff = world_coord(psMoveCntl->asPath[psMoveCntl->numPoints - 1].y) + TILE_UNITS/2 - ty;
|
||||
prevDist = xdiff*xdiff + ydiff*ydiff;
|
||||
|
||||
xdiff = world_coord(psAStarRoute->finalX) + TILE_UNITS/2 - tx;
|
||||
ydiff = world_coord(psAStarRoute->finalY) + TILE_UNITS/2 - ty;
|
||||
nextDist = xdiff*xdiff + ydiff*ydiff;
|
||||
|
||||
if (nextDist < prevDist)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Create a final route from a gateway route
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
|
@ -276,42 +215,27 @@ static BOOL fpathRouteCloser(MOVE_CONTROL *psMoveCntl, ASTAR_ROUTE *psAStarRoute
|
|||
static FPATH_RETVAL fpathGatewayRoute(DROID* psDroid, SDWORD routeMode, SDWORD sx, SDWORD sy,
|
||||
SDWORD fx, SDWORD fy, MOVE_CONTROL *psMoveCntl, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
static ASTAR_ROUTE sAStarRoute;
|
||||
int asret;
|
||||
|
||||
if (routeMode == ASR_NEWROUTE)
|
||||
{
|
||||
// initialise the move control structures
|
||||
psMoveCntl->numPoints = 0;
|
||||
sAStarRoute.numPoints = 0;
|
||||
}
|
||||
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "fpathGatewayRoute: astar route : (%d,%d) -> (%d,%d)",
|
||||
map_coord(sx), map_coord(sy), map_coord(fx), map_coord(fy));
|
||||
asret = fpathAStarRoute(routeMode, &sAStarRoute, sx, sy, fx,fy, propulsion);
|
||||
asret = fpathAStarRoute(routeMode, &psDroid->sMove, sx, sy, fx,fy, propulsion);
|
||||
if (asret == ASR_PARTIAL)
|
||||
{
|
||||
// routing hasn't finished yet
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "fpathGatewayRoute: Reschedule");
|
||||
return FPR_WAIT;
|
||||
}
|
||||
routeMode = ASR_NEWROUTE;
|
||||
|
||||
if (asret == ASR_NEAREST && actionRouteBlockingPos(psDroid, sAStarRoute.finalX,sAStarRoute.finalY))
|
||||
{
|
||||
// found a blocking wall - route to that
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "fpathGatewayRoute: Got blocking wall");
|
||||
return FPR_OK;
|
||||
}
|
||||
else if (asret == ASR_NEAREST)
|
||||
{
|
||||
// all routing was in one zone - this is as good as it's going to be
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "fpathGatewayRoute: Nearest route in same zone");
|
||||
if (fpathRouteCloser(psMoveCntl, &sAStarRoute, fx,fy))
|
||||
{
|
||||
psMoveCntl->numPoints = 0;
|
||||
fpathAppendRoute(psMoveCntl, &sAStarRoute);
|
||||
}
|
||||
return FPR_OK;
|
||||
}
|
||||
else if (asret == ASR_FAILED)
|
||||
|
@ -320,15 +244,7 @@ static FPATH_RETVAL fpathGatewayRoute(DROID* psDroid, SDWORD routeMode, SDWORD s
|
|||
objTrace(LOG_MOVEMENT, psDroid->id, "fpathGatewayRoute: Failed route in same zone");
|
||||
return FPR_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fpathRouteCloser(psMoveCntl, &sAStarRoute, fx,fy))
|
||||
{
|
||||
psMoveCntl->numPoints = 0;
|
||||
fpathAppendRoute(psMoveCntl, &sAStarRoute);
|
||||
}
|
||||
return FPR_OK;
|
||||
}
|
||||
return FPR_OK;
|
||||
}
|
||||
|
||||
// Find a route for an DROID to a location
|
||||
|
|
16
src/game.c
16
src/game.c
|
@ -1469,6 +1469,13 @@ static bool deserializeSaveGameData(PHYSFS_file* fileHandle, SAVE_GAME* serializ
|
|||
#define SAVE_COMP_PROGRAM 8
|
||||
#define SAVE_COMP_WEAPON 9
|
||||
|
||||
typedef struct _path_point
|
||||
{
|
||||
UBYTE x,y;
|
||||
} PATH_POINT;
|
||||
|
||||
#define TRAVELSIZE 100
|
||||
|
||||
typedef struct _save_move_control
|
||||
{
|
||||
UBYTE Status; // Inactive, Navigating or moving point to point status
|
||||
|
@ -1583,7 +1590,6 @@ typedef struct _save_droid_v18
|
|||
DROID_SAVE_V18;
|
||||
} SAVE_DROID_V18;
|
||||
|
||||
|
||||
//DROID_SAVE_20 replaces all previous saves uses 60 character names
|
||||
#define DROID_SAVE_V20 \
|
||||
OBJECT_SAVE_V20; \
|
||||
|
@ -5611,8 +5617,9 @@ static void SaveDroidMoveControl(SAVE_DROID * const psSaveDroid, DROID const * c
|
|||
// Copy over the endian neutral stuff (all UBYTE)
|
||||
psSaveDroid->sMove.Status = psDroid->sMove.Status;
|
||||
psSaveDroid->sMove.Position = psDroid->sMove.Position;
|
||||
psSaveDroid->sMove.numPoints = psDroid->sMove.numPoints;
|
||||
memcpy(&psSaveDroid->sMove.asPath, &psDroid->sMove.asPath, sizeof(psSaveDroid->sMove.asPath));
|
||||
psSaveDroid->sMove.numPoints = MIN(psDroid->sMove.numPoints, TRAVELSIZE);
|
||||
memcpy(&psSaveDroid->sMove.asPath, psDroid->sMove.asPath,
|
||||
MIN(sizeof(psSaveDroid->sMove.asPath), sizeof(*psDroid->sMove.asPath) * psDroid->sMove.numPoints));
|
||||
|
||||
// Little endian SDWORDs
|
||||
psSaveDroid->sMove.DestinationX = PHYSFS_swapSLE32(psDroid->sMove.DestinationX);
|
||||
|
@ -5679,7 +5686,8 @@ static void LoadDroidMoveControl(DROID * const psDroid, SAVE_DROID const * const
|
|||
psDroid->sMove.Status = psSaveDroid->sMove.Status;
|
||||
psDroid->sMove.Position = psSaveDroid->sMove.Position;
|
||||
psDroid->sMove.numPoints = psSaveDroid->sMove.numPoints;
|
||||
memcpy(&psDroid->sMove.asPath, &psSaveDroid->sMove.asPath, sizeof(psSaveDroid->sMove.asPath));
|
||||
psDroid->sMove.asPath = malloc(sizeof(*psDroid->sMove.asPath) * psDroid->sMove.numPoints);
|
||||
memcpy(psDroid->sMove.asPath, &psSaveDroid->sMove.asPath, sizeof(*psDroid->sMove.asPath) * psDroid->sMove.numPoints);
|
||||
|
||||
// Little endian SDWORDs
|
||||
psDroid->sMove.DestinationX = PHYSFS_swapSLE32(psSaveDroid->sMove.DestinationX);
|
||||
|
|
|
@ -1505,7 +1505,7 @@ bool readVisibilityData(const char* fileName)
|
|||
static void astarTest(const char *name, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
int asret, i;
|
||||
ASTAR_ROUTE route;
|
||||
MOVE_CONTROL route;
|
||||
int x = world_coord(x1);
|
||||
int y = world_coord(y1);
|
||||
int endx = world_coord(x2);
|
||||
|
@ -1518,6 +1518,7 @@ static void astarTest(const char *name, int x1, int y1, int x2, int y2)
|
|||
retval = levLoadData(name, NULL, 0);
|
||||
ASSERT(retval, "Could not load %s", name);
|
||||
fpathInitialise();
|
||||
route.asPath = NULL;
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
iterations = 1;
|
||||
|
@ -1532,6 +1533,8 @@ static void astarTest(const char *name, int x1, int y1, int x2, int y2)
|
|||
asret = fpathAStarRoute(ASR_CONTINUE, &route, x, y, endx, endy, WHEELED);
|
||||
iterations++;
|
||||
}
|
||||
free(route.asPath);
|
||||
route.asPath = NULL;
|
||||
}
|
||||
stop = clock();
|
||||
fprintf(stdout, "\t\tPath-finding timing %s: %.02f (%d nodes, %d iterations)\n", name,
|
||||
|
|
|
@ -24,22 +24,15 @@
|
|||
#ifndef __INCLUDED_MOVEDEF_H__
|
||||
#define __INCLUDED_MOVEDEF_H__
|
||||
|
||||
#define TRAVELSIZE 100
|
||||
|
||||
//Watermelon:num of VTOL weapons should be same as DROID_MAXWEAPS
|
||||
#define VTOL_MAXWEAPS 3
|
||||
|
||||
typedef struct _path_point
|
||||
{
|
||||
UBYTE x,y;
|
||||
} PATH_POINT;
|
||||
|
||||
typedef struct _move_control
|
||||
{
|
||||
UBYTE Status; // Inactive, Navigating or moving point to point status
|
||||
UBYTE Position; // Position in asPath
|
||||
UBYTE numPoints; // number of points in asPath
|
||||
PATH_POINT asPath[TRAVELSIZE]; // Pointer to list of block X,Y coordinates.
|
||||
Vector2i *asPath; // Pointer to list of block X,Y coordinates.
|
||||
SDWORD DestinationX; // DestinationX,Y should match objects current X,Y
|
||||
SDWORD DestinationY; // location for this movement to be complete.
|
||||
SDWORD srcX,srcY,targetX,targetY;
|
||||
|
|
|
@ -432,6 +432,10 @@ void killDroid(DROID *psDel)
|
|||
setDroidActionTarget(psDel, NULL, i);
|
||||
}
|
||||
setDroidBase(psDel, NULL);
|
||||
if (psDel->sMove.asPath)
|
||||
{
|
||||
free(psDel->sMove.asPath);
|
||||
}
|
||||
|
||||
destroyObject((BASE_OBJECT**)apsDroidLists, (BASE_OBJECT*)psDel);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue