Fix hover tanks thinking they are submarines, going under the water, and the height wrapping around.

Hover tanks float above the water, which can only be fixed when droid heights are stored in something slightly less unsigned.
Closes ticket:1554 which was a combination of bugs or design flaws exposed in -r9619.

git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@9741 4a71c877-e1ca-e34f-864e-861f7616d084
master
Cyp 2010-02-08 12:44:25 +00:00 committed by Git SVN Gateway
parent 6bfd2ce794
commit be907e3994
3 changed files with 27 additions and 16 deletions

View File

@ -3750,7 +3750,7 @@ BOOL isVtolDroid(const DROID* psDroid)
&& psDroid->droidType != DROID_TRANSPORTER;
}
/*returns true if the droid has lift propulsion and is above the ground level*/
// returns true if the droid has lift propulsion and is moving
BOOL isFlying(const DROID* psDroid)
{
return (asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat)->propulsionType == PROPULSION_TYPE_LIFT

View File

@ -974,23 +974,22 @@ BOOL mapLoad(char *filename)
// reset the random water bottom heights
environReset();
// set the river bed
for (i=0;i<mapWidth;i++)
{
for (j=0;j<mapHeight;j++)
{
setTileHeight(i, j, map_TileHeight(i, j));
// FIXME: magic number
mapTile(i, j)->waterLevel = mapTile(i, j)->height - world_coord(1) / 3.0f / (float)ELEVATION_SCALE;
// lower riverbed
if (mapTile(i, j)->ground == waterGroundType)
{
mapTile(i, j)->height = mapTile(i, j)->height - (WATER_DEPTH - 2.0f * environGetData(i, j)) / (float)ELEVATION_SCALE;
mapTile(i, j)->height -= (WATER_DEPTH - 2.0f * environGetData(i, j)) / (float)ELEVATION_SCALE;
}
}
}
/* set up the scroll mins and maxs - set values to valid ones for any new map */
scrollMinX = scrollMinY = 0;
scrollMaxX = mapWidth;
@ -1858,7 +1857,7 @@ BOOL mapShutdown(void)
return true;
}
/// The height of the terrain at the specified world coordinates
/// The max height of the terrain and water at the specified world coordinates
extern SWORD map_Height(int x, int y)
{
int tileX, tileY;
@ -1894,7 +1893,7 @@ extern SWORD map_Height(int x, int y)
{
for (j = 0; j < 2; j++)
{
height[i][j] = map_TileHeight(tileX+i, tileY+j);
height[i][j] = map_TileHeightSurface(tileX+i, tileY+j);
center += height[i][j];
}
}
@ -1957,6 +1956,7 @@ extern SWORD map_Height(int x, int y)
onBottom = left * (1 - towardsRight) + right * towardsRight;
result = onBottom + (center - middle) * towardsCenter * 2;
result = MAX(result, 0); // HACK Avoid unsigned underflow, when this is squashed into a Vector3uw later.
return (SDWORD)(result+0.5f);
}
@ -1964,15 +1964,16 @@ extern SWORD map_Height(int x, int y)
extern BOOL mapObjIsAboveGround( BASE_OBJECT *psObj )
{
// min is used to make sure we don't go over array bounds!
// TODO Using the corner of the map instead doesn't make sense. Fix this...
SDWORD iZ,
tileX = map_coord(psObj->pos.x),
tileY = map_coord(psObj->pos.y),
tileYOffset1 = (tileY * mapWidth),
tileYOffset2 = ((tileY+1) * mapWidth),
h1 = psMapTiles[MIN(mapWidth * mapHeight, tileYOffset1 + tileX) ].height,
h2 = psMapTiles[MIN(mapWidth * mapHeight, tileYOffset1 + tileX + 1)].height,
h3 = psMapTiles[MIN(mapWidth * mapHeight, tileYOffset2 + tileX) ].height,
h4 = psMapTiles[MIN(mapWidth * mapHeight, tileYOffset2 + tileX + 1)].height;
h1 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset1 + tileX) ].height,
h2 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset1 + tileX + 1)].height,
h3 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset2 + tileX) ].height,
h4 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset2 + tileX + 1)].height;
/* trivial test above */
if ( (psObj->pos.z > h1) && (psObj->pos.z > h2) &&

View File

@ -321,24 +321,34 @@ static inline WZ_DECL_PURE MAPTILE *mapTile(SDWORD x, SDWORD y)
return &psMapTiles[x + (y * mapWidth)];
}
/* Return height of tile at x,y */
/// Return ground height of top-left corner of tile at x,y
static inline WZ_DECL_PURE float map_TileHeight(SDWORD x, SDWORD y)
{
if ( x >= mapWidth || y >= mapHeight )
{
return 0;
}
return ((float)psMapTiles[x + (y * mapWidth)].height * ELEVATION_SCALE);
return psMapTiles[x + (y * mapWidth)].height * ELEVATION_SCALE;
}
/* Return height of tile at x,y */
/// Return water height of top-left corner of tile at x,y
static inline WZ_DECL_PURE float map_WaterHeight(SDWORD x, SDWORD y)
{
if ( x >= mapWidth || y >= mapHeight )
{
return 0;
}
return ((float)psMapTiles[x + (y * mapWidth)].waterLevel * ELEVATION_SCALE);
return psMapTiles[x + (y * mapWidth)].waterLevel * ELEVATION_SCALE;
}
/// Return max(ground, water) height of top-left corner of tile at x,y
static inline WZ_DECL_PURE float map_TileHeightSurface(SDWORD x, SDWORD y)
{
if ( x >= mapWidth || y >= mapHeight )
{
return 0;
}
return MAX(psMapTiles[x + (y * mapWidth)].height, psMapTiles[x + (y * mapWidth)].waterLevel) * ELEVATION_SCALE;
}
@ -401,7 +411,7 @@ typedef struct _tile_coord
MAPTILE *psTile;
} TILE_COORD;
/* Return height of x,y */
/// The max height of the terrain and water at the specified world coordinates
extern SWORD map_Height(int x, int y);
/* returns true if object is above ground */