Pass propulsion type as a parameter to raycasting, path-finding and tile
blocking functions so that we do not have to set global state to know which kind of propulsion we are testing. This change is experimental, and may break VTOL behaviour subtly, please do not backport. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@4960 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
1fd785ba09
commit
f3a5558e21
12
src/astar.c
12
src/astar.c
|
@ -319,7 +319,7 @@ static BOOL obstruction;
|
|||
|
||||
/** The visibility ray callback
|
||||
*/
|
||||
static BOOL fpathVisCallback(SDWORD x, SDWORD y, SDWORD dist)
|
||||
static BOOL fpathVisCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
SDWORD vx,vy;
|
||||
|
||||
|
@ -333,7 +333,7 @@ static BOOL fpathVisCallback(SDWORD x, SDWORD y, SDWORD dist)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (fpathBlockingTile(map_coord(x), map_coord(y)))
|
||||
if (fpathBlockingTile(map_coord(x), map_coord(y), propulsion))
|
||||
{
|
||||
// found an obstruction
|
||||
obstruction = true;
|
||||
|
@ -358,8 +358,7 @@ BOOL fpathTileLOS(SDWORD x1,SDWORD y1, SDWORD x2,SDWORD y2)
|
|||
vectorY = y1 - y2;
|
||||
obstruction = false;
|
||||
|
||||
rayCast(x1,y1, rayPointsToAngle(x1,y1,x2,y2),
|
||||
RAY_MAXLEN, fpathVisCallback);
|
||||
rayCast(x1, y1, rayPointsToAngle(x1, y1, x2, y2), RAY_MAXLEN, INVALID_PROP_TYPE, fpathVisCallback);
|
||||
|
||||
return !obstruction;
|
||||
}
|
||||
|
@ -399,8 +398,7 @@ static void fpathOptimise(FP_NODE *psRoute)
|
|||
} while (psCurr);
|
||||
}
|
||||
|
||||
SDWORD fpathAStarRoute(SDWORD routeMode, ASTAR_ROUTE *psRoutePoints,
|
||||
SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy)
|
||||
SDWORD fpathAStarRoute(SDWORD routeMode, ASTAR_ROUTE *psRoutePoints, SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
FP_NODE *psFound, *psCurr, *psNew, *psParent, *psNext;
|
||||
static FP_NODE *psNearest, *psRoute;
|
||||
|
@ -493,7 +491,7 @@ static FP_NODE *psNearest, *psRoute;
|
|||
}
|
||||
|
||||
// If the tile hasn't been visited see if it is a blocking tile
|
||||
if (!psFound && fpathBlockingTile(x,y))
|
||||
if (!psFound && fpathBlockingTile(x, y, propulsion))
|
||||
{
|
||||
// tile is blocked, skip it
|
||||
// debug( LOG_NEVER, "blocked : %3d, %3d\n", x, y );
|
||||
|
|
|
@ -81,8 +81,7 @@ enum
|
|||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
extern SDWORD fpathAStarRoute(SDWORD routeMode, ASTAR_ROUTE *psRoutePoints,
|
||||
SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy);
|
||||
SDWORD fpathAStarRoute(SDWORD routeMode, ASTAR_ROUTE *psRoutePoints, SDWORD sx, SDWORD sy, SDWORD fx, SDWORD fy, PROPULSION_TYPE propulsion);
|
||||
|
||||
/** Check LOS (Line Of Sight) between two tiles
|
||||
*/
|
||||
|
|
51
src/droid.c
51
src/droid.c
|
@ -3821,7 +3821,7 @@ static BOOL oneDroid(UDWORD x, UDWORD y)
|
|||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// returns true if it's a sensible place to put that droid.
|
||||
BOOL sensiblePlace(SDWORD x, SDWORD y)
|
||||
static BOOL sensiblePlace(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
UDWORD count=0;
|
||||
|
||||
|
@ -3831,32 +3831,34 @@ BOOL sensiblePlace(SDWORD x, SDWORD y)
|
|||
if((y < TOO_NEAR_EDGE) || (y > (SDWORD)(mapHeight - TOO_NEAR_EDGE)))
|
||||
return false;
|
||||
|
||||
//check no features there
|
||||
// check no features there
|
||||
if(TileHasFeature(mapTile(x,y)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// not on a blocking tile.
|
||||
if( fpathBlockingTile(x,y) )
|
||||
if (fpathBlockingTile(x, y, propulsion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// shouldn't next to more than one blocking tile, to avoid windy paths.
|
||||
if( fpathBlockingTile(x-1 ,y-1) )
|
||||
if (fpathBlockingTile(x - 1, y - 1, propulsion))
|
||||
count++;
|
||||
if( fpathBlockingTile(x,y-1) )
|
||||
if (fpathBlockingTile(x, y - 1, propulsion))
|
||||
count++;
|
||||
if( fpathBlockingTile(x+1,y-1) )
|
||||
if (fpathBlockingTile(x + 1, y - 1, propulsion))
|
||||
count++;
|
||||
if( fpathBlockingTile(x-1,y) )
|
||||
if (fpathBlockingTile(x - 1, y, propulsion))
|
||||
count++;
|
||||
if( fpathBlockingTile(x+1,y) )
|
||||
if (fpathBlockingTile(x + 1, y, propulsion))
|
||||
count++;
|
||||
if( fpathBlockingTile(x-1,y+1) )
|
||||
if (fpathBlockingTile(x -1, y + 1, propulsion))
|
||||
count++;
|
||||
if( fpathBlockingTile(x,y+1) )
|
||||
if (fpathBlockingTile(x, y + 1, propulsion))
|
||||
count++;
|
||||
if( fpathBlockingTile(x+1,y+1) )
|
||||
if (fpathBlockingTile(x +1, y + 1, propulsion))
|
||||
count++;
|
||||
|
||||
if(count > 1)
|
||||
|
@ -3865,24 +3867,11 @@ BOOL sensiblePlace(SDWORD x, SDWORD y)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
BOOL normalPAT(UDWORD x, UDWORD y)
|
||||
{
|
||||
if(sensiblePlace(x,y) && noDroid(x,y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Should stop things being placed in inaccessible areas?
|
||||
// Should stop things being placed in inaccessible areas? Assume wheeled propulsion.
|
||||
BOOL zonedPAT(UDWORD x, UDWORD y)
|
||||
{
|
||||
if (sensiblePlace(x,y) && noDroid(x,y))
|
||||
if (sensiblePlace(x, y, WHEELED) && noDroid(x,y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
@ -3905,7 +3894,7 @@ BOOL pickATileGen(UDWORD *x, UDWORD *y, UBYTE numIterations,
|
|||
ASSERT( *y<mapHeight,"y coordinate is off-map for pickATileGen" );
|
||||
|
||||
/* Exit if they're fine! */
|
||||
if(sensiblePlace(*x,*y) && noDroid(*x,*y))
|
||||
if (sensiblePlace(*x, *y, WHEELED) && noDroid(*x,*y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
@ -4004,7 +3993,7 @@ BOOL pickATile(UDWORD *x, UDWORD *y, UBYTE numIterations)
|
|||
ASSERT( *y<mapHeight,"y coordinate is off-map for pickATile" );
|
||||
|
||||
/* Exit if they're fine! */
|
||||
if(sensiblePlace(*x,*y) && noDroid(*x,*y))
|
||||
if (sensiblePlace(*x, *y, WHEELED) && noDroid(*x,*y))
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
@ -4024,7 +4013,7 @@ BOOL pickATile(UDWORD *x, UDWORD *y, UBYTE numIterations)
|
|||
if(i==startX || i==endX || j==startY || j==endY)
|
||||
{
|
||||
/* Good enough? */
|
||||
if(sensiblePlace(i,j) && noDroid(i,j))
|
||||
if (sensiblePlace(i, j, WHEELED) && noDroid(i,j))
|
||||
{
|
||||
/* Set exit conditions and get out NOW */
|
||||
*x = i; *y = j;
|
||||
|
@ -4057,7 +4046,7 @@ PICKTILE pickHalfATile(UDWORD *x, UDWORD *y, UBYTE numIterations)
|
|||
}
|
||||
|
||||
/* Exit if they're fine! */
|
||||
if (sensiblePlace(*x, *y) && oneDroid(*x, *y))
|
||||
if (sensiblePlace(*x, *y, WHEELED) && oneDroid(*x, *y))
|
||||
{
|
||||
return HALF_FREE_TILE;
|
||||
}
|
||||
|
@ -4079,7 +4068,7 @@ PICKTILE pickHalfATile(UDWORD *x, UDWORD *y, UBYTE numIterations)
|
|||
if(i==startX || i==endX || j==startY || j==endY)
|
||||
{
|
||||
/* Good enough? */
|
||||
if(sensiblePlace(i,j) && oneDroid(i,j))
|
||||
if (sensiblePlace(i, j, WHEELED) && oneDroid(i,j))
|
||||
{
|
||||
/* Set exit conditions and get out NOW */
|
||||
*x = i; *y = j;
|
||||
|
|
|
@ -264,13 +264,10 @@ extern void templateSetName(DROID_TEMPLATE *psTemplate,char *pName);
|
|||
|
||||
// returns true when no droid on x,y square.
|
||||
extern BOOL noDroid (UDWORD x, UDWORD y); // true if no droid at x,y
|
||||
// returns true if it's a sensible place to put that droid.
|
||||
extern BOOL sensiblePlace (SDWORD x, SDWORD y); // true if x,y is an ok place
|
||||
// returns an x/y coord to place a droid
|
||||
extern BOOL pickATile (UDWORD *x0,UDWORD *y0, UBYTE numIterations);
|
||||
extern PICKTILE pickHalfATile (UDWORD *x, UDWORD *y, UBYTE numIterations);
|
||||
extern BOOL pickATile2 (UDWORD *x, UDWORD *y, UDWORD numIterations);
|
||||
extern BOOL normalPAT(UDWORD x, UDWORD y);
|
||||
extern BOOL zonedPAT(UDWORD x, UDWORD y);
|
||||
extern BOOL pickATileGen(UDWORD *x, UDWORD *y, UBYTE numIterations,
|
||||
BOOL (*function)(UDWORD x, UDWORD y));
|
||||
|
|
|
@ -434,7 +434,7 @@ static void formationFindFree(FORMATION *psFormation, DROID* psDroid,
|
|||
{
|
||||
// calculate the position on the line
|
||||
formationCalcPos(psFormation, line, currDist+objRadius, &x,&y);
|
||||
if (fpathBlockingTile(map_coord(x), map_coord(y)))
|
||||
if (fpathBlockingTile(map_coord(x), map_coord(y), getPropulsionStats(psDroid)->propulsionType))
|
||||
{
|
||||
// blocked, try the next rank
|
||||
found = false;
|
||||
|
|
179
src/fpath.c
179
src/fpath.c
|
@ -62,9 +62,6 @@ static const Vector2i aDirOffset[NUM_DIR] =
|
|||
{ 1, 1},
|
||||
};
|
||||
|
||||
// function pointer for the blocking tile check
|
||||
BOOL (*fpathBlockingTile)(SDWORD x, SDWORD y);
|
||||
|
||||
// if a route is spread over a number of frames this stores the droid
|
||||
// the route is being done for
|
||||
static DROID* psPartialRouteDroid = NULL;
|
||||
|
@ -76,12 +73,10 @@ static SDWORD partialSX,partialSY, partialTX,partialTY;
|
|||
static SDWORD lastPartialFrame;
|
||||
|
||||
static BOOL fpathFindRoute(DROID *psDroid, SDWORD sX,SDWORD sY, SDWORD tX,SDWORD tY);
|
||||
static BOOL fpathLiftBlockingTile(SDWORD x, SDWORD y);
|
||||
|
||||
// initialise the findpath module
|
||||
BOOL fpathInitialise(void)
|
||||
{
|
||||
fpathBlockingTile = fpathGroundBlockingTile;
|
||||
psPartialRouteDroid = NULL;
|
||||
|
||||
return true;
|
||||
|
@ -106,96 +101,42 @@ void fpathUpdate(void)
|
|||
}
|
||||
|
||||
// Check if the map tile at a location blocks a droid
|
||||
BOOL fpathGroundBlockingTile(SDWORD x, SDWORD y)
|
||||
BOOL fpathBlockingTile(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
MAPTILE *psTile;
|
||||
|
||||
/* check VTOL limits if not routing */
|
||||
if (x < scrollMinX + 1
|
||||
|| y < scrollMinY + 1
|
||||
|| x >= scrollMaxX - 1
|
||||
|| y >= scrollMaxY - 1)
|
||||
{
|
||||
// coords off map - auto blocking tile
|
||||
return true;
|
||||
}
|
||||
|
||||
ASSERT(x >= 0 && y >= 0 && x < mapWidth && y < mapHeight, "fpathGroundBlockingTile: off map")
|
||||
|
||||
psTile = mapTile(x, y);
|
||||
|
||||
if (psTile->tileInfoBits & BITS_FPATHBLOCK
|
||||
|| (TileIsOccupied(psTile)
|
||||
&& !TILE_IS_NOTBLOCKING(psTile))
|
||||
|| terrainType(psTile) == TER_CLIFFFACE
|
||||
|| terrainType(psTile) == TER_WATER)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the map tile at a location blocks a droid
|
||||
BOOL fpathHoverBlockingTile(SDWORD x, SDWORD y)
|
||||
{
|
||||
MAPTILE *psTile;
|
||||
|
||||
if (x < scrollMinX + 1
|
||||
|| y < scrollMinY + 1
|
||||
|| x >= scrollMaxX - 1
|
||||
|| y >= scrollMaxY - 1)
|
||||
{
|
||||
// coords off map - auto blocking tile
|
||||
return true;
|
||||
}
|
||||
|
||||
ASSERT(x >= 0 && y >= 0 && x < mapWidth && y < mapHeight, "fpathHoverBlockingTile: off map")
|
||||
|
||||
psTile = mapTile(x, y);
|
||||
|
||||
if (psTile->tileInfoBits & BITS_FPATHBLOCK
|
||||
|| (TileIsOccupied(psTile)
|
||||
&& !TILE_IS_NOTBLOCKING(psTile))
|
||||
|| terrainType(psTile) == TER_CLIFFFACE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Check if the map tile at a location blocks a VTOL droid
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
static BOOL fpathLiftBlockingTile(SDWORD x, SDWORD y)
|
||||
{
|
||||
MAPTILE *psTile;
|
||||
|
||||
// All tiles outside of the map are blocking
|
||||
/* All tiles outside of the map and on map border are blocking. */
|
||||
if (x < 1 || y < 1 || x >= mapWidth - 1 || y >= mapHeight - 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
psTile = mapTile(x, y);
|
||||
|
||||
// Only tall structures are blocking now
|
||||
return TileHasTallStructure(psTile);
|
||||
}
|
||||
|
||||
// Check if an edge map tile blocks a vtol (for sliding at map edge)
|
||||
BOOL fpathLiftSlideBlockingTile(SDWORD x, SDWORD y)
|
||||
{
|
||||
if (x < 1 || y < 1 || x >= mapWidth - 1 || y >= mapHeight - 1)
|
||||
/* Check scroll limits (used in campaign to partition the map. */
|
||||
if (propulsion != LIFT && (x < scrollMinX + 1 || y < scrollMinY + 1 || x >= scrollMaxX - 1 || y >= scrollMaxY - 1))
|
||||
{
|
||||
// coords off map - auto blocking tile
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
psTile = mapTile(x, y);
|
||||
|
||||
// Only tall structures are blocking VTOL now
|
||||
if (propulsion == LIFT && !TileHasTallStructure(psTile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (propulsion == LIFT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (psTile->tileInfoBits & BITS_FPATHBLOCK || (TileIsOccupied(psTile) && !TILE_IS_NOTBLOCKING(psTile))
|
||||
|| terrainType(psTile) == TER_CLIFFFACE || (terrainType(psTile) == TER_WATER && propulsion != HOVER))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Calculate the distance to a tile from a point
|
||||
|
@ -222,9 +163,9 @@ static BOOL obstruction;
|
|||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
static BOOL fpathEndPointCallback(SDWORD x, SDWORD y, SDWORD dist)
|
||||
static BOOL fpathEndPointCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
SDWORD vx,vy;
|
||||
SDWORD vx, vy;
|
||||
|
||||
dist = dist;
|
||||
|
||||
|
@ -237,7 +178,7 @@ static BOOL fpathEndPointCallback(SDWORD x, SDWORD y, SDWORD dist)
|
|||
}
|
||||
|
||||
// note the last clear tile
|
||||
if (!fpathBlockingTile(map_coord(x), map_coord(y)))
|
||||
if (!fpathBlockingTile(map_coord(x), map_coord(y), propulsion))
|
||||
{
|
||||
clearX = (x & ~TILE_MASK) + TILE_UNITS/2;
|
||||
clearY = (y & ~TILE_MASK) + TILE_UNITS/2;
|
||||
|
@ -333,7 +274,7 @@ static BOOL fpathRouteCloser(MOVE_CONTROL *psMoveCntl, ASTAR_ROUTE *psAStarRoute
|
|||
* @ingroup pathfinding
|
||||
*/
|
||||
static FPATH_RETVAL fpathGatewayRoute(DROID* psDroid, SDWORD routeMode, SDWORD sx, SDWORD sy,
|
||||
SDWORD fx, SDWORD fy, MOVE_CONTROL *psMoveCntl)
|
||||
SDWORD fx, SDWORD fy, MOVE_CONTROL *psMoveCntl, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
static ASTAR_ROUTE sAStarRoute;
|
||||
int asret;
|
||||
|
@ -347,7 +288,7 @@ static FPATH_RETVAL fpathGatewayRoute(DROID* psDroid, SDWORD routeMode, SDWORD s
|
|||
|
||||
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);
|
||||
asret = fpathAStarRoute(routeMode, &sAStarRoute, sx, sy, fx,fy, propulsion);
|
||||
if (asret == ASR_PARTIAL)
|
||||
{
|
||||
// routing hasn't finished yet
|
||||
|
@ -390,22 +331,6 @@ static FPATH_RETVAL fpathGatewayRoute(DROID* psDroid, SDWORD routeMode, SDWORD s
|
|||
}
|
||||
}
|
||||
|
||||
// set the correct blocking tile function
|
||||
void fpathSetBlockingTile( UBYTE ubPropulsionType )
|
||||
{
|
||||
switch ( ubPropulsionType )
|
||||
{
|
||||
case HOVER:
|
||||
fpathBlockingTile = fpathHoverBlockingTile;
|
||||
break;
|
||||
case LIFT:
|
||||
fpathBlockingTile = fpathLiftBlockingTile;
|
||||
break;
|
||||
default:
|
||||
fpathBlockingTile = fpathGroundBlockingTile;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a route for an DROID to a location
|
||||
FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
||||
{
|
||||
|
@ -454,13 +379,11 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
|
||||
ASSERT(psPropStats != NULL, "invalid propulsion stats pointer");
|
||||
|
||||
fpathSetBlockingTile( psPropStats->propulsionType );
|
||||
|
||||
if (psPartialRouteDroid == NULL || psPartialRouteDroid != psDroid)
|
||||
{
|
||||
// check whether the start point of the route
|
||||
// is a blocking tile and find an alternative if it is
|
||||
if (fpathBlockingTile(map_coord(startX), map_coord(startY)))
|
||||
if (fpathBlockingTile(map_coord(startX), map_coord(startY), psPropStats->propulsionType))
|
||||
{
|
||||
// find the nearest non blocking tile to the DROID
|
||||
minDist = SDWORD_MAX;
|
||||
|
@ -469,7 +392,7 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
{
|
||||
int x = map_coord(startX) + aDirOffset[dir].x;
|
||||
int y = map_coord(startY) + aDirOffset[dir].y;
|
||||
if (!fpathBlockingTile(x,y))
|
||||
if (!fpathBlockingTile(x, y, psPropStats->propulsionType))
|
||||
{
|
||||
tileDist = fpathDistToTile(x,y, startX,startY);
|
||||
if (tileDist < minDist)
|
||||
|
@ -483,9 +406,8 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
if (nearestDir == NUM_DIR)
|
||||
{
|
||||
// surrounded by blocking tiles, give up
|
||||
retVal = FPR_FAILED;
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "droid %u: route failed (surrouned by blocking)", (unsigned int)psDroid->id);
|
||||
goto exit;
|
||||
return FPR_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -508,25 +430,24 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
obstruction = false;
|
||||
|
||||
// cast the ray to find the last clear tile before the obstruction
|
||||
rayCast(startX,startY, rayPointsToAngle(startX,startY, finalX, finalY),
|
||||
RAY_MAXLEN, fpathEndPointCallback);
|
||||
rayCast(startX, startY, rayPointsToAngle(startX,startY, finalX, finalY), RAY_MAXLEN,
|
||||
psPropStats->propulsionType, fpathEndPointCallback);
|
||||
|
||||
if (!obstruction)
|
||||
{
|
||||
// no obstructions - trivial route
|
||||
fpathSetDirectRoute(psDroid, targetX, targetY);
|
||||
retVal = FPR_OK;
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "droid %u: trivial route", (unsigned int)psDroid->id);
|
||||
if (psPartialRouteDroid != NULL)
|
||||
{
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "Unit %u: trivial route during multi-frame route", (unsigned int)psDroid->id);
|
||||
}
|
||||
goto exit;
|
||||
return FPR_OK;
|
||||
}
|
||||
|
||||
// check whether the end point of the route
|
||||
// is a blocking tile and find an alternative if it is
|
||||
if (fpathBlockingTile(map_coord(targetX), map_coord(targetY)))
|
||||
if (fpathBlockingTile(map_coord(targetX), map_coord(targetY), psPropStats->propulsionType))
|
||||
{
|
||||
// route to the last clear tile found by the raycast
|
||||
// Does this code work? - Per
|
||||
|
@ -548,7 +469,7 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
{
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "droid %u: found existing route", (unsigned int)psDroid->id);
|
||||
}
|
||||
goto exit;
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,10 +479,6 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
ASSERT( targetX >= 0 && targetX < (SDWORD)mapWidth*TILE_UNITS &&
|
||||
targetY >= 0 && targetY < (SDWORD)mapHeight*TILE_UNITS,
|
||||
"target coords off map" );
|
||||
ASSERT( fpathBlockingTile == fpathGroundBlockingTile ||
|
||||
fpathBlockingTile == fpathHoverBlockingTile ||
|
||||
fpathBlockingTile == fpathLiftBlockingTile,
|
||||
"invalid blocking function" );
|
||||
|
||||
ASSERT(astarInner >= 0, "astarInner overflowed!");
|
||||
|
||||
|
@ -570,14 +487,12 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
// Time out
|
||||
if (psPartialRouteDroid == psDroid)
|
||||
{
|
||||
retVal = FPR_WAIT;
|
||||
goto exit;
|
||||
return FPR_WAIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "droid %u: reschedule", (unsigned int)psDroid->id);
|
||||
retVal = FPR_RESCHEDULE;
|
||||
goto exit;
|
||||
return FPR_RESCHEDULE;
|
||||
}
|
||||
}
|
||||
else if ((psPartialRouteDroid != NULL
|
||||
|
@ -587,20 +502,19 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
&& psNextRouteDroid != psDroid))
|
||||
{
|
||||
// Not our turn
|
||||
retVal = FPR_RESCHEDULE;
|
||||
goto exit;
|
||||
return FPR_RESCHEDULE;
|
||||
}
|
||||
|
||||
// Now actually create a route
|
||||
if (psPartialRouteDroid == NULL)
|
||||
{
|
||||
retVal = fpathGatewayRoute(psDroid, ASR_NEWROUTE, startX,startY, targetX,targetY, psMoveCntl);
|
||||
retVal = fpathGatewayRoute(psDroid, ASR_NEWROUTE, startX,startY, targetX,targetY, psMoveCntl, psPropStats->propulsionType);
|
||||
}
|
||||
else
|
||||
{
|
||||
objTrace(LOG_MOVEMENT, psDroid->id, "Partial Route");
|
||||
psPartialRouteDroid = NULL;
|
||||
retVal = fpathGatewayRoute(psDroid, ASR_CONTINUE, startX,startY, targetX,targetY, psMoveCntl);
|
||||
retVal = fpathGatewayRoute(psDroid, ASR_CONTINUE, startX,startY, targetX,targetY, psMoveCntl, psPropStats->propulsionType);
|
||||
}
|
||||
if (retVal == FPR_WAIT)
|
||||
{
|
||||
|
@ -617,11 +531,6 @@ FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD tX, SDWORD tY)
|
|||
retVal = FPR_OK;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
||||
// reset the blocking tile function
|
||||
fpathBlockingTile = fpathGroundBlockingTile;
|
||||
|
||||
#ifdef DEBUG_MAP
|
||||
{
|
||||
MAPTILE *psTile;
|
||||
|
@ -675,12 +584,16 @@ static BOOL fpathFindRoute(DROID *psDroid, SDWORD sX,SDWORD sY, SDWORD tX,SDWORD
|
|||
DROID *psCurr;
|
||||
SDWORD i, startX,startY, index;
|
||||
FORMATION* psFormation = formationFind(tX, tY);
|
||||
PROPULSION_STATS *psPropStats;
|
||||
|
||||
if (!psFormation)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
|
||||
ASSERT(psPropStats != NULL, "invalid propulsion stats pointer");
|
||||
|
||||
// now look for a unit in this formation with a route that can be used
|
||||
for (psCurr = apsDroidLists[psDroid->player]; psCurr; psCurr = psCurr->psNext)
|
||||
{
|
||||
|
@ -707,8 +620,8 @@ static BOOL fpathFindRoute(DROID *psDroid, SDWORD sX,SDWORD sY, SDWORD tX,SDWORD
|
|||
obstruction = false;
|
||||
|
||||
// cast the ray to find the last clear tile before the obstruction
|
||||
rayCast(startX,startY, rayPointsToAngle(startX,startY, finalX, finalY),
|
||||
RAY_MAXLEN, fpathEndPointCallback);
|
||||
rayCast(startX, startY, rayPointsToAngle(startX,startY, finalX, finalY), RAY_MAXLEN,
|
||||
psPropStats->propulsionType, fpathEndPointCallback);
|
||||
|
||||
if (!obstruction)
|
||||
{
|
||||
|
|
29
src/fpath.h
29
src/fpath.h
|
@ -62,34 +62,7 @@ extern FPATH_RETVAL fpathRoute(DROID* psDroid, SDWORD targetX, SDWORD targetY);
|
|||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
extern BOOL (*fpathBlockingTile)(SDWORD x, SDWORD y);
|
||||
|
||||
/** Check if the map tile at the given location blocks a droid with "normal"
|
||||
* propulsion.
|
||||
*
|
||||
* @return true if the given tile is blocking for a "normal" droid
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
extern BOOL fpathGroundBlockingTile(SDWORD x, SDWORD y);
|
||||
|
||||
/** Check if the map tile at the given location blocks a droid with hovercraft
|
||||
* propulsion.
|
||||
*
|
||||
* @return true if the given tile is blocking for a hovercraft droid
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
extern BOOL fpathHoverBlockingTile(SDWORD x, SDWORD y);
|
||||
|
||||
/** Check if the map tile at the given location blocks a droid with VTOL
|
||||
* propulsion.
|
||||
*
|
||||
* @return true if the given tile is blocking for a VTOL droid
|
||||
*
|
||||
* @ingroup pathfinding
|
||||
*/
|
||||
extern BOOL fpathLiftSlideBlockingTile(SDWORD x, SDWORD y);
|
||||
extern BOOL fpathBlockingTile(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion);
|
||||
|
||||
/** Set the correct blocking tile function.
|
||||
* @ingroup pathfinding
|
||||
|
|
|
@ -1524,12 +1524,12 @@ static void astarTest(const char *name, int x1, int y1, int x2, int y2)
|
|||
route.numPoints = 0;
|
||||
astarResetCounters();
|
||||
ASSERT(astarInner == 0, "astarInner not reset");
|
||||
asret = fpathAStarRoute(ASR_NEWROUTE, &route, x, y, endx, endy);
|
||||
asret = fpathAStarRoute(ASR_NEWROUTE, &route, x, y, endx, endy, WHEELED);
|
||||
while (asret == ASR_PARTIAL)
|
||||
{
|
||||
astarResetCounters();
|
||||
ASSERT(astarInner == 0, "astarInner not reset");
|
||||
asret = fpathAStarRoute(ASR_CONTINUE, &route, x, y, endx, endy);
|
||||
asret = fpathAStarRoute(ASR_CONTINUE, &route, x, y, endx, endy, WHEELED);
|
||||
iterations++;
|
||||
}
|
||||
}
|
||||
|
|
65
src/move.c
65
src/move.c
|
@ -600,17 +600,17 @@ static void moveShuffleDroid(DROID *psDroid, UDWORD shuffleStart, SDWORD sx, SDW
|
|||
|
||||
// check for blocking tiles
|
||||
if (fpathBlockingTile(map_coord((SDWORD)psDroid->pos.x + lvx),
|
||||
map_coord((SDWORD)psDroid->pos.y + lvy)))
|
||||
map_coord((SDWORD)psDroid->pos.y + lvy), getPropulsionStats(psDroid)->propulsionType))
|
||||
{
|
||||
leftClear = false;
|
||||
}
|
||||
else if (fpathBlockingTile(map_coord((SDWORD)psDroid->pos.x + rvx),
|
||||
map_coord((SDWORD)psDroid->pos.y + rvy)))
|
||||
map_coord((SDWORD)psDroid->pos.y + rvy), getPropulsionStats(psDroid)->propulsionType))
|
||||
{
|
||||
rightClear = false;
|
||||
}
|
||||
else if (fpathBlockingTile(map_coord((SDWORD)psDroid->pos.x + svx),
|
||||
map_coord((SDWORD)psDroid->pos.y + svy)))
|
||||
map_coord((SDWORD)psDroid->pos.y + svy), getPropulsionStats(psDroid)->propulsionType))
|
||||
{
|
||||
frontClear = false;
|
||||
}
|
||||
|
@ -1161,6 +1161,7 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
SDWORD horizX,horizY, vertX,vertY;
|
||||
BOOL blocked;
|
||||
SDWORD slideDir;
|
||||
PROPULSION_TYPE propulsion = getPropulsionStats(psDroid)->propulsionType;
|
||||
|
||||
CHECK_DROID(psDroid);
|
||||
|
||||
|
@ -1175,7 +1176,7 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
nty = map_coord(ny);
|
||||
|
||||
// is the new tile blocking?
|
||||
if (fpathBlockingTile(ntx,nty))
|
||||
if (fpathBlockingTile(ntx, nty, propulsion))
|
||||
{
|
||||
blocked = true;
|
||||
}
|
||||
|
@ -1219,7 +1220,7 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
vertX = ntx;
|
||||
vertY = my < 0 ? nty + 1 : nty - 1;
|
||||
|
||||
if (fpathBlockingTile(horizX,horizY) && fpathBlockingTile(vertX,vertY))
|
||||
if (fpathBlockingTile(horizX, horizY, propulsion) && fpathBlockingTile(vertX, vertY, propulsion))
|
||||
{
|
||||
// in a corner - choose an arbitrary slide
|
||||
if (ONEINTWO)
|
||||
|
@ -1233,11 +1234,11 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
*pmy = 0;
|
||||
}
|
||||
}
|
||||
else if (fpathBlockingTile(horizX,horizY))
|
||||
else if (fpathBlockingTile(horizX, horizY, propulsion))
|
||||
{
|
||||
*pmy = 0;
|
||||
}
|
||||
else if (fpathBlockingTile(vertX,vertY))
|
||||
else if (fpathBlockingTile(vertX, vertY, propulsion))
|
||||
{
|
||||
*pmx = 0;
|
||||
}
|
||||
|
@ -1252,7 +1253,7 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
if ((psDroid->pos.y & TILE_MASK) > TILE_UNITS/2)
|
||||
{
|
||||
// top half
|
||||
if (fpathBlockingTile(ntx,nty+1))
|
||||
if (fpathBlockingTile(ntx, nty + 1, propulsion))
|
||||
{
|
||||
*pmx = 0;
|
||||
}
|
||||
|
@ -1264,7 +1265,7 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
else
|
||||
{
|
||||
// bottom half
|
||||
if (fpathBlockingTile(ntx,nty-1))
|
||||
if (fpathBlockingTile(ntx, nty - 1, propulsion))
|
||||
{
|
||||
*pmx = 0;
|
||||
}
|
||||
|
@ -1280,7 +1281,7 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
if ((psDroid->pos.x & TILE_MASK) > TILE_UNITS/2)
|
||||
{
|
||||
// top half
|
||||
if (fpathBlockingTile(ntx+1,nty))
|
||||
if (fpathBlockingTile(ntx + 1, nty, propulsion))
|
||||
{
|
||||
*pmy = 0;
|
||||
}
|
||||
|
@ -1292,7 +1293,7 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
else
|
||||
{
|
||||
// bottom half
|
||||
if (fpathBlockingTile(ntx-1,nty))
|
||||
if (fpathBlockingTile(ntx - 1, nty, propulsion))
|
||||
{
|
||||
*pmy = 0;
|
||||
}
|
||||
|
@ -1316,12 +1317,12 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
if (inty < TILE_UNITS/2)
|
||||
{
|
||||
// top left
|
||||
if ((mx < 0) && fpathBlockingTile(tx-1, ty))
|
||||
if ((mx < 0) && fpathBlockingTile(tx - 1, ty, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpy = (jumpy & ~TILE_MASK) -1;
|
||||
}
|
||||
if ((my < 0) && fpathBlockingTile(tx, ty-1))
|
||||
if ((my < 0) && fpathBlockingTile(tx, ty - 1, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpx = (jumpx & ~TILE_MASK) -1;
|
||||
|
@ -1330,12 +1331,12 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
else
|
||||
{
|
||||
// bottom left
|
||||
if ((mx < 0) && fpathBlockingTile(tx-1, ty))
|
||||
if ((mx < 0) && fpathBlockingTile(tx - 1, ty, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpy = (jumpy & ~TILE_MASK) + TILE_UNITS;
|
||||
}
|
||||
if ((my >= 0) && fpathBlockingTile(tx, ty+1))
|
||||
if ((my >= 0) && fpathBlockingTile(tx, ty + 1, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpx = (jumpx & ~TILE_MASK) -1;
|
||||
|
@ -1347,12 +1348,12 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
if (inty < TILE_UNITS/2)
|
||||
{
|
||||
// top right
|
||||
if ((mx >= 0) && fpathBlockingTile(tx+1, ty))
|
||||
if ((mx >= 0) && fpathBlockingTile(tx + 1, ty, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpy = (jumpy & ~TILE_MASK) -1;
|
||||
}
|
||||
if ((my < 0) && fpathBlockingTile(tx, ty-1))
|
||||
if ((my < 0) && fpathBlockingTile(tx, ty - 1, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpx = (jumpx & ~TILE_MASK) + TILE_UNITS;
|
||||
|
@ -1361,12 +1362,12 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD
|
|||
else
|
||||
{
|
||||
// bottom right
|
||||
if ((mx >= 0) && fpathBlockingTile(tx+1, ty))
|
||||
if ((mx >= 0) && fpathBlockingTile(tx + 1, ty, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpy = (jumpy & ~TILE_MASK) + TILE_UNITS;
|
||||
}
|
||||
if ((my >= 0) && fpathBlockingTile(tx, ty+1))
|
||||
if ((my >= 0) && fpathBlockingTile(tx, ty + 1, propulsion))
|
||||
{
|
||||
bJumped = true;
|
||||
jumpx = (jumpx & ~TILE_MASK) + TILE_UNITS;
|
||||
|
@ -1568,11 +1569,9 @@ static void moveGetObstacleVector(DROID *psDroid, float *pX, float *pY)
|
|||
float omag, ox, oy, ratio;
|
||||
float avoidX, avoidY;
|
||||
SDWORD mapX, mapY, tx, ty, td;
|
||||
PROPULSION_STATS *psPropStats;
|
||||
PROPULSION_STATS *psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
|
||||
|
||||
psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat;
|
||||
ASSERT( psPropStats != NULL,
|
||||
"moveUpdateUnit: invalid propulsion stats pointer" );
|
||||
ASSERT(psPropStats, "invalid propulsion stats pointer");
|
||||
|
||||
droidGetNaybors(psDroid);
|
||||
|
||||
|
@ -1640,7 +1639,7 @@ static void moveGetObstacleVector(DROID *psDroid, float *pX, float *pY)
|
|||
// object behind
|
||||
continue;
|
||||
}
|
||||
if (fpathBlockingTile(mapX+xdiff, mapY+ydiff))
|
||||
if (fpathBlockingTile(mapX + xdiff, mapY + ydiff, psPropStats->propulsionType))
|
||||
{
|
||||
tx = world_coord(xdiff);
|
||||
ty = world_coord(ydiff);
|
||||
|
@ -2548,9 +2547,7 @@ static void moveUpdateVtolModel(DROID *psDroid, SDWORD speed, SDWORD direction)
|
|||
/* set slide blocking tile for map edge */
|
||||
if ( psDroid->droidType != DROID_TRANSPORTER )
|
||||
{
|
||||
fpathBlockingTile = fpathLiftSlideBlockingTile;
|
||||
moveCalcBlockingSlide( psDroid, &dx, &dy, direction, &slideDir );
|
||||
fpathBlockingTile = fpathGroundBlockingTile;
|
||||
}
|
||||
|
||||
moveUpdateDroidPos( psDroid, dx, dy );
|
||||
|
@ -3048,8 +3045,6 @@ void moveUpdateDroid(DROID *psDroid)
|
|||
/* save current motion status of droid */
|
||||
bStopped = moveDroidStopped( psDroid, 0 );
|
||||
|
||||
fpathSetBlockingTile( psPropStats->propulsionType );
|
||||
|
||||
moveSpeed = 0;
|
||||
moveDir = psDroid->direction;
|
||||
|
||||
|
@ -3121,7 +3116,6 @@ void moveUpdateDroid(DROID *psDroid)
|
|||
|
||||
turnOffMultiMsg(true);
|
||||
moveDroidTo(psDroid, psDroid->sMove.DestinationX,psDroid->sMove.DestinationY);
|
||||
fpathSetBlockingTile( psPropStats->propulsionType );
|
||||
turnOffMultiMsg(false);
|
||||
}
|
||||
else if ((psDroid->sMove.Status == MOVESHUFFLE) ||
|
||||
|
@ -3165,7 +3159,6 @@ void moveUpdateDroid(DROID *psDroid)
|
|||
break;
|
||||
case MOVEWAITROUTE:
|
||||
moveDroidTo(psDroid, psDroid->sMove.DestinationX,psDroid->sMove.DestinationY);
|
||||
fpathSetBlockingTile( psPropStats->propulsionType );
|
||||
break;
|
||||
case MOVENAVIGATE:
|
||||
// Get the next control point
|
||||
|
@ -3231,15 +3224,8 @@ void moveUpdateDroid(DROID *psDroid)
|
|||
moveCalcBoundary(psDroid);
|
||||
}
|
||||
|
||||
if (psDroid->sMove.psFormation &&
|
||||
psDroid->sMove.Position == psDroid->sMove.numPoints)
|
||||
if (psDroid->sMove.psFormation && psDroid->sMove.Position == psDroid->sMove.numPoints)
|
||||
{
|
||||
if (vtolDroid(psDroid))
|
||||
{
|
||||
// vtols have to use the ground blocking tile when they are going to land
|
||||
fpathBlockingTile = fpathGroundBlockingTile;
|
||||
}
|
||||
|
||||
if (formationGetPos(psDroid->sMove.psFormation, psDroid, &fx,&fy,true))
|
||||
{
|
||||
psDroid->sMove.targetX = fx;
|
||||
|
@ -3435,9 +3421,6 @@ void moveUpdateDroid(DROID *psDroid)
|
|||
// }
|
||||
// }
|
||||
|
||||
// reset the blocking tile function and current object
|
||||
fpathBlockingTile = fpathGroundBlockingTile;
|
||||
|
||||
/* If it's sitting in water then it's got to go with the flow! */
|
||||
if (terrainType(mapTile(psDroid->pos.x/TILE_UNITS,psDroid->pos.y/TILE_UNITS)) == TER_WATER)
|
||||
{
|
||||
|
|
70
src/order.c
70
src/order.c
|
@ -1565,7 +1565,7 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder)
|
|||
case DORDER_SCOUT:
|
||||
// can't move vtols to blocking tiles
|
||||
if (vtolDroid(psDroid)
|
||||
&& (fpathGroundBlockingTile(map_coord(psOrder->x), map_coord(psOrder->y))
|
||||
&& (fpathBlockingTile(map_coord(psOrder->x), map_coord(psOrder->y), getPropulsionStats(psDroid)->propulsionType)
|
||||
|| !TEST_TILE_VISIBLE(psDroid->player, mapTile(map_coord(psOrder->x), map_coord(psOrder->y)))))
|
||||
{
|
||||
break;
|
||||
|
@ -1574,11 +1574,8 @@ void orderDroidBase(DROID *psDroid, DROID_ORDER_DATA *psOrder)
|
|||
if (game.maxPlayers > 0)
|
||||
{
|
||||
if (psDroid->droidType == DROID_TRANSPORTER
|
||||
&& (fpathGroundBlockingTile(map_coord(psOrder->x),
|
||||
map_coord(psOrder->y))
|
||||
|| !TEST_TILE_VISIBLE(psDroid->player,
|
||||
mapTile(map_coord(psOrder->x),
|
||||
map_coord(psOrder->y)))))
|
||||
&& (fpathBlockingTile(map_coord(psOrder->x), map_coord(psOrder->y), getPropulsionStats(psDroid)->propulsionType)
|
||||
|| !TEST_TILE_VISIBLE(psDroid->player, mapTile(map_coord(psOrder->x), map_coord(psOrder->y)))))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -2674,11 +2671,20 @@ static BOOL orderDroidObjAdd(DROID *psDroid, DROID_ORDER order, BASE_OBJECT *psO
|
|||
/* Choose an order for a droid from a location */
|
||||
DROID_ORDER chooseOrderLoc(DROID *psDroid, UDWORD x,UDWORD y)
|
||||
{
|
||||
DROID_ORDER order;
|
||||
SECONDARY_STATE state;
|
||||
DROID_ORDER order = DORDER_NONE;
|
||||
SECONDARY_STATE state;
|
||||
PROPULSION_TYPE propulsion = getPropulsionStats(psDroid)->propulsionType;
|
||||
|
||||
// default to move
|
||||
order = DORDER_MOVE;
|
||||
// default to move; however, we can only end up on a tile
|
||||
// where can stay, ie VTOLs must be able to land as well
|
||||
if (vtolDroid(psDroid))
|
||||
{
|
||||
propulsion = WHEELED;
|
||||
}
|
||||
if (!fpathBlockingTile(map_coord(x), map_coord(y), propulsion))
|
||||
{
|
||||
order = DORDER_MOVE;
|
||||
}
|
||||
|
||||
// scout if shift was pressed
|
||||
if(keyDown(KEY_LSHIFT) || keyDown(KEY_RSHIFT))
|
||||
|
@ -2686,28 +2692,15 @@ DROID_ORDER chooseOrderLoc(DROID *psDroid, UDWORD x,UDWORD y)
|
|||
order = DORDER_SCOUT;
|
||||
}
|
||||
|
||||
/*if(psDroid->droidType == DROID_TRANSPORTER)
|
||||
// and now we want Transporters to fly! - in multiPlayer!!
|
||||
if (psDroid->droidType == DROID_TRANSPORTER && game.maxPlayers != 0)
|
||||
{
|
||||
order = DORDER_NONE;
|
||||
}*/
|
||||
//VTOL Droids won't move to a location - only to a target object -
|
||||
//this cope with Transporters as well - not any more! AB 16/11/98
|
||||
// if (vtolDroid(psDroid) || psDroid->droidType == DROID_TRANSPORTER)
|
||||
|
||||
//and now we want Transporters to fly! - in multiPlayer!!
|
||||
if (psDroid->droidType == DROID_TRANSPORTER)
|
||||
{
|
||||
//if (!bMultiPlayer)
|
||||
if (game.maxPlayers == 0)
|
||||
{
|
||||
order = DORDER_NONE;
|
||||
}
|
||||
/*in MultiPlayer - if ALT-key is pressed then need to get the Transporter
|
||||
to fly to location and all units disembark*/
|
||||
else if (keyDown(KEY_LALT) || keyDown(KEY_RALT))
|
||||
{
|
||||
order = DORDER_DISEMBARK;
|
||||
}
|
||||
/* in MultiPlayer - if ALT-key is pressed then need to get the Transporter
|
||||
* to fly to location and all units disembark */
|
||||
if (keyDown(KEY_LALT) || keyDown(KEY_RALT))
|
||||
{
|
||||
order = DORDER_DISEMBARK;
|
||||
}
|
||||
}
|
||||
else if (secondaryGetState(psDroid, DSO_CIRCLE, &state) &&
|
||||
state == DSS_CIRCLE_SET)
|
||||
|
@ -2733,11 +2726,8 @@ DROID_ORDER chooseOrderLoc(DROID *psDroid, UDWORD x,UDWORD y)
|
|||
*/
|
||||
void orderSelectedLocAdd(UDWORD player, UDWORD x, UDWORD y, BOOL add)
|
||||
{
|
||||
DROID *psCurr;//, *psPrev;
|
||||
DROID *psCurr;
|
||||
DROID_ORDER order;
|
||||
// FORMATION *psFormation = NULL;
|
||||
|
||||
// DBPRINTF(("orderSelectedLoc: player %d -> (%d,%d)\n", player, x,y));
|
||||
|
||||
//if were in build select mode ignore all other clicking
|
||||
if (intBuildSelectMode())
|
||||
|
@ -2745,13 +2735,11 @@ void orderSelectedLocAdd(UDWORD player, UDWORD x, UDWORD y, BOOL add)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!add && bMultiPlayer && SendGroupOrderSelected((UBYTE)player,x,y,NULL) )
|
||||
{ // turn off multiplay messages,since we've send a group one instead.
|
||||
turnOffMultiMsg(true);
|
||||
}
|
||||
|
||||
|
||||
// remove any units from their command group
|
||||
for(psCurr = apsDroidLists[player]; psCurr; psCurr=psCurr->psNext)
|
||||
{
|
||||
|
@ -2764,14 +2752,13 @@ void orderSelectedLocAdd(UDWORD player, UDWORD x, UDWORD y, BOOL add)
|
|||
// note that an order list graphic needs to be displayed
|
||||
bOrderEffectDisplayed = false;
|
||||
|
||||
// psPrev = NULL;
|
||||
for(psCurr = apsDroidLists[player]; psCurr; psCurr=psCurr->psNext)
|
||||
{
|
||||
if (psCurr->selected)
|
||||
{
|
||||
order = chooseOrderLoc(psCurr, x,y);
|
||||
order = chooseOrderLoc(psCurr, x, y);
|
||||
// see if the order can be added to the list
|
||||
if (!(add && orderDroidLocAdd(psCurr, order, x,y)))
|
||||
if (order != DORDER_NONE && !(add && orderDroidLocAdd(psCurr, order, x, y)))
|
||||
{
|
||||
// if not just do it straight off
|
||||
orderDroidLoc(psCurr, order, x,y);
|
||||
|
@ -2779,9 +2766,6 @@ void orderSelectedLocAdd(UDWORD player, UDWORD x, UDWORD y, BOOL add)
|
|||
}
|
||||
}
|
||||
|
||||
//might be a Delivery Point of a factory
|
||||
//processDeliveryPoint(player,x,y);
|
||||
|
||||
turnOffMultiMsg(false); // msgs back on...
|
||||
}
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ BOOL rayInitialise(void)
|
|||
* Sorry about the wacky angle set up but that was what I thought
|
||||
* warzone used, but turned out not to be after I wrote it.
|
||||
*/
|
||||
void rayCast(UDWORD x, UDWORD y, UDWORD ray, UDWORD length, RAY_CALLBACK callback)
|
||||
void rayCast(UDWORD x, UDWORD y, UDWORD ray, UDWORD length, PROPULSION_TYPE propulsion, RAY_CALLBACK callback)
|
||||
{
|
||||
SDWORD hdInc=0, vdInc=0; // increases in x and y distance per intersection
|
||||
SDWORD hDist, vDist; // distance to current horizontal and vertical intersectionse
|
||||
|
@ -238,7 +238,7 @@ void rayCast(UDWORD x, UDWORD y, UDWORD ray, UDWORD length, RAY_CALLBACK callbac
|
|||
}
|
||||
|
||||
// pass through the current intersection, converting x from fixed point
|
||||
if (!callback( sHoriz.x >> RAY_ACC,sHoriz.y, hDist))
|
||||
if (!callback( sHoriz.x >> RAY_ACC,sHoriz.y, hDist, propulsion))
|
||||
{
|
||||
// callback doesn't want any more points so return
|
||||
return;
|
||||
|
@ -259,7 +259,7 @@ void rayCast(UDWORD x, UDWORD y, UDWORD ray, UDWORD length, RAY_CALLBACK callbac
|
|||
}
|
||||
|
||||
// pass through the current intersection, converting y from fixed point
|
||||
if (!callback( sVert.x,sVert.y >> RAY_ACC, vDist))
|
||||
if (!callback( sVert.x,sVert.y >> RAY_ACC, vDist, propulsion))
|
||||
{
|
||||
// callback doesn't want any more points so return
|
||||
return;
|
||||
|
@ -344,7 +344,7 @@ SDWORD rayPointDist(SDWORD x1,SDWORD y1, SDWORD x2,SDWORD y2,
|
|||
from wherever you specify, as well as the distance away
|
||||
*/
|
||||
//-----------------------------------------------------------------------------------
|
||||
static BOOL getTileHighestCallback(SDWORD x, SDWORD y, SDWORD dist)
|
||||
static BOOL getTileHighestCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
if(clipXY(x,y))
|
||||
{
|
||||
|
@ -364,9 +364,10 @@ static BOOL getTileHighestCallback(SDWORD x, SDWORD y, SDWORD dist)
|
|||
return(true);
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
/* Will return false when we've hit the edge of the grid */
|
||||
static BOOL getTileHeightCallback(SDWORD x, SDWORD y, SDWORD dist)
|
||||
static BOOL getTileHeightCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
#ifdef TEST_RAY
|
||||
Vector3i pos;
|
||||
|
@ -444,10 +445,7 @@ void getBestPitchToEdgeOfGrid(UDWORD x, UDWORD y, UDWORD direction, SDWORD *pitc
|
|||
gHeight = map_Height(x,y);
|
||||
gStartTileX = map_coord(x);
|
||||
gStartTileY = map_coord(y);
|
||||
//#ifdef TEST_RAY
|
||||
//DBPRINTF(("%d\n",direction);
|
||||
//#endif
|
||||
rayCast(x,y, direction%360,5430,getTileHeightCallback);
|
||||
rayCast(x, y, direction % 360, 5430, INVALID_PROP_TYPE, getTileHeightCallback);
|
||||
*pitch = gPitch;
|
||||
}
|
||||
|
||||
|
@ -458,6 +456,6 @@ void getPitchToHighestPoint( UDWORD x, UDWORD y, UDWORD direction,
|
|||
gHOrigHeight = map_Height(x,y);
|
||||
gHighestHeight = map_Height(x,y);
|
||||
gHMinDist = thresholdDistance;
|
||||
rayCast(x,y,direction%360,3000,getTileHighestCallback);
|
||||
rayCast(x, y, direction % 360, 3000, INVALID_PROP_TYPE, getTileHighestCallback);
|
||||
*pitch = gHPitch;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#ifndef __INCLUDED_SRC_RAYCAST_H__
|
||||
#define __INCLUDED_SRC_RAYCAST_H__
|
||||
|
||||
#include "statsdef.h"
|
||||
|
||||
#define NUM_RAYS 360
|
||||
|
||||
#define RAY_ANGLE ((float)(2 * M_PI / NUM_RAYS))
|
||||
|
@ -33,17 +35,17 @@
|
|||
// maximum length for a visiblity ray
|
||||
#define RAY_MAXLEN 0x7ffff
|
||||
|
||||
|
||||
/* Initialise the visibility rays */
|
||||
extern BOOL rayInitialise(void);
|
||||
|
||||
/* The raycast intersection callback.
|
||||
* Return false if no more points are required, true otherwise
|
||||
*/
|
||||
typedef BOOL (*RAY_CALLBACK)(SDWORD x, SDWORD y, SDWORD dist);
|
||||
typedef BOOL (*RAY_CALLBACK)(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion);
|
||||
|
||||
/* cast a ray from x,y (world coords) at angle ray (0-NUM_RAYS) */
|
||||
extern void rayCast(UDWORD x, UDWORD y, UDWORD ray, UDWORD length,
|
||||
RAY_CALLBACK callback);
|
||||
extern void rayCast(UDWORD x, UDWORD y, UDWORD ray, UDWORD length, PROPULSION_TYPE propulsion, RAY_CALLBACK callback);
|
||||
|
||||
// Calculate the angle to cast a ray between two points
|
||||
extern UDWORD rayPointsToAngle(SDWORD x1,SDWORD y1, SDWORD x2,SDWORD y2);
|
||||
|
|
|
@ -5576,38 +5576,42 @@ static BOOL structDoubleCheck(BASE_STATS *psStat,UDWORD xx,UDWORD yy, SDWORD max
|
|||
y = yTL; // top
|
||||
for(x = xTL;x!=xBR+1;x++)
|
||||
{
|
||||
if(fpathGroundBlockingTile(x,y))
|
||||
if (fpathBlockingTile(x, y, WHEELED))
|
||||
{
|
||||
count++;
|
||||
break;
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
y = yBR; // bottom
|
||||
for(x = xTL;x!=xBR+1;x++)
|
||||
{
|
||||
if(fpathGroundBlockingTile(x,y))
|
||||
if (fpathBlockingTile(x, y, WHEELED))
|
||||
{
|
||||
count++;
|
||||
break;
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
x = xTL; // left
|
||||
for(y = yTL+1; y!=yBR; y++)
|
||||
{
|
||||
if(fpathGroundBlockingTile(x,y))
|
||||
if (fpathBlockingTile(x, y, WHEELED))
|
||||
{
|
||||
count++;
|
||||
break;
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
x = xBR; // right
|
||||
for(y = yTL+1; y!=yBR; y++)
|
||||
{
|
||||
if(fpathGroundBlockingTile(x,y))
|
||||
if (fpathBlockingTile(x, y, WHEELED))
|
||||
{
|
||||
count++;
|
||||
break;
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
//make sure this location is not blocked from too many sides
|
||||
if((count <= maxBlockingTiles) || (maxBlockingTiles == -1))
|
||||
|
|
|
@ -2370,7 +2370,7 @@ static BOOL structClearTile(UWORD x, UWORD y)
|
|||
DROID *psCurr;
|
||||
|
||||
/* Check for a structure */
|
||||
if(fpathBlockingTile(x,y))
|
||||
if (fpathBlockingTile(x, y, WHEELED))
|
||||
{
|
||||
debug(LOG_NEVER, "failed - blocked");
|
||||
return false;
|
||||
|
@ -4474,7 +4474,7 @@ BOOL validLocation(BASE_STATS *psStats, UDWORD x, UDWORD y, UDWORD player,
|
|||
{
|
||||
// not positioning a structure
|
||||
valid = true;
|
||||
if (fpathGroundBlockingTile(x,y))
|
||||
if (fpathBlockingTile(x, y, WHEELED))
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
|
|
|
@ -76,9 +76,6 @@ static SDWORD finalX,finalY; // The final tile of the ray cast
|
|||
static SDWORD numWalls; // Whether the LOS has hit a wall
|
||||
static SDWORD wallX,wallY; // the position of a wall if it is on the LOS
|
||||
|
||||
BOOL rayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist);
|
||||
BOOL scrRayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist);
|
||||
|
||||
// holds information about map tiles visible by droids
|
||||
static bool scrTileVisible[MAX_PLAYERS][UBYTE_MAX][UBYTE_MAX] = {{{false}}};
|
||||
|
||||
|
@ -133,7 +130,7 @@ static SDWORD visObjHeight(const BASE_OBJECT * const psObject)
|
|||
}
|
||||
|
||||
/* The terrain revealing ray callback */
|
||||
BOOL rayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist)
|
||||
BOOL rayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
SDWORD newH, newG; // The new gradient
|
||||
MAPTILE *psTile;
|
||||
|
@ -186,7 +183,7 @@ BOOL rayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist)
|
|||
}
|
||||
|
||||
/* The los ray callback */
|
||||
static BOOL rayLOSCallback(SDWORD x, SDWORD y, SDWORD dist)
|
||||
static BOOL rayLOSCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
SDWORD newG; // The new gradient
|
||||
SDWORD distSq;
|
||||
|
@ -282,7 +279,7 @@ void visTilesUpdate(BASE_OBJECT *psObj, RAY_CALLBACK callback)
|
|||
currG = -UBYTE_MAX * GRAD_MUL;
|
||||
|
||||
// Cast the rays from the viewer
|
||||
rayCast(psObj->pos.x, psObj->pos.y,ray, range, callback);
|
||||
rayCast(psObj->pos.x, psObj->pos.y,ray, range, INVALID_PROP_TYPE, callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +415,7 @@ BOOL visibleObject(const BASE_OBJECT* psViewer, const BASE_OBJECT* psTarget)
|
|||
finalY = map_coord(psTarget->pos.y);
|
||||
|
||||
// Cast a ray from the viewer to the target
|
||||
rayCast(x,y, ray, range, rayLOSCallback);
|
||||
rayCast(x,y, ray, range, INVALID_PROP_TYPE, rayLOSCallback);
|
||||
|
||||
// See if the target can be seen
|
||||
top = ((SDWORD)psTarget->pos.z + visObjHeight(psTarget) - startH);
|
||||
|
@ -749,7 +746,7 @@ void updateSensorDisplay()
|
|||
}
|
||||
}
|
||||
|
||||
BOOL scrRayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist)
|
||||
BOOL scrRayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion)
|
||||
{
|
||||
SDWORD newH, newG; // The new gradient
|
||||
MAPTILE *psTile;
|
||||
|
|
|
@ -30,10 +30,10 @@ extern BOOL visInitialise(void);
|
|||
extern BOOL visTilesPending(BASE_OBJECT *psObj);
|
||||
|
||||
/* The terrain revealing ray callback */
|
||||
extern BOOL rayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist);
|
||||
extern BOOL rayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion);
|
||||
|
||||
/* Ray callback for scripts */
|
||||
extern BOOL scrRayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist);
|
||||
extern BOOL scrRayTerrainCallback(SDWORD x, SDWORD y, SDWORD dist, PROPULSION_TYPE propulsion);
|
||||
|
||||
/* Check which tiles can be seen by an object */
|
||||
extern void visTilesUpdate(BASE_OBJECT *psObj, RAY_CALLBACK callback);
|
||||
|
|
Loading…
Reference in New Issue