mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-12 10:30:28 +00:00
Codechange: Unify tile height model in all functions (Patch by adf88, #6583)
This commit is contained in:
parent
05da5a177c
commit
c33596fe4a
@ -131,9 +131,15 @@ Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped)
|
|||||||
* (FOUNDATION_HALFTILE_LOWER on SLOPE_STEEP_S hides north halftile completely)
|
* (FOUNDATION_HALFTILE_LOWER on SLOPE_STEEP_S hides north halftile completely)
|
||||||
* So give it a z-malus of 4 in the first iterations. */
|
* So give it a z-malus of 4 in the first iterations. */
|
||||||
int z = 0;
|
int z = 0;
|
||||||
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + max(z, 4) - 4, min_coord, max_x), Clamp(pt.y + max(z, 4) - 4, min_coord, max_y)) / 2;
|
if (clamp_to_map) {
|
||||||
for (int m = 3; m > 0; m--) z = GetSlopePixelZ(Clamp(pt.x + max(z, m) - m, min_coord, max_x), Clamp(pt.y + max(z, m) - m, min_coord, max_y)) / 2;
|
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + max(z, 4) - 4, min_coord, max_x), Clamp(pt.y + max(z, 4) - 4, min_coord, max_y)) / 2;
|
||||||
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + z, min_coord, max_x), Clamp(pt.y + z, min_coord, max_y)) / 2;
|
for (int m = 3; m > 0; m--) z = GetSlopePixelZ(Clamp(pt.x + max(z, m) - m, min_coord, max_x), Clamp(pt.y + max(z, m) - m, min_coord, max_y)) / 2;
|
||||||
|
for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + z, min_coord, max_x), Clamp(pt.y + z, min_coord, max_y)) / 2;
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 5; i++) z = GetSlopePixelZOutsideMap(pt.x + max(z, 4) - 4, pt.y + max(z, 4) - 4) / 2;
|
||||||
|
for (int m = 3; m > 0; m--) z = GetSlopePixelZOutsideMap(pt.x + max(z, m) - m, pt.y + max(z, m) - m) / 2;
|
||||||
|
for (int i = 0; i < 5; i++) z = GetSlopePixelZOutsideMap(pt.x + z, pt.y + z ) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
pt.x += z;
|
pt.x += z;
|
||||||
pt.y += z;
|
pt.y += z;
|
||||||
@ -342,6 +348,23 @@ int GetSlopePixelZ(int x, int y)
|
|||||||
return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
|
return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return world \c z coordinate of a given point of a tile,
|
||||||
|
* also for tiles outside the map (virtual "black" tiles).
|
||||||
|
*
|
||||||
|
* @param x World X coordinate in tile "units", may be ouside the map.
|
||||||
|
* @param y World Y coordinate in tile "units", may be ouside the map.
|
||||||
|
* @return World Z coordinate at tile ground level, including slopes and foundations.
|
||||||
|
*/
|
||||||
|
int GetSlopePixelZOutsideMap(int x, int y)
|
||||||
|
{
|
||||||
|
if (IsInsideBS(x, 0, MapSizeX() * TILE_SIZE) && IsInsideBS(y, 0, MapSizeY() * TILE_SIZE)) {
|
||||||
|
return GetSlopePixelZ(x, y);
|
||||||
|
} else {
|
||||||
|
return _tile_type_procs[MP_VOID]->get_slope_z_proc(INVALID_TILE, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the Z height of a corner relative to TileZ.
|
* Determine the Z height of a corner relative to TileZ.
|
||||||
*
|
*
|
||||||
|
@ -40,6 +40,7 @@ Slope GetFoundationSlope(TileIndex tile, int *z = NULL);
|
|||||||
|
|
||||||
uint GetPartialPixelZ(int x, int y, Slope corners);
|
uint GetPartialPixelZ(int x, int y, Slope corners);
|
||||||
int GetSlopePixelZ(int x, int y);
|
int GetSlopePixelZ(int x, int y);
|
||||||
|
int GetSlopePixelZOutsideMap(int x, int y);
|
||||||
void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2);
|
void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
126
src/tile_map.cpp
126
src/tile_map.cpp
@ -14,60 +14,6 @@
|
|||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the tile height for a coordinate outside map. Such a height is
|
|
||||||
* needed for painting the area outside map using completely black tiles.
|
|
||||||
* The idea is descending to heightlevel 0 as fast as possible.
|
|
||||||
* @param x The X-coordinate (same unit as TileX).
|
|
||||||
* @param y The Y-coordinate (same unit as TileY).
|
|
||||||
* @return The height in the same unit as TileHeight.
|
|
||||||
*/
|
|
||||||
uint TileHeightOutsideMap(int x, int y)
|
|
||||||
{
|
|
||||||
/* In all cases: Descend to heightlevel 0 as fast as possible.
|
|
||||||
* So: If we are at the 0-side of the map (x<0 or y<0), we must
|
|
||||||
* subtract the distance to coordinate 0 from the heightlevel at
|
|
||||||
* coordinate 0.
|
|
||||||
* In other words: Subtract e.g. -x. If we are at the MapMax
|
|
||||||
* side of the map, we also need to subtract the distance to
|
|
||||||
* the edge of map, e.g. MapMaxX - x.
|
|
||||||
*
|
|
||||||
* NOTE: Assuming constant heightlevel outside map would be
|
|
||||||
* simpler here. However, then we run into painting problems,
|
|
||||||
* since whenever a heightlevel change at the map border occurs,
|
|
||||||
* we would need to repaint anything outside map.
|
|
||||||
* In contrast, by doing it this way, we can localize this change,
|
|
||||||
* which means we may assume constant heightlevel for all tiles
|
|
||||||
* at more than <heightlevel at map border> distance from the
|
|
||||||
* map border.
|
|
||||||
*/
|
|
||||||
if (x < 0) {
|
|
||||||
if (y < 0) {
|
|
||||||
return max((int)TileHeight(TileXY(0, 0)) - (-x) - (-y), 0);
|
|
||||||
} else if (y < (int)MapMaxY()) {
|
|
||||||
return max((int)TileHeight(TileXY(0, y)) - (-x), 0);
|
|
||||||
} else {
|
|
||||||
return max((int)TileHeight(TileXY(0, (int)MapMaxY())) - (-x) - (y - (int)MapMaxY()), 0);
|
|
||||||
}
|
|
||||||
} else if (x < (int)MapMaxX()) {
|
|
||||||
if (y < 0) {
|
|
||||||
return max((int)TileHeight(TileXY(x, 0)) - (-y), 0);
|
|
||||||
} else if (y < (int)MapMaxY()) {
|
|
||||||
return TileHeight(TileXY(x, y));
|
|
||||||
} else {
|
|
||||||
return max((int)TileHeight(TileXY(x, (int)MapMaxY())) - (y - (int)MapMaxY()), 0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (y < 0) {
|
|
||||||
return max((int)TileHeight(TileXY((int)MapMaxX(), 0)) - (x - (int)MapMaxX()) - (-y), 0);
|
|
||||||
} else if (y < (int)MapMaxY()) {
|
|
||||||
return max((int)TileHeight(TileXY((int)MapMaxX(), y)) - (x - (int)MapMaxX()), 0);
|
|
||||||
} else {
|
|
||||||
return max((int)TileHeight(TileXY((int)MapMaxX(), (int)MapMaxY())) - (x - (int)MapMaxX()) - (y - (int)MapMaxY()), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a tile's slope given the heigh of its four corners.
|
* Get a tile's slope given the heigh of its four corners.
|
||||||
* @param hnorth The height at the northern corner in the same unit as TileHeight.
|
* @param hnorth The height at the northern corner in the same unit as TileHeight.
|
||||||
@ -114,30 +60,26 @@ static Slope GetTileSlopeGivenHeight(int hnorth, int hwest, int heast, int hsout
|
|||||||
*/
|
*/
|
||||||
Slope GetTileSlope(TileIndex tile, int *h)
|
Slope GetTileSlope(TileIndex tile, int *h)
|
||||||
{
|
{
|
||||||
assert(tile < MapSize());
|
uint x1 = TileX(tile);
|
||||||
|
uint y1 = TileY(tile);
|
||||||
|
uint x2 = min(x1 + 1, MapMaxX());
|
||||||
|
uint y2 = min(y1 + 1, MapMaxY());
|
||||||
|
|
||||||
uint x = TileX(tile);
|
int hnorth = TileHeight(tile); // Height of the North corner.
|
||||||
uint y = TileY(tile);
|
int hwest = TileHeight(TileXY(x2, y1)); // Height of the West corner.
|
||||||
if (x == MapMaxX() || y == MapMaxY()) {
|
int heast = TileHeight(TileXY(x1, y2)); // Height of the East corner.
|
||||||
if (h != NULL) *h = TileHeight(tile);
|
int hsouth = TileHeight(TileXY(x2, y2)); // Height of the South corner.
|
||||||
return SLOPE_FLAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
int hnorth = TileHeight(tile); // Height of the North corner.
|
|
||||||
int hwest = TileHeight(tile + TileDiffXY(1, 0)); // Height of the West corner.
|
|
||||||
int heast = TileHeight(tile + TileDiffXY(0, 1)); // Height of the East corner.
|
|
||||||
int hsouth = TileHeight(tile + TileDiffXY(1, 1)); // Height of the South corner.
|
|
||||||
|
|
||||||
return GetTileSlopeGivenHeight(hnorth, hwest, heast, hsouth, h);
|
return GetTileSlopeGivenHeight(hnorth, hwest, heast, hsouth, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the slope of a given tile outside the map.
|
* Return the slope of a given tile, also for tiles outside the map (virtual "black" tiles).
|
||||||
*
|
*
|
||||||
* @param x X-coordinate of the tile outside to compute height of.
|
* @param x X coordinate of the tile to compute slope of, may be ouside the map.
|
||||||
* @param y Y-coordinate of the tile outside to compute height of.
|
* @param y Y coordinate of the tile to compute slope of, may be ouside the map.
|
||||||
* @param h If not \c NULL, pointer to storage of z height.
|
* @param h If not \c NULL, pointer to storage of z height.
|
||||||
* @return Slope of the tile outside map, except for the HALFTILE part.
|
* @return Slope of the tile, except for the HALFTILE part.
|
||||||
*/
|
*/
|
||||||
Slope GetTilePixelSlopeOutsideMap(int x, int y, int *h)
|
Slope GetTilePixelSlopeOutsideMap(int x, int y, int *h)
|
||||||
{
|
{
|
||||||
@ -159,17 +101,15 @@ Slope GetTilePixelSlopeOutsideMap(int x, int y, int *h)
|
|||||||
*/
|
*/
|
||||||
bool IsTileFlat(TileIndex tile, int *h)
|
bool IsTileFlat(TileIndex tile, int *h)
|
||||||
{
|
{
|
||||||
assert(tile < MapSize());
|
uint x1 = TileX(tile);
|
||||||
|
uint y1 = TileY(tile);
|
||||||
if (!IsInnerTile(tile)) {
|
uint x2 = min(x1 + 1, MapMaxX());
|
||||||
if (h != NULL) *h = TileHeight(tile);
|
uint y2 = min(y1 + 1, MapMaxY());
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint z = TileHeight(tile);
|
uint z = TileHeight(tile);
|
||||||
if (TileHeight(tile + TileDiffXY(1, 0)) != z) return false;
|
if (TileHeight(TileXY(x2, y1)) != z) return false;
|
||||||
if (TileHeight(tile + TileDiffXY(0, 1)) != z) return false;
|
if (TileHeight(TileXY(x1, y2)) != z) return false;
|
||||||
if (TileHeight(tile + TileDiffXY(1, 1)) != z) return false;
|
if (TileHeight(TileXY(x2, y2)) != z) return false;
|
||||||
|
|
||||||
if (h != NULL) *h = z;
|
if (h != NULL) *h = z;
|
||||||
return true;
|
return true;
|
||||||
@ -182,12 +122,15 @@ bool IsTileFlat(TileIndex tile, int *h)
|
|||||||
*/
|
*/
|
||||||
int GetTileZ(TileIndex tile)
|
int GetTileZ(TileIndex tile)
|
||||||
{
|
{
|
||||||
if (TileX(tile) == MapMaxX() || TileY(tile) == MapMaxY()) return 0;
|
uint x1 = TileX(tile);
|
||||||
|
uint y1 = TileY(tile);
|
||||||
|
uint x2 = min(x1 + 1, MapMaxX());
|
||||||
|
uint y2 = min(y1 + 1, MapMaxY());
|
||||||
|
|
||||||
int h = TileHeight(tile); // N corner
|
int h = TileHeight(tile); // N corner
|
||||||
h = min(h, TileHeight(tile + TileDiffXY(1, 0))); // W corner
|
h = min(h, TileHeight(TileXY(x2, y1))); // W corner
|
||||||
h = min(h, TileHeight(tile + TileDiffXY(0, 1))); // E corner
|
h = min(h, TileHeight(TileXY(x1, y2))); // E corner
|
||||||
h = min(h, TileHeight(tile + TileDiffXY(1, 1))); // S corner
|
h = min(h, TileHeight(TileXY(x2, y2))); // S corner
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
@ -199,12 +142,15 @@ int GetTileZ(TileIndex tile)
|
|||||||
*/
|
*/
|
||||||
int GetTileMaxZ(TileIndex t)
|
int GetTileMaxZ(TileIndex t)
|
||||||
{
|
{
|
||||||
if (TileX(t) == MapMaxX() || TileY(t) == MapMaxY()) return TileHeightOutsideMap(TileX(t), TileY(t));
|
uint x1 = TileX(t);
|
||||||
|
uint y1 = TileY(t);
|
||||||
|
uint x2 = min(x1 + 1, MapMaxX());
|
||||||
|
uint y2 = min(y1 + 1, MapMaxY());
|
||||||
|
|
||||||
int h = TileHeight(t); // N corner
|
int h = TileHeight(t); // N corner
|
||||||
h = max<int>(h, TileHeight(t + TileDiffXY(1, 0))); // W corner
|
h = max<int>(h, TileHeight(TileXY(x2, y1))); // W corner
|
||||||
h = max<int>(h, TileHeight(t + TileDiffXY(0, 1))); // E corner
|
h = max<int>(h, TileHeight(TileXY(x1, y2))); // E corner
|
||||||
h = max<int>(h, TileHeight(t + TileDiffXY(1, 1))); // S corner
|
h = max<int>(h, TileHeight(TileXY(x2, y2))); // S corner
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,17 @@ static inline uint TileHeight(TileIndex tile)
|
|||||||
return _m[tile].height;
|
return _m[tile].height;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint TileHeightOutsideMap(int x, int y);
|
/**
|
||||||
|
* Returns the height of a tile, also for tiles outside the map (virtual "black" tiles).
|
||||||
|
*
|
||||||
|
* @param x X coordinate of the tile, may be ouside the map.
|
||||||
|
* @param y Y coordinate of the tile, may be ouside the map.
|
||||||
|
* @return The height in the same unit as TileHeight.
|
||||||
|
*/
|
||||||
|
static inline uint TileHeightOutsideMap(int x, int y)
|
||||||
|
{
|
||||||
|
return TileHeight(TileXY(Clamp(x, 0, MapMaxX()), Clamp(y, 0, MapMaxY())));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the height of a tile.
|
* Sets the height of a tile.
|
||||||
@ -67,11 +77,10 @@ static inline uint TilePixelHeight(TileIndex tile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the tile height for a coordinate outside map. Such a height is
|
* Returns the height of a tile in pixels, also for tiles outside the map (virtual "black" tiles).
|
||||||
* needed for painting the area outside map using completely black tiles.
|
*
|
||||||
* The idea is descending to heightlevel 0 as fast as possible.
|
* @param x X coordinate of the tile, may be ouside the map.
|
||||||
* @param x The X-coordinate (same unit as TileX).
|
* @param y Y coordinate of the tile, may be ouside the map.
|
||||||
* @param y The Y-coordinate (same unit as TileY).
|
|
||||||
* @return The height in pixels in the same unit as TilePixelHeight.
|
* @return The height in pixels in the same unit as TilePixelHeight.
|
||||||
*/
|
*/
|
||||||
static inline uint TilePixelHeightOutsideMap(int x, int y)
|
static inline uint TilePixelHeightOutsideMap(int x, int y)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
/** @file void_cmd.cpp Handling of void tiles. */
|
/** @file void_cmd.cpp Handling of void tiles. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "tile_cmd.h"
|
#include "landscape.h"
|
||||||
#include "command_func.h"
|
#include "command_func.h"
|
||||||
#include "viewport_func.h"
|
#include "viewport_func.h"
|
||||||
#include "slope_func.h"
|
#include "slope_func.h"
|
||||||
@ -28,7 +28,12 @@ static void DrawTile_Void(TileInfo *ti)
|
|||||||
|
|
||||||
static int GetSlopePixelZ_Void(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Void(TileIndex tile, uint x, uint y)
|
||||||
{
|
{
|
||||||
return TilePixelHeight(tile);
|
/* This function may be called on tiles outside the map, don't asssume
|
||||||
|
* that 'tile' is a valid tile index. See GetSlopePixelZOutsideMap. */
|
||||||
|
int z;
|
||||||
|
Slope tileh = GetTilePixelSlopeOutsideMap(x >> 4, y >> 4, &z);
|
||||||
|
|
||||||
|
return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Foundation GetFoundation_Void(TileIndex tile, Slope tileh)
|
static Foundation GetFoundation_Void(TileIndex tile, Slope tileh)
|
||||||
|
Loading…
Reference in New Issue
Block a user