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-861f7616d084
master
Per Inge Mathisen 2008-05-07 20:23:39 +00:00
parent ab90207cc0
commit 1a42ffda05
10 changed files with 38 additions and 223 deletions

View File

@ -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

View File

@ -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);

View File

@ -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
{

View File

@ -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
*/

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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,

View File

@ -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;

View File

@ -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);
}