Skip to content

Commit

Permalink
Fix hover tanks thinking they are submarines, going under the water, …
Browse files Browse the repository at this point in the history
…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

Backport of be907e3, fixes #2232.
  • Loading branch information
Cyp authored and cybersphinx committed Oct 18, 2010
1 parent e28711f commit a430a29
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/droid.c
Original file line number Diff line number Diff line change
Expand Up @@ -4446,8 +4446,8 @@ BOOL isVtolDroid(const DROID* psDroid)
&& psDroid->droidType != DROID_TRANSPORTER;
}

/* returns true if the droid has lift propulsion and is moving */
BOOL isFlying(const DROID* psDroid)
// 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
&& ( psDroid->sMove.Status != MOVEINACTIVE || psDroid->droidType == DROID_TRANSPORTER );
Expand Down
17 changes: 9 additions & 8 deletions src/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -865,13 +865,12 @@ BOOL mapLoad(char *filename)
{
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;
}
}
}
Expand Down Expand Up @@ -1964,7 +1963,7 @@ BOOL map_Intersect(int* Cx, int* Cy, int* Vx, int* Vy, int* Sx, int* Sy)
return false;
}

/// 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;
Expand Down Expand Up @@ -1999,7 +1998,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];
}
}
Expand Down Expand Up @@ -2062,22 +2061,24 @@ 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);
}

/* returns true if object is above ground */
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 * ELEVATION_SCALE,
h2 = psMapTiles[MIN(mapWidth * mapHeight, tileYOffset1 + tileX + 1)].height * ELEVATION_SCALE,
h3 = psMapTiles[MIN(mapWidth * mapHeight, tileYOffset2 + tileX) ].height * ELEVATION_SCALE,
h4 = psMapTiles[MIN(mapWidth * mapHeight, tileYOffset2 + tileX + 1)].height * ELEVATION_SCALE;
h1 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset1 + tileX) ].height * ELEVATION_SCALE,
h2 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset1 + tileX + 1)].height * ELEVATION_SCALE,
h3 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset2 + tileX) ].height * ELEVATION_SCALE,
h4 = psMapTiles[MIN(mapWidth * mapHeight - 1, tileYOffset2 + tileX + 1)].height * ELEVATION_SCALE;

/* trivial test above */
if ( (psObj->pos.z > h1) && (psObj->pos.z > h2) &&
Expand Down
20 changes: 15 additions & 5 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,24 +318,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(UDWORD x, UDWORD 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(UDWORD x, UDWORD 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;
}


Expand Down Expand Up @@ -401,7 +411,7 @@ typedef struct _tile_coord
/* Intersect a line with the map and report tile intersection points */
extern BOOL map_Intersect(int *Cx, int *Cy, int *Vx, int* Vy, int *Sx, int *Sy);

/* 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 */
Expand Down

0 comments on commit a430a29

Please sign in to comment.