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-861f7616d084master
parent
6bfd2ce794
commit
be907e3994
|
@ -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
|
||||
|
|
21
src/map.c
21
src/map.c
|
@ -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) &&
|
||||
|
|
20
src/map.h
20
src/map.h
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue