Merge branch 'master' into jgrpp
# Conflicts: # src/elrail.cpp # src/ground_vehicle.hpp # src/landscape.cpp # src/saveload/afterload.cpp # src/saveload/saveload.h # src/tile_cmd.h # src/town_cmd.cpp # src/tunnelbridge_cmd.cpp
This commit is contained in:
@@ -23,6 +23,7 @@ add_subdirectory(saveload)
|
|||||||
add_subdirectory(sound)
|
add_subdirectory(sound)
|
||||||
add_subdirectory(spriteloader)
|
add_subdirectory(spriteloader)
|
||||||
add_subdirectory(table)
|
add_subdirectory(table)
|
||||||
|
add_subdirectory(tests)
|
||||||
add_subdirectory(video)
|
add_subdirectory(video)
|
||||||
add_subdirectory(widgets)
|
add_subdirectory(widgets)
|
||||||
|
|
||||||
|
@@ -197,7 +197,7 @@ static void DrawTile_Clear(TileInfo *ti, DrawTileProcParams params)
|
|||||||
DrawBridgeMiddle(ti);
|
DrawBridgeMiddle(ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetSlopePixelZ_Clear(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Clear(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
int z;
|
int z;
|
||||||
Slope tileh = GetTilePixelSlope(tile, &z);
|
Slope tileh = GetTilePixelSlope(tile, &z);
|
||||||
|
@@ -31,7 +31,7 @@
|
|||||||
* @return The selected bits, aligned to a LSB.
|
* @return The selected bits, aligned to a LSB.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
debug_inline static uint GB(const T x, const uint8 s, const uint8 n)
|
debug_inline constexpr static uint GB(const T x, const uint8 s, const uint8 n)
|
||||||
{
|
{
|
||||||
return (x >> s) & (((T)1U << n) - 1);
|
return (x >> s) & (((T)1U << n) - 1);
|
||||||
}
|
}
|
||||||
|
@@ -224,7 +224,7 @@ static inline bool IsInsideBS(const T x, const size_t base, const size_t size)
|
|||||||
* @see IsInsideBS()
|
* @see IsInsideBS()
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline bool IsInsideMM(const T x, const size_t min, const size_t max)
|
static inline constexpr bool IsInsideMM(const T x, const size_t min, const size_t max)
|
||||||
{
|
{
|
||||||
return (size_t)(x - min) < (max - min);
|
return (size_t)(x - min) < (max - min);
|
||||||
}
|
}
|
||||||
|
@@ -266,7 +266,7 @@ static int GetPCPElevation(TileIndex tile, DiagDirection PCPpos)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int z = GetSlopePixelZ(TileX(tile) * TILE_SIZE + std::min<int8>(x_pcp_offsets[PCPpos], TILE_SIZE - 1),
|
int z = GetSlopePixelZ(TileX(tile) * TILE_SIZE + std::min<int8>(x_pcp_offsets[PCPpos], TILE_SIZE - 1),
|
||||||
TileY(tile) * TILE_SIZE + std::min<int8>(y_pcp_offsets[PCPpos], TILE_SIZE - 1));
|
TileY(tile) * TILE_SIZE + std::min<int8>(y_pcp_offsets[PCPpos], TILE_SIZE - 1), true);
|
||||||
return (z + 2) & ~3; // this means z = (z + TILE_HEIGHT / 4) / (TILE_HEIGHT / 2) * (TILE_HEIGHT / 2);
|
return (z + 2) & ~3; // this means z = (z + TILE_HEIGHT / 4) / (TILE_HEIGHT / 2) * (TILE_HEIGHT / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,7 +591,7 @@ static void DrawRailCatenaryRailway(const TileInfo *ti)
|
|||||||
* down to the nearest full height change.
|
* down to the nearest full height change.
|
||||||
*/
|
*/
|
||||||
AddSortableSpriteToDraw(wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
|
AddSortableSpriteToDraw(wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
|
||||||
sss->x_size, sss->y_size, sss->z_size, (GetSlopePixelZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + 4) / 8 * 8 + sss->z_offset,
|
sss->x_size, sss->y_size, sss->z_size, (GetSlopePixelZ(ti->x + sss->x_offset, ti->y + sss->y_offset, true) + 4) / 8 * 8 + sss->z_offset,
|
||||||
IsTransparencySet(TO_CATENARY));
|
IsTransparencySet(TO_CATENARY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -151,7 +151,7 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
*/
|
*/
|
||||||
inline void UpdateZPositionAndInclination()
|
inline void UpdateZPositionAndInclination()
|
||||||
{
|
{
|
||||||
this->z_pos = GetSlopePixelZ(this->x_pos, this->y_pos);
|
this->z_pos = GetSlopePixelZ(this->x_pos, this->y_pos, true);
|
||||||
ClrBit(this->gv_flags, GVF_GOINGUP_BIT);
|
ClrBit(this->gv_flags, GVF_GOINGUP_BIT);
|
||||||
ClrBit(this->gv_flags, GVF_GOINGDOWN_BIT);
|
ClrBit(this->gv_flags, GVF_GOINGDOWN_BIT);
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
* direction it is sloped, we get the 'z' at the center of
|
* direction it is sloped, we get the 'z' at the center of
|
||||||
* the tile (middle_z) and the edge of the tile (old_z),
|
* the tile (middle_z) and the edge of the tile (old_z),
|
||||||
* which we then can compare. */
|
* which we then can compare. */
|
||||||
int middle_z = GetSlopePixelZ((this->x_pos & ~TILE_UNIT_MASK) | (TILE_SIZE / 2), (this->y_pos & ~TILE_UNIT_MASK) | (TILE_SIZE / 2));
|
int middle_z = GetSlopePixelZ((this->x_pos & ~TILE_UNIT_MASK) | (TILE_SIZE / 2), (this->y_pos & ~TILE_UNIT_MASK) | (TILE_SIZE / 2), true);
|
||||||
|
|
||||||
if (middle_z != this->z_pos) {
|
if (middle_z != this->z_pos) {
|
||||||
SetBit(this->gv_flags, (middle_z > this->z_pos) ? GVF_GOINGUP_BIT : GVF_GOINGDOWN_BIT);
|
SetBit(this->gv_flags, (middle_z > this->z_pos) ? GVF_GOINGUP_BIT : GVF_GOINGDOWN_BIT);
|
||||||
@@ -183,25 +183,25 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
if (HasBit(this->gv_flags, GVF_GOINGUP_BIT)) {
|
if (HasBit(this->gv_flags, GVF_GOINGUP_BIT)) {
|
||||||
switch (this->direction) {
|
switch (this->direction) {
|
||||||
case DIR_NE:
|
case DIR_NE:
|
||||||
this->z_pos += (this->x_pos & 1); break;
|
|
||||||
case DIR_SW:
|
|
||||||
this->z_pos += (this->x_pos & 1) ^ 1; break;
|
this->z_pos += (this->x_pos & 1) ^ 1; break;
|
||||||
|
case DIR_SW:
|
||||||
|
this->z_pos += (this->x_pos & 1); break;
|
||||||
case DIR_NW:
|
case DIR_NW:
|
||||||
this->z_pos += (this->y_pos & 1); break;
|
|
||||||
case DIR_SE:
|
|
||||||
this->z_pos += (this->y_pos & 1) ^ 1; break;
|
this->z_pos += (this->y_pos & 1) ^ 1; break;
|
||||||
|
case DIR_SE:
|
||||||
|
this->z_pos += (this->y_pos & 1); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
} else if (HasBit(this->gv_flags, GVF_GOINGDOWN_BIT)) {
|
} else if (HasBit(this->gv_flags, GVF_GOINGDOWN_BIT)) {
|
||||||
switch (this->direction) {
|
switch (this->direction) {
|
||||||
case DIR_NE:
|
case DIR_NE:
|
||||||
this->z_pos -= (this->x_pos & 1); break;
|
|
||||||
case DIR_SW:
|
|
||||||
this->z_pos -= (this->x_pos & 1) ^ 1; break;
|
this->z_pos -= (this->x_pos & 1) ^ 1; break;
|
||||||
|
case DIR_SW:
|
||||||
|
this->z_pos -= (this->x_pos & 1); break;
|
||||||
case DIR_NW:
|
case DIR_NW:
|
||||||
this->z_pos -= (this->y_pos & 1); break;
|
|
||||||
case DIR_SE:
|
|
||||||
this->z_pos -= (this->y_pos & 1) ^ 1; break;
|
this->z_pos -= (this->y_pos & 1) ^ 1; break;
|
||||||
|
case DIR_SE:
|
||||||
|
this->z_pos -= (this->y_pos & 1); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
if (HasBit(this->gv_flags, GVF_GOINGUP_BIT) || HasBit(this->gv_flags, GVF_GOINGDOWN_BIT)) {
|
if (HasBit(this->gv_flags, GVF_GOINGUP_BIT) || HasBit(this->gv_flags, GVF_GOINGDOWN_BIT)) {
|
||||||
if (T::From(this)->HasToUseGetSlopePixelZ()) {
|
if (T::From(this)->HasToUseGetSlopePixelZ()) {
|
||||||
/* In some cases, we have to use GetSlopePixelZ() */
|
/* In some cases, we have to use GetSlopePixelZ() */
|
||||||
this->z_pos = GetSlopePixelZ(this->x_pos, this->y_pos);
|
this->z_pos = GetSlopePixelZ(this->x_pos, this->y_pos, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* DirToDiagDir() is a simple right shift */
|
/* DirToDiagDir() is a simple right shift */
|
||||||
@@ -230,8 +230,7 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
int8 d = DiagDirToAxis(dir) == AXIS_X ? x_pos : y_pos;
|
int8 d = DiagDirToAxis(dir) == AXIS_X ? x_pos : y_pos;
|
||||||
/* We need only the least significant bit */
|
/* We need only the least significant bit */
|
||||||
d &= 1;
|
d &= 1;
|
||||||
/* Conditional "^ 1". Optimised to "(dir - 1) <= 1". */
|
d ^= (int8)(dir == DIAGDIR_NW || dir == DIAGDIR_NE);
|
||||||
d ^= (int8)(dir == DIAGDIR_SW || dir == DIAGDIR_SE);
|
|
||||||
/* Subtraction instead of addition because we are testing for GVF_GOINGUP_BIT.
|
/* Subtraction instead of addition because we are testing for GVF_GOINGUP_BIT.
|
||||||
* GVF_GOINGUP_BIT is used because it's bit 0, so simple AND can be used,
|
* GVF_GOINGUP_BIT is used because it's bit 0, so simple AND can be used,
|
||||||
* without any shift */
|
* without any shift */
|
||||||
@@ -239,7 +238,7 @@ struct GroundVehicle : public SpecializedVehicle<T, Type> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
assert(this->z_pos == GetSlopePixelZ(this->x_pos, this->y_pos));
|
assert(this->z_pos == GetSlopePixelZ(this->x_pos, this->y_pos, true));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (HasBit(this->gv_flags, GVF_CHUNNEL_BIT) && !IsTunnelTile(this->tile)) {
|
if (HasBit(this->gv_flags, GVF_CHUNNEL_BIT) && !IsTunnelTile(this->tile)) {
|
||||||
|
@@ -387,7 +387,7 @@ static void DrawTile_Industry(TileInfo *ti, DrawTileProcParams params)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetSlopePixelZ_Industry(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Industry(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
return GetTileMaxPixelZ(tile);
|
return GetTileMaxPixelZ(tile);
|
||||||
}
|
}
|
||||||
|
@@ -226,144 +226,112 @@ uint ApplyFoundationToSlope(Foundation f, Slope *s)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines height at given coordinate of a slope
|
* Determines height at given coordinate of a slope.
|
||||||
* @param x x coordinate
|
*
|
||||||
* @param y y coordinate
|
* At the northern corner (0, 0) the result is always a multiple of TILE_HEIGHT.
|
||||||
|
* When the height is a fractional Z, then the height is rounded down. For example,
|
||||||
|
* when at the height is 0 at x = 0 and the height is 8 at x = 16 (actually x = 0
|
||||||
|
* of the next tile), then height is 0 at x = 1, 1 at x = 2, and 7 at x = 15.
|
||||||
|
* @param x x coordinate (value from 0 to 15)
|
||||||
|
* @param y y coordinate (value from 0 to 15)
|
||||||
* @param corners slope to examine
|
* @param corners slope to examine
|
||||||
* @return height of given point of given slope
|
* @return height of given point of given slope
|
||||||
*/
|
*/
|
||||||
uint GetPartialPixelZ(int x, int y, Slope corners)
|
static constexpr uint InternalGetPartialPixelZ(int x, int y, Slope corners)
|
||||||
{
|
{
|
||||||
if (IsHalftileSlope(corners)) {
|
if (IsHalftileSlope(corners)) {
|
||||||
|
/* A foundation is placed on half the tile at a specific corner. This means that,
|
||||||
|
* depending on the corner, that one half of the tile is at the maximum height. */
|
||||||
switch (GetHalftileSlopeCorner(corners)) {
|
switch (GetHalftileSlopeCorner(corners)) {
|
||||||
case CORNER_W:
|
case CORNER_W:
|
||||||
if (x - y >= 0) return GetSlopeMaxPixelZ(corners);
|
if (x > y) return GetSlopeMaxPixelZ(corners);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CORNER_S:
|
case CORNER_S:
|
||||||
if (x - (y ^ 0xF) >= 0) return GetSlopeMaxPixelZ(corners);
|
if (x + y >= (int)TILE_SIZE) return GetSlopeMaxPixelZ(corners);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CORNER_E:
|
case CORNER_E:
|
||||||
if (y - x >= 0) return GetSlopeMaxPixelZ(corners);
|
if (x <= y) return GetSlopeMaxPixelZ(corners);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CORNER_N:
|
case CORNER_N:
|
||||||
if ((y ^ 0xF) - x >= 0) return GetSlopeMaxPixelZ(corners);
|
if (x + y < (int)TILE_SIZE) return GetSlopeMaxPixelZ(corners);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int z = 0;
|
|
||||||
|
|
||||||
switch (RemoveHalftileSlope(corners)) {
|
switch (RemoveHalftileSlope(corners)) {
|
||||||
case SLOPE_W:
|
case SLOPE_FLAT: return 0;
|
||||||
if (x - y >= 0) {
|
|
||||||
z = (x - y) >> 1;
|
/* One corner is up.*/
|
||||||
|
case SLOPE_N: return x + y <= (int)TILE_SIZE ? (TILE_SIZE - x - y) >> 1 : 0;
|
||||||
|
case SLOPE_E: return y >= x ? (1 + y - x) >> 1 : 0;
|
||||||
|
case SLOPE_S: return x + y >= (int)TILE_SIZE ? (1 + x + y - TILE_SIZE) >> 1 : 0;
|
||||||
|
case SLOPE_W: return x >= y ? (x - y) >> 1 : 0;
|
||||||
|
|
||||||
|
/* Two corners next to eachother are up. */
|
||||||
|
case SLOPE_NE: return (TILE_SIZE - x) >> 1;
|
||||||
|
case SLOPE_SE: return (y + 1) >> 1;
|
||||||
|
case SLOPE_SW: return (x + 1) >> 1;
|
||||||
|
case SLOPE_NW: return (TILE_SIZE - y) >> 1;
|
||||||
|
|
||||||
|
/* Three corners are up on the same level. */
|
||||||
|
case SLOPE_ENW: return x + y >= (int)TILE_SIZE ? TILE_HEIGHT - ((1 + x + y - TILE_SIZE) >> 1) : TILE_HEIGHT;
|
||||||
|
case SLOPE_SEN: return y < x ? TILE_HEIGHT - ((x - y) >> 1) : TILE_HEIGHT;
|
||||||
|
case SLOPE_WSE: return x + y <= (int)TILE_SIZE ? TILE_HEIGHT - ((TILE_SIZE - x - y) >> 1) : TILE_HEIGHT;
|
||||||
|
case SLOPE_NWS: return x < y ? TILE_HEIGHT - ((1 + y - x) >> 1) : TILE_HEIGHT;
|
||||||
|
|
||||||
|
/* Two corners at opposite sides are up. */
|
||||||
|
case SLOPE_NS: return x + y < (int)TILE_SIZE ? (TILE_SIZE - x - y) >> 1 : (1 + x + y - TILE_SIZE) >> 1;
|
||||||
|
case SLOPE_EW: return x >= y ? (x - y) >> 1 : (1 + y - x) >> 1;
|
||||||
|
|
||||||
|
/* Very special cases. */
|
||||||
|
case SLOPE_ELEVATED: return TILE_HEIGHT;
|
||||||
|
|
||||||
|
/* Steep slopes. The top is at 2 * TILE_HEIGHT. */
|
||||||
|
case SLOPE_STEEP_N: return (TILE_SIZE - x + TILE_SIZE - y) >> 1;
|
||||||
|
case SLOPE_STEEP_E: return (TILE_SIZE + 1 + y - x) >> 1;
|
||||||
|
case SLOPE_STEEP_S: return (1 + x + y) >> 1;
|
||||||
|
case SLOPE_STEEP_W: return (TILE_SIZE + x - y) >> 1;
|
||||||
|
|
||||||
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_S:
|
|
||||||
y ^= 0xF;
|
|
||||||
if ((x - y) >= 0) {
|
|
||||||
z = (x - y) >> 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_SW:
|
|
||||||
z = (x >> 1) + 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_E:
|
|
||||||
if (y - x >= 0) {
|
|
||||||
z = (y - x) >> 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_EW:
|
|
||||||
case SLOPE_NS:
|
|
||||||
case SLOPE_ELEVATED:
|
|
||||||
z = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_SE:
|
|
||||||
z = (y >> 1) + 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_WSE:
|
|
||||||
z = 8;
|
|
||||||
y ^= 0xF;
|
|
||||||
if (x - y < 0) {
|
|
||||||
z += (x - y) >> 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_N:
|
|
||||||
y ^= 0xF;
|
|
||||||
if (y - x >= 0) {
|
|
||||||
z = (y - x) >> 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_NW:
|
|
||||||
z = (y ^ 0xF) >> 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_NWS:
|
|
||||||
z = 8;
|
|
||||||
if (x - y < 0) {
|
|
||||||
z += (x - y) >> 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_NE:
|
|
||||||
z = (x ^ 0xF) >> 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_ENW:
|
|
||||||
z = 8;
|
|
||||||
y ^= 0xF;
|
|
||||||
if (y - x < 0) {
|
|
||||||
z += (y - x) >> 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_SEN:
|
|
||||||
z = 8;
|
|
||||||
if (y - x < 0) {
|
|
||||||
z += (y - x) >> 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_STEEP_S:
|
|
||||||
z = 1 + ((x + y) >> 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_STEEP_W:
|
|
||||||
z = 1 + ((x + (y ^ 0xF)) >> 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_STEEP_N:
|
|
||||||
z = 1 + (((x ^ 0xF) + (y ^ 0xF)) >> 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SLOPE_STEEP_E:
|
|
||||||
z = 1 + (((x ^ 0xF) + y) >> 1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetSlopePixelZ(int x, int y)
|
#include "tests/landscape_partial_pixel_z.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines height at given coordinate of a slope.
|
||||||
|
* See #InternalGetPartialPixelZ.
|
||||||
|
* @param x x coordinate (value from 0 to 15)
|
||||||
|
* @param y y coordinate (value from 0 to 15)
|
||||||
|
* @param corners slope to examine
|
||||||
|
* @return height of given point of given slope
|
||||||
|
*/
|
||||||
|
uint GetPartialPixelZ(int x, int y, Slope corners)
|
||||||
|
{
|
||||||
|
return InternalGetPartialPixelZ(x, y, corners);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return world \c Z coordinate of a given point of a tile. Normally this is the
|
||||||
|
* Z of the ground/foundation at the given location, but in some cases the
|
||||||
|
* ground/foundation can differ from the Z coordinate that the (ground) vehicle
|
||||||
|
* passing over it would take. For example when entering a tunnel or bridge.
|
||||||
|
*
|
||||||
|
* @param x World X coordinate in tile "units".
|
||||||
|
* @param y World Y coordinate in tile "units".
|
||||||
|
* @param ground_vehicle Whether to get the Z coordinate of the ground vehicle, or the ground.
|
||||||
|
* @return World Z coordinate at tile ground (vehicle) level, including slopes and foundations.
|
||||||
|
*/
|
||||||
|
int GetSlopePixelZ(int x, int y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
TileIndex tile = TileVirtXY(x, y);
|
TileIndex tile = TileVirtXY(x, 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, ground_vehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -377,9 +345,9 @@ int GetSlopePixelZ(int x, int y)
|
|||||||
int GetSlopePixelZOutsideMap(int x, int y)
|
int GetSlopePixelZOutsideMap(int x, int y)
|
||||||
{
|
{
|
||||||
if (IsInsideBS(x, 0, MapSizeX() * TILE_SIZE) && IsInsideBS(y, 0, MapSizeY() * TILE_SIZE)) {
|
if (IsInsideBS(x, 0, MapSizeX() * TILE_SIZE) && IsInsideBS(y, 0, MapSizeY() * TILE_SIZE)) {
|
||||||
return GetSlopePixelZ(x, y);
|
return GetSlopePixelZ(x, y, false);
|
||||||
} else {
|
} else {
|
||||||
return _tile_type_procs[MP_VOID]->get_slope_z_proc(INVALID_TILE, x, y);
|
return _tile_type_procs[MP_VOID]->get_slope_z_proc(INVALID_TILE, x, y, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ Slope GetFoundationSlopeFromTileSlope(TileIndex tile, Slope tileh, int *z = null
|
|||||||
Slope GetFoundationSlope(TileIndex tile, int *z = nullptr);
|
Slope GetFoundationSlope(TileIndex tile, int *z = nullptr);
|
||||||
|
|
||||||
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, bool ground_vehicle = false);
|
||||||
int GetSlopePixelZOutsideMap(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);
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ static inline Point RemapCoords(int x, int y, int z)
|
|||||||
*/
|
*/
|
||||||
static inline Point RemapCoords2(int x, int y)
|
static inline Point RemapCoords2(int x, int y)
|
||||||
{
|
{
|
||||||
return RemapCoords(x, y, GetSlopePixelZ(x, y));
|
return RemapCoords(x, y, GetSlopePixelZ(x, y, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -659,7 +659,7 @@ static void DrawTile_Object(TileInfo *ti, DrawTileProcParams params)
|
|||||||
DrawBridgeMiddle(ti);
|
DrawBridgeMiddle(ti);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetSlopePixelZ_Object(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Object(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
if (IsObjectType(tile, OBJECT_OWNED_LAND)) {
|
if (IsObjectType(tile, OBJECT_OWNED_LAND)) {
|
||||||
int z;
|
int z;
|
||||||
|
@@ -226,8 +226,8 @@ static uint NPFSlopeCost(AyStarNode *current)
|
|||||||
/* Get the height on both sides of the tile edge.
|
/* Get the height on both sides of the tile edge.
|
||||||
* Avoid testing the height on the tile-center. This will fail for halftile-foundations.
|
* Avoid testing the height on the tile-center. This will fail for halftile-foundations.
|
||||||
*/
|
*/
|
||||||
int z1 = GetSlopePixelZ(x1 + dx4, y1 + dy4);
|
int z1 = GetSlopePixelZ(x1 + dx4, y1 + dy4, true);
|
||||||
int z2 = GetSlopePixelZ(x2 - dx4, y2 - dy4);
|
int z2 = GetSlopePixelZ(x2 - dx4, y2 - dy4, true);
|
||||||
|
|
||||||
if (z2 - z1 > 1) {
|
if (z2 - z1 > 1) {
|
||||||
/* Slope up */
|
/* Slope up */
|
||||||
|
@@ -53,12 +53,12 @@ protected:
|
|||||||
/* height of the center of the current tile */
|
/* height of the center of the current tile */
|
||||||
int x1 = TileX(tile) * TILE_SIZE;
|
int x1 = TileX(tile) * TILE_SIZE;
|
||||||
int y1 = TileY(tile) * TILE_SIZE;
|
int y1 = TileY(tile) * TILE_SIZE;
|
||||||
int z1 = GetSlopePixelZ(x1 + TILE_SIZE / 2, y1 + TILE_SIZE / 2);
|
int z1 = GetSlopePixelZ(x1 + TILE_SIZE / 2, y1 + TILE_SIZE / 2, true);
|
||||||
|
|
||||||
/* height of the center of the next tile */
|
/* height of the center of the next tile */
|
||||||
int x2 = TileX(next_tile) * TILE_SIZE;
|
int x2 = TileX(next_tile) * TILE_SIZE;
|
||||||
int y2 = TileY(next_tile) * TILE_SIZE;
|
int y2 = TileY(next_tile) * TILE_SIZE;
|
||||||
int z2 = GetSlopePixelZ(x2 + TILE_SIZE / 2, y2 + TILE_SIZE / 2);
|
int z2 = GetSlopePixelZ(x2 + TILE_SIZE / 2, y2 + TILE_SIZE / 2, true);
|
||||||
|
|
||||||
if (z2 - z1 > 1) {
|
if (z2 - z1 > 1) {
|
||||||
/* Slope up */
|
/* Slope up */
|
||||||
|
@@ -439,7 +439,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
|
|||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
z = GetSlopePixelZ(x, y);
|
z = GetSlopePixelZ(x, y, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -3752,7 +3752,7 @@ void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype)
|
|||||||
DrawRailTileSeqInGUI(x, y, dts, offset, 0, palette);
|
DrawRailTileSeqInGUI(x, y, dts, offset, 0, palette);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetSlopePixelZ_Track(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Track(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
if (IsPlainRail(tile)) {
|
if (IsPlainRail(tile)) {
|
||||||
int z;
|
int z;
|
||||||
|
@@ -2494,7 +2494,7 @@ void UpdateNearestTownForRoadTiles(bool invalidate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetSlopePixelZ_Road(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Road(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (IsNormalRoad(tile)) {
|
if (IsNormalRoad(tile)) {
|
||||||
|
@@ -288,7 +288,7 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin
|
|||||||
int y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
|
int y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
|
||||||
v->x_pos = x;
|
v->x_pos = x;
|
||||||
v->y_pos = y;
|
v->y_pos = y;
|
||||||
v->z_pos = GetSlopePixelZ(x, y);
|
v->z_pos = GetSlopePixelZ(x, y, true);
|
||||||
|
|
||||||
v->state = RVSB_IN_DEPOT;
|
v->state = RVSB_IN_DEPOT;
|
||||||
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
|
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
|
||||||
@@ -2013,7 +2013,7 @@ again:
|
|||||||
* A vehicle has to spend at least 9 frames on a tile, so the following articulated part can follow.
|
* A vehicle has to spend at least 9 frames on a tile, so the following articulated part can follow.
|
||||||
* (The following part may only be one tile behind, and the front part is moved before the following ones.)
|
* (The following part may only be one tile behind, and the front part is moved before the following ones.)
|
||||||
* The short (inner) curve has 8 frames, this elongates it to 10. */
|
* The short (inner) curve has 8 frames, this elongates it to 10. */
|
||||||
v->UpdateInclination(false, true);
|
v->UpdateViewport(true, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -569,12 +569,12 @@ static uint FixVehicleInclination(Vehicle *v, Direction dir)
|
|||||||
case INVALID_DIR: break;
|
case INVALID_DIR: break;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
byte entry_z = GetSlopePixelZ(entry_x, entry_y);
|
byte entry_z = GetSlopePixelZ(entry_x, entry_y, true);
|
||||||
|
|
||||||
/* Compute middle of the tile. */
|
/* Compute middle of the tile. */
|
||||||
int middle_x = (v->x_pos & ~TILE_UNIT_MASK) + TILE_SIZE / 2;
|
int middle_x = (v->x_pos & ~TILE_UNIT_MASK) + TILE_SIZE / 2;
|
||||||
int middle_y = (v->y_pos & ~TILE_UNIT_MASK) + TILE_SIZE / 2;
|
int middle_y = (v->y_pos & ~TILE_UNIT_MASK) + TILE_SIZE / 2;
|
||||||
byte middle_z = GetSlopePixelZ(middle_x, middle_y);
|
byte middle_z = GetSlopePixelZ(middle_x, middle_y, true);
|
||||||
|
|
||||||
/* middle_z == entry_z, no height change. */
|
/* middle_z == entry_z, no height change. */
|
||||||
if (middle_z == entry_z) return 0;
|
if (middle_z == entry_z) return 0;
|
||||||
@@ -586,6 +586,25 @@ static uint FixVehicleInclination(Vehicle *v, Direction dir)
|
|||||||
return 1U << GVF_GOINGUP_BIT;
|
return 1U << GVF_GOINGUP_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the ground vehicles are at the correct Z-coordinate. When they
|
||||||
|
* are not, this will cause all kinds of problems later on as the vehicle might
|
||||||
|
* not get onto bridges and so on.
|
||||||
|
*/
|
||||||
|
static void CheckGroundVehiclesAtCorrectZ()
|
||||||
|
{
|
||||||
|
for (Vehicle *v : Vehicle::Iterate()) {
|
||||||
|
if (v->IsGroundVehicle()) {
|
||||||
|
/*
|
||||||
|
* Either the vehicle is not actually on the given tile, i.e. it is
|
||||||
|
* in the wormhole of a bridge or a tunnel, or the Z-coordinate must
|
||||||
|
* be the same as when it would be recalculated right now.
|
||||||
|
*/
|
||||||
|
assert(v->tile != TileVirtXY(v->x_pos, v->y_pos) || v->z_pos == GetSlopePixelZ(v->x_pos, v->y_pos, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for the possibility that a bridge may be on this tile
|
* Checks for the possibility that a bridge may be on this tile
|
||||||
* These are in fact all the tile types on which a bridge can be found
|
* These are in fact all the tile types on which a bridge can be found
|
||||||
@@ -1440,7 +1459,7 @@ bool AfterLoadGame()
|
|||||||
case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break;
|
case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break;
|
||||||
case DIAGDIR_NW: if ((v->y_pos & 0xF) != 0) continue; break;
|
case DIAGDIR_NW: if ((v->y_pos & 0xF) != 0) continue; break;
|
||||||
}
|
}
|
||||||
} else if (v->z_pos > GetSlopePixelZ(v->x_pos, v->y_pos)) {
|
} else if (v->z_pos > GetTileMaxPixelZ(TileVirtXY(v->x_pos, v->y_pos))) {
|
||||||
v->tile = GetNorthernBridgeEnd(v->tile);
|
v->tile = GetNorthernBridgeEnd(v->tile);
|
||||||
v->UpdatePosition();
|
v->UpdatePosition();
|
||||||
} else {
|
} else {
|
||||||
@@ -2895,7 +2914,7 @@ bool AfterLoadGame()
|
|||||||
if (!IsTunnelTile(vtile)) continue;
|
if (!IsTunnelTile(vtile)) continue;
|
||||||
|
|
||||||
/* Are we actually in this tunnel? Or maybe a lower tunnel? */
|
/* Are we actually in this tunnel? Or maybe a lower tunnel? */
|
||||||
if (GetSlopePixelZ(v->x_pos, v->y_pos) != v->z_pos) continue;
|
if (GetSlopePixelZ(v->x_pos, v->y_pos, true) != v->z_pos) continue;
|
||||||
|
|
||||||
/* What way are we going? */
|
/* What way are we going? */
|
||||||
const DiagDirection dir = GetTunnelBridgeDirection(vtile);
|
const DiagDirection dir = GetTunnelBridgeDirection(vtile);
|
||||||
@@ -2974,6 +2993,23 @@ bool AfterLoadGame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsSavegameVersionBefore(SLV_CONSISTENT_PARTIAL_Z) && SlXvIsFeatureMissing(XSLFI_CONSISTENT_PARTIAL_Z)) {
|
||||||
|
/*
|
||||||
|
* The logic of GetPartialPixelZ has been changed, so the resulting Zs on
|
||||||
|
* the map are consistent. This requires that the Z position of some
|
||||||
|
* vehicles is updated to reflect this new situation.
|
||||||
|
*
|
||||||
|
* This needs to be before SLV_158, because that performs asserts using
|
||||||
|
* GetSlopePixelZ which internally uses GetPartialPixelZ.
|
||||||
|
*/
|
||||||
|
for (Vehicle *v : Vehicle::Iterate()) {
|
||||||
|
if (v->IsGroundVehicle() && TileVirtXY(v->x_pos, v->y_pos) == v->tile) {
|
||||||
|
/* Vehicle is on the ground, and not in a wormhole. */
|
||||||
|
v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IsSavegameVersionBefore(SLV_158)) {
|
if (IsSavegameVersionBefore(SLV_158)) {
|
||||||
for (Vehicle *v : Vehicle::Iterate()) {
|
for (Vehicle *v : Vehicle::Iterate()) {
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
@@ -3040,7 +3076,7 @@ bool AfterLoadGame()
|
|||||||
/* In old versions, z_pos was 1 unit lower on bridge heads.
|
/* In old versions, z_pos was 1 unit lower on bridge heads.
|
||||||
* However, this invalid state could be converted to new savegames
|
* However, this invalid state could be converted to new savegames
|
||||||
* by loading and saving the game in a new version. */
|
* by loading and saving the game in a new version. */
|
||||||
v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos);
|
v->z_pos = GetSlopePixelZ(v->x_pos, v->y_pos, true);
|
||||||
DiagDirection dir = GetTunnelBridgeDirection(v->tile);
|
DiagDirection dir = GetTunnelBridgeDirection(v->tile);
|
||||||
if (v->type == VEH_TRAIN && !(v->vehstatus & VS_CRASHED) &&
|
if (v->type == VEH_TRAIN && !(v->vehstatus & VS_CRASHED) &&
|
||||||
v->direction != DiagDirToDir(dir)) {
|
v->direction != DiagDirToDir(dir)) {
|
||||||
@@ -3054,7 +3090,7 @@ bool AfterLoadGame()
|
|||||||
|
|
||||||
/* If the vehicle is really above v->tile (not in a wormhole),
|
/* If the vehicle is really above v->tile (not in a wormhole),
|
||||||
* it should have set v->z_pos correctly. */
|
* it should have set v->z_pos correctly. */
|
||||||
assert(v->tile != TileVirtXY(v->x_pos, v->y_pos) || v->z_pos == GetSlopePixelZ(v->x_pos, v->y_pos));
|
assert(v->tile != TileVirtXY(v->x_pos, v->y_pos) || v->z_pos == GetSlopePixelZ(v->x_pos, v->y_pos, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill Vehicle::cur_real_order_index */
|
/* Fill Vehicle::cur_real_order_index */
|
||||||
@@ -4209,6 +4245,14 @@ bool AfterLoadGame()
|
|||||||
AfterLoad_LinkGraphPauseControl();
|
AfterLoad_LinkGraphPauseControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SlXvIsFeatureMissing(XSLFI_CONSISTENT_PARTIAL_Z)) {
|
||||||
|
CheckGroundVehiclesAtCorrectZ();
|
||||||
|
} else {
|
||||||
|
#ifdef _DEBUG
|
||||||
|
CheckGroundVehiclesAtCorrectZ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
_game_load_cur_date_ymd = _cur_date_ymd;
|
_game_load_cur_date_ymd = _cur_date_ymd;
|
||||||
_game_load_date_fract = _date_fract;
|
_game_load_date_fract = _date_fract;
|
||||||
_game_load_tick_skip_counter = _tick_skip_counter;
|
_game_load_tick_skip_counter = _tick_skip_counter;
|
||||||
|
@@ -194,6 +194,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_LAST_LOADING_TICK, XSCF_NULL, 2, 2, "last_loading_tick", nullptr, nullptr, nullptr },
|
{ XSLFI_LAST_LOADING_TICK, XSCF_NULL, 2, 2, "last_loading_tick", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_SCRIPT_LEAGUE_TABLES, XSCF_NULL, 1, 1, "script_league_tables", nullptr, nullptr, "LEAE,LEAT" },
|
{ XSLFI_SCRIPT_LEAGUE_TABLES, XSCF_NULL, 1, 1, "script_league_tables", nullptr, nullptr, "LEAE,LEAT" },
|
||||||
{ XSLFI_VELOCITY_NAUTICAL, XSCF_IGNORABLE_ALL, 1, 1, "velocity_nautical", nullptr, nullptr, nullptr },
|
{ XSLFI_VELOCITY_NAUTICAL, XSCF_IGNORABLE_ALL, 1, 1, "velocity_nautical", nullptr, nullptr, nullptr },
|
||||||
|
{ XSLFI_CONSISTENT_PARTIAL_Z, XSCF_NULL, 1, 1, "consistent_partial_z", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -146,6 +146,7 @@ enum SlXvFeatureIndex {
|
|||||||
XSLFI_LAST_LOADING_TICK, ///< See: SLV_LAST_LOADING_TICK
|
XSLFI_LAST_LOADING_TICK, ///< See: SLV_LAST_LOADING_TICK
|
||||||
XSLFI_SCRIPT_LEAGUE_TABLES, ///< See: Scriptable league tables (PR #10001)
|
XSLFI_SCRIPT_LEAGUE_TABLES, ///< See: Scriptable league tables (PR #10001)
|
||||||
XSLFI_VELOCITY_NAUTICAL, ///< See: SLV_VELOCITY_NAUTICAL (PR #10594)
|
XSLFI_VELOCITY_NAUTICAL, ///< See: SLV_VELOCITY_NAUTICAL (PR #10594)
|
||||||
|
XSLFI_CONSISTENT_PARTIAL_Z, ///< See: SLV_CONSISTENT_PARTIAL_Z (PR #10570)
|
||||||
|
|
||||||
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
||||||
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
||||||
|
@@ -357,6 +357,7 @@ enum SaveLoadVersion : uint16 {
|
|||||||
SLV_LINKGRAPH_EDGES, ///< 304 PR#10314 Explicitly store link graph edges destination.
|
SLV_LINKGRAPH_EDGES, ///< 304 PR#10314 Explicitly store link graph edges destination.
|
||||||
|
|
||||||
SLV_VELOCITY_NAUTICAL, ///< 305 PR#10594 Separation of land and nautical velocity (knots!)
|
SLV_VELOCITY_NAUTICAL, ///< 305 PR#10594 Separation of land and nautical velocity (knots!)
|
||||||
|
SLV_CONSISTENT_PARTIAL_Z, ///< 306 PR#10570 Conversion from an inconsistent partial Z calculation for slopes, to one that is (more) consistent.
|
||||||
|
|
||||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
* @param corner A #Corner.
|
* @param corner A #Corner.
|
||||||
* @return true iff corner is in a valid range.
|
* @return true iff corner is in a valid range.
|
||||||
*/
|
*/
|
||||||
static inline bool IsValidCorner(Corner corner)
|
static constexpr inline bool IsValidCorner(Corner corner)
|
||||||
{
|
{
|
||||||
return IsInsideMM(corner, 0, CORNER_END);
|
return IsInsideMM(corner, 0, CORNER_END);
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ static inline bool IsValidCorner(Corner corner)
|
|||||||
* @param s The given #Slope.
|
* @param s The given #Slope.
|
||||||
* @return True if the slope is steep, else false.
|
* @return True if the slope is steep, else false.
|
||||||
*/
|
*/
|
||||||
static inline bool IsSteepSlope(Slope s)
|
static constexpr inline bool IsSteepSlope(Slope s)
|
||||||
{
|
{
|
||||||
return (s & SLOPE_STEEP) != 0;
|
return (s & SLOPE_STEEP) != 0;
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ static inline bool IsSteepSlope(Slope s)
|
|||||||
* @param s The given #Slope.
|
* @param s The given #Slope.
|
||||||
* @return True if the slope is non-continuous, else false.
|
* @return True if the slope is non-continuous, else false.
|
||||||
*/
|
*/
|
||||||
static inline bool IsHalftileSlope(Slope s)
|
static constexpr inline bool IsHalftileSlope(Slope s)
|
||||||
{
|
{
|
||||||
return (s & SLOPE_HALFTILE) != 0;
|
return (s & SLOPE_HALFTILE) != 0;
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ static inline bool IsHalftileSlope(Slope s)
|
|||||||
* @param s A #Slope.
|
* @param s A #Slope.
|
||||||
* @return The slope s without its halftile slope.
|
* @return The slope s without its halftile slope.
|
||||||
*/
|
*/
|
||||||
static inline Slope RemoveHalftileSlope(Slope s)
|
static constexpr inline Slope RemoveHalftileSlope(Slope s)
|
||||||
{
|
{
|
||||||
return s & ~SLOPE_HALFTILE_MASK;
|
return s & ~SLOPE_HALFTILE_MASK;
|
||||||
}
|
}
|
||||||
@@ -145,7 +145,7 @@ static inline Corner GetHighestSlopeCorner(Slope s)
|
|||||||
* @param s The #Slope.
|
* @param s The #Slope.
|
||||||
* @return The corner of the leveled halftile.
|
* @return The corner of the leveled halftile.
|
||||||
*/
|
*/
|
||||||
static inline Corner GetHalftileSlopeCorner(Slope s)
|
static constexpr inline Corner GetHalftileSlopeCorner(Slope s)
|
||||||
{
|
{
|
||||||
dbg_assert(IsHalftileSlope(s));
|
dbg_assert(IsHalftileSlope(s));
|
||||||
return (Corner)((s >> 6) & 3);
|
return (Corner)((s >> 6) & 3);
|
||||||
@@ -157,7 +157,7 @@ static inline Corner GetHalftileSlopeCorner(Slope s)
|
|||||||
* @param s The #Slope.
|
* @param s The #Slope.
|
||||||
* @return Relative height of highest corner.
|
* @return Relative height of highest corner.
|
||||||
*/
|
*/
|
||||||
static inline int GetSlopeMaxZ(Slope s)
|
static constexpr inline int GetSlopeMaxZ(Slope s)
|
||||||
{
|
{
|
||||||
if (s == SLOPE_FLAT) return 0;
|
if (s == SLOPE_FLAT) return 0;
|
||||||
if (IsSteepSlope(s)) return 2;
|
if (IsSteepSlope(s)) return 2;
|
||||||
@@ -170,7 +170,7 @@ static inline int GetSlopeMaxZ(Slope s)
|
|||||||
* @param s The #Slope.
|
* @param s The #Slope.
|
||||||
* @return Relative height of highest corner.
|
* @return Relative height of highest corner.
|
||||||
*/
|
*/
|
||||||
static inline int GetSlopeMaxPixelZ(Slope s)
|
static constexpr inline int GetSlopeMaxPixelZ(Slope s)
|
||||||
{
|
{
|
||||||
return GetSlopeMaxZ(s) * TILE_HEIGHT;
|
return GetSlopeMaxZ(s) * TILE_HEIGHT;
|
||||||
}
|
}
|
||||||
@@ -271,7 +271,7 @@ static inline Slope InclinedSlope(DiagDirection dir)
|
|||||||
* @param corner The #Corner of the halftile.
|
* @param corner The #Corner of the halftile.
|
||||||
* @return The #Slope s with the halftile slope added.
|
* @return The #Slope s with the halftile slope added.
|
||||||
*/
|
*/
|
||||||
static inline Slope HalftileSlope(Slope s, Corner corner)
|
static constexpr inline Slope HalftileSlope(Slope s, Corner corner)
|
||||||
{
|
{
|
||||||
dbg_assert(IsValidCorner(corner));
|
dbg_assert(IsValidCorner(corner));
|
||||||
return (Slope)(s | SLOPE_HALFTILE | (corner << 6));
|
return (Slope)(s | SLOPE_HALFTILE | (corner << 6));
|
||||||
|
@@ -3668,7 +3668,7 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro
|
|||||||
DrawRailTileSeqInGUI(x, y, t, (st == STATION_WAYPOINT || st == STATION_ROADWAYPOINT) ? 0 : total_offset, 0, pal);
|
DrawRailTileSeqInGUI(x, y, t, (st == STATION_WAYPOINT || st == STATION_ROADWAYPOINT) ? 0 : total_offset, 0, pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetSlopePixelZ_Station(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Station(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
return GetTileMaxPixelZ(tile);
|
return GetTileMaxPixelZ(tile);
|
||||||
}
|
}
|
||||||
|
3
src/tests/CMakeLists.txt
Normal file
3
src/tests/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
add_files(
|
||||||
|
landscape_partial_pixel_z.h
|
||||||
|
)
|
552
src/tests/landscape_partial_pixel_z.h
Normal file
552
src/tests/landscape_partial_pixel_z.h
Normal file
@@ -0,0 +1,552 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file landscape_partial_pixel_z.h Tests for consistency/validity of the results of GetPartialPixelZ. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the addition of two slope's GetPartialPixelZ values results in
|
||||||
|
* the GetPartialPixelZ values of the expected slope.
|
||||||
|
* This iterates over all sub-pixel locations within a single tile.
|
||||||
|
* @param slope_expected The slope that is expected.
|
||||||
|
* @param slope_a The first slope of the addition.
|
||||||
|
* @param slope_b The second slope of the addition.
|
||||||
|
* @return True iff at all GetPartialPixelZ results are the same for each sub-tile position.
|
||||||
|
*/
|
||||||
|
constexpr bool CheckPartialPixelZSlopeAddition(Slope slope_expected, Slope slope_a, Slope slope_b)
|
||||||
|
{
|
||||||
|
for (uint x = 0; x < TILE_SIZE; x++) {
|
||||||
|
for (uint y = 0; y < TILE_SIZE; y++) {
|
||||||
|
int z_a = InternalGetPartialPixelZ(x, y, slope_a);
|
||||||
|
int z_b = InternalGetPartialPixelZ(x, y, slope_b);
|
||||||
|
int z_result = InternalGetPartialPixelZ(x, y, slope_expected);
|
||||||
|
if (z_result != z_a + z_b) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A one corner slope, plus the opposite three corner slope results in a flat but elevated slope. */
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, SLOPE_N, SLOPE_WSE));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, SLOPE_E, SLOPE_NWS));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, SLOPE_S, SLOPE_ENW));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, SLOPE_W, SLOPE_SEN));
|
||||||
|
|
||||||
|
/* Diagonal slopes with their opposite slope result in a flat but elevated slope. */
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, SLOPE_NW, SLOPE_SE));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, SLOPE_SW, SLOPE_NE));
|
||||||
|
|
||||||
|
/* Half tile slopes with their opposite half tile slope result in a flat but elevated slope. */
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, HalftileSlope(SLOPE_N, CORNER_N), HalftileSlope(SLOPE_S, CORNER_S)));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_ELEVATED, HalftileSlope(SLOPE_E, CORNER_E), HalftileSlope(SLOPE_W, CORNER_W)));
|
||||||
|
|
||||||
|
/* Two opposite one corner slopes result in the two corner slope with opposite corners. */
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_NS, SLOPE_N, SLOPE_S));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_EW, SLOPE_E, SLOPE_W));
|
||||||
|
|
||||||
|
/* A steep slope is a one corner slope on top of a three corner slope. */
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_STEEP_N, SLOPE_N, SLOPE_ENW));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_STEEP_E, SLOPE_E, SLOPE_SEN));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_STEEP_S, SLOPE_S, SLOPE_WSE));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(SLOPE_STEEP_W, SLOPE_W, SLOPE_NWS));
|
||||||
|
|
||||||
|
/* A half tile steep slope is a one corner half tile on top of a three corner slope. */
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(HalftileSlope(SLOPE_STEEP_N, CORNER_N), HalftileSlope(SLOPE_N, CORNER_N), SLOPE_ENW));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(HalftileSlope(SLOPE_STEEP_E, CORNER_E), HalftileSlope(SLOPE_E, CORNER_E), SLOPE_SEN));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(HalftileSlope(SLOPE_STEEP_S, CORNER_S), HalftileSlope(SLOPE_S, CORNER_S), SLOPE_WSE));
|
||||||
|
static_assert(CheckPartialPixelZSlopeAddition(HalftileSlope(SLOPE_STEEP_W, CORNER_W), HalftileSlope(SLOPE_W, CORNER_W), SLOPE_NWS));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the partial pixel Z values are the expected values. The arrays
|
||||||
|
* are as if the map is rotated 45 degrees counterclockwise.
|
||||||
|
* @param slope The slope that is to be checked.
|
||||||
|
* @param expected The expect partial pixels Z values.
|
||||||
|
* @return True iff at all GetPartialPixelZ results are the same as the expected Z-coordinates.
|
||||||
|
*/
|
||||||
|
constexpr bool CheckPartialPixelZ(Slope slope, std::array<int, TILE_SIZE * TILE_SIZE> expected)
|
||||||
|
{
|
||||||
|
for (uint i = 0; i < expected.size(); i++) {
|
||||||
|
int actual = InternalGetPartialPixelZ(GB(i, 4, 4), GB(i, 0, 4), slope);
|
||||||
|
if (actual != expected[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* One corner up slopes. */
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_N, {
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0,
|
||||||
|
7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0,
|
||||||
|
6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0,
|
||||||
|
6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0,
|
||||||
|
5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_E, {
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
|
||||||
|
0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
|
||||||
|
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||||
|
0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_S, {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
|
||||||
|
0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
|
||||||
|
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||||
|
0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
|
||||||
|
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_W, {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0,
|
||||||
|
6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0,
|
||||||
|
6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0,
|
||||||
|
7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0,
|
||||||
|
7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0}));
|
||||||
|
|
||||||
|
/* Two corner up, diagonal slopes. */
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_NE, {
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_SE, {
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_SW, {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_NW, {
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0}));
|
||||||
|
|
||||||
|
/* Two opposite corner up slopes. */
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_NS, {
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0,
|
||||||
|
7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1,
|
||||||
|
6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1,
|
||||||
|
6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2,
|
||||||
|
5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2,
|
||||||
|
5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3,
|
||||||
|
4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3,
|
||||||
|
4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4,
|
||||||
|
3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
|
||||||
|
3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
|
||||||
|
2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
|
||||||
|
2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
|
||||||
|
1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||||
|
1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
|
||||||
|
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_EW, {
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
|
||||||
|
1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7,
|
||||||
|
1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
||||||
|
2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
|
||||||
|
2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
|
||||||
|
3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
|
||||||
|
3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4,
|
||||||
|
4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 4,
|
||||||
|
4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3,
|
||||||
|
5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2, 3,
|
||||||
|
5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2, 2,
|
||||||
|
6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1, 2,
|
||||||
|
6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1, 1,
|
||||||
|
7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 1,
|
||||||
|
7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0}));
|
||||||
|
|
||||||
|
/* Three corner up slopes. */
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_ENW, {
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3,
|
||||||
|
8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3,
|
||||||
|
8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2,
|
||||||
|
8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2,
|
||||||
|
8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1,
|
||||||
|
8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_SEN, {
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,
|
||||||
|
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8,
|
||||||
|
2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,
|
||||||
|
1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8,
|
||||||
|
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_WSE, {
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
||||||
|
1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8,
|
||||||
|
2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8,
|
||||||
|
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8,
|
||||||
|
3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8,
|
||||||
|
3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
4, 5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
5, 5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
5, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_NWS, {
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1,
|
||||||
|
8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1,
|
||||||
|
8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2,
|
||||||
|
8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2,
|
||||||
|
8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}));
|
||||||
|
|
||||||
|
/* Normal half tile slopes. */
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_N, CORNER_N), {
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_E, CORNER_E), {
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_S, CORNER_S), {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_W, CORNER_W), {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0}));
|
||||||
|
|
||||||
|
/* Steep slopes. */
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_STEEP_N, {
|
||||||
|
16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8,
|
||||||
|
15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8,
|
||||||
|
15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7,
|
||||||
|
14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7,
|
||||||
|
14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6,
|
||||||
|
13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6,
|
||||||
|
13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5,
|
||||||
|
12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5,
|
||||||
|
12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4,
|
||||||
|
11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4,
|
||||||
|
11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3,
|
||||||
|
10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3,
|
||||||
|
10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2,
|
||||||
|
9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2,
|
||||||
|
9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1,
|
||||||
|
8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_STEEP_E, {
|
||||||
|
8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
|
||||||
|
8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15,
|
||||||
|
7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15,
|
||||||
|
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
||||||
|
6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14,
|
||||||
|
6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
|
||||||
|
5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13,
|
||||||
|
5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
|
||||||
|
4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
|
||||||
|
4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||||
|
3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11,
|
||||||
|
3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
|
||||||
|
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
|
||||||
|
2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
|
||||||
|
1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
|
||||||
|
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_STEEP_S, {
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
|
||||||
|
1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9,
|
||||||
|
2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
|
||||||
|
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
|
||||||
|
3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10,
|
||||||
|
3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11,
|
||||||
|
4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
||||||
|
4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,
|
||||||
|
5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12,
|
||||||
|
5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13,
|
||||||
|
6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
|
||||||
|
6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14,
|
||||||
|
7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14,
|
||||||
|
7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15,
|
||||||
|
8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(SLOPE_STEEP_W, {
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1,
|
||||||
|
9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1,
|
||||||
|
9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2,
|
||||||
|
10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2,
|
||||||
|
10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3,
|
||||||
|
11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3,
|
||||||
|
11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4,
|
||||||
|
12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5, 4,
|
||||||
|
12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5, 5,
|
||||||
|
13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6, 5,
|
||||||
|
13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 6,
|
||||||
|
14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6,
|
||||||
|
14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7,
|
||||||
|
15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7,
|
||||||
|
15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8}));
|
||||||
|
|
||||||
|
/* Half tile on top of steep slopes. */
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_STEEP_N, CORNER_N), {
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4,
|
||||||
|
16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3,
|
||||||
|
16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3,
|
||||||
|
16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2,
|
||||||
|
16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2,
|
||||||
|
16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1,
|
||||||
|
16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_STEEP_E, CORNER_E), {
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16,
|
||||||
|
3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16,
|
||||||
|
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16,
|
||||||
|
2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16,
|
||||||
|
1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16,
|
||||||
|
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_STEEP_S, CORNER_S), {
|
||||||
|
0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
|
||||||
|
1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16,
|
||||||
|
1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16,
|
||||||
|
2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16,
|
||||||
|
2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16,
|
||||||
|
3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16,
|
||||||
|
3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16,
|
||||||
|
4, 4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
4, 5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
5, 5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
5, 6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
6, 6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
6, 7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
7, 7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
7, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||||
|
8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}));
|
||||||
|
|
||||||
|
static_assert(CheckPartialPixelZ(HalftileSlope(SLOPE_STEEP_W, CORNER_W), {
|
||||||
|
8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
|
||||||
|
16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1,
|
||||||
|
16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1,
|
||||||
|
16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2,
|
||||||
|
16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2,
|
||||||
|
16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3,
|
||||||
|
16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4, 4,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5, 4,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5, 5,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6, 5,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6, 6,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7, 6,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7, 7,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8, 7,
|
||||||
|
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 8}));
|
@@ -81,7 +81,20 @@ struct DrawTileProcParams {
|
|||||||
* @param ti Information about the tile to draw
|
* @param ti Information about the tile to draw
|
||||||
*/
|
*/
|
||||||
typedef void DrawTileProc(TileInfo *ti, DrawTileProcParams params);
|
typedef void DrawTileProc(TileInfo *ti, DrawTileProcParams params);
|
||||||
typedef int GetSlopeZProc(TileIndex tile, uint x, uint y);
|
|
||||||
|
/**
|
||||||
|
* Tile callback function signature for obtaining the world \c Z coordinate of a given
|
||||||
|
* point of a tile.
|
||||||
|
*
|
||||||
|
* @param tile The queries tile for the Z coordinate.
|
||||||
|
* @param x World X coordinate in tile "units".
|
||||||
|
* @param y World Y coordinate in tile "units".
|
||||||
|
* @param ground_vehicle Whether to get the Z coordinate of the ground vehicle, or the ground.
|
||||||
|
* @return World Z coordinate at tile ground (vehicle) level, including slopes and foundations.
|
||||||
|
* @see GetSlopePixelZ
|
||||||
|
*/
|
||||||
|
typedef int GetSlopeZProc(TileIndex tile, uint x, uint y, bool ground_vehicle);
|
||||||
|
|
||||||
typedef CommandCost ClearTileProc(TileIndex tile, DoCommandFlag flags);
|
typedef CommandCost ClearTileProc(TileIndex tile, DoCommandFlag flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -413,7 +413,7 @@ void DrawHouseImage(HouseID house_id, int left, int top, int right, int bottom)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetSlopePixelZ_Town(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Town(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
return GetTileMaxPixelZ(tile);
|
return GetTileMaxPixelZ(tile);
|
||||||
}
|
}
|
||||||
|
@@ -1462,7 +1462,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const
|
|||||||
|
|
||||||
v->x_pos = x;
|
v->x_pos = x;
|
||||||
v->y_pos = y;
|
v->y_pos = y;
|
||||||
v->z_pos = GetSlopePixelZ(x, y);
|
v->z_pos = GetSlopePixelZ(x, y, true);
|
||||||
v->owner = _current_company;
|
v->owner = _current_company;
|
||||||
v->track = TRACK_BIT_DEPOT;
|
v->track = TRACK_BIT_DEPOT;
|
||||||
v->vehstatus = VS_HIDDEN | VS_DEFPAL;
|
v->vehstatus = VS_HIDDEN | VS_DEFPAL;
|
||||||
@@ -1602,7 +1602,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engin
|
|||||||
v->owner = _current_company;
|
v->owner = _current_company;
|
||||||
v->x_pos = x;
|
v->x_pos = x;
|
||||||
v->y_pos = y;
|
v->y_pos = y;
|
||||||
v->z_pos = GetSlopePixelZ(x, y);
|
v->z_pos = GetSlopePixelZ(x, y, true);
|
||||||
v->track = TRACK_BIT_DEPOT;
|
v->track = TRACK_BIT_DEPOT;
|
||||||
SetBit(v->flags, VRF_CONSIST_SPEED_REDUCTION);
|
SetBit(v->flags, VRF_CONSIST_SPEED_REDUCTION);
|
||||||
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
|
v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
|
||||||
@@ -5778,7 +5778,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
|
|||||||
|
|
||||||
if (v->IsFrontEngine()) {
|
if (v->IsFrontEngine()) {
|
||||||
/* Check if track in front is free and see if we can leave wormhole. */
|
/* Check if track in front is free and see if we can leave wormhole. */
|
||||||
int z = GetSlopePixelZ(gp.x, gp.y) - v->z_pos;
|
int z = GetSlopePixelZ(gp.x, gp.y, true) - v->z_pos;
|
||||||
if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && !(abs(z) > 2)) {
|
if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && !(abs(z) > 2)) {
|
||||||
if (CheckTrainStayInWormHole(v, gp.new_tile)) {
|
if (CheckTrainStayInWormHole(v, gp.new_tile)) {
|
||||||
v->cur_speed = 0;
|
v->cur_speed = 0;
|
||||||
|
@@ -788,7 +788,7 @@ static void DrawTile_Trees(TileInfo *ti, DrawTileProcParams params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int GetSlopePixelZ_Trees(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Trees(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
int z;
|
int z;
|
||||||
Slope tileh = GetTilePixelSlope(tile, &z);
|
Slope tileh = GetTilePixelSlope(tile, &z);
|
||||||
|
@@ -2563,7 +2563,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int GetSlopePixelZ_TunnelBridge(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_TunnelBridge(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
int z;
|
int z;
|
||||||
Slope tileh = GetTilePixelSlope(tile, &z);
|
Slope tileh = GetTilePixelSlope(tile, &z);
|
||||||
@@ -2572,34 +2572,27 @@ static int GetSlopePixelZ_TunnelBridge(TileIndex tile, uint x, uint y)
|
|||||||
y &= 0xF;
|
y &= 0xF;
|
||||||
|
|
||||||
if (IsTunnel(tile)) {
|
if (IsTunnel(tile)) {
|
||||||
uint pos = (DiagDirToAxis(GetTunnelBridgeDirection(tile)) == AXIS_X ? y : x);
|
|
||||||
|
|
||||||
/* In the tunnel entrance? */
|
/* In the tunnel entrance? */
|
||||||
if (5 <= pos && pos <= 10) return z;
|
if (ground_vehicle) return z;
|
||||||
} else { // IsBridge(tile)
|
} else { // IsBridge(tile)
|
||||||
if (IsCustomBridgeHeadTile(tile)) {
|
if (IsCustomBridgeHeadTile(tile)) {
|
||||||
return z + TILE_HEIGHT + (IsSteepSlope(tileh) ? TILE_HEIGHT : 0);
|
return z + TILE_HEIGHT + (IsSteepSlope(tileh) ? TILE_HEIGHT : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DiagDirection dir = GetTunnelBridgeDirection(tile);
|
DiagDirection dir = GetTunnelBridgeDirection(tile);
|
||||||
uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
|
|
||||||
|
|
||||||
z += ApplyPixelFoundationToSlope(GetBridgeFoundation(tileh, DiagDirToAxis(dir)), &tileh);
|
z += ApplyPixelFoundationToSlope(GetBridgeFoundation(tileh, DiagDirToAxis(dir)), &tileh);
|
||||||
|
|
||||||
/* On the bridge ramp? */
|
/* On the bridge ramp? */
|
||||||
if (5 <= pos && pos <= 10) {
|
if (ground_vehicle) {
|
||||||
int delta;
|
|
||||||
|
|
||||||
if (tileh != SLOPE_FLAT) return z + TILE_HEIGHT;
|
if (tileh != SLOPE_FLAT) return z + TILE_HEIGHT;
|
||||||
|
|
||||||
switch (dir) {
|
switch (dir) {
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
|
case DIAGDIR_NE: tileh = SLOPE_NE; break;
|
||||||
case DIAGDIR_SE: delta = y / 2; break;
|
case DIAGDIR_SE: tileh = SLOPE_SE; break;
|
||||||
case DIAGDIR_SW: delta = x / 2; break;
|
case DIAGDIR_SW: tileh = SLOPE_SW; break;
|
||||||
case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
|
case DIAGDIR_NW: tileh = SLOPE_NW; break;
|
||||||
}
|
}
|
||||||
return z + 1 + delta;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3063,6 +3056,29 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to prepare the ground vehicle when entering a bridge. This get called
|
||||||
|
* when entering the bridge, at the last frame of travel on the bridge head.
|
||||||
|
* Our calling function gets called before UpdateInclination/UpdateZPosition,
|
||||||
|
* which normally controls the Z-coordinate. However, in the wormhole of the
|
||||||
|
* bridge the vehicle is in a strange state so UpdateInclination does not get
|
||||||
|
* called for the wormhole of the bridge and as such the going up/down bits
|
||||||
|
* would remain set. As such, this function clears those. In doing so, the call
|
||||||
|
* to UpdateInclination will not update the Z-coordinate, so that has to be
|
||||||
|
* done here as well.
|
||||||
|
* @param gv The ground vehicle entering the bridge.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
static void PrepareToEnterBridge(T *gv)
|
||||||
|
{
|
||||||
|
if (HasBit(gv->gv_flags, GVF_GOINGUP_BIT)) {
|
||||||
|
gv->z_pos++;
|
||||||
|
ClrBit(gv->gv_flags, GVF_GOINGUP_BIT);
|
||||||
|
} else {
|
||||||
|
ClrBit(gv->gv_flags, GVF_GOINGDOWN_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frame when the 'enter tunnel' sound should be played. This is the second
|
* Frame when the 'enter tunnel' sound should be played. This is the second
|
||||||
* frame on a tile, so the sound is played shortly after entering the tunnel
|
* frame on a tile, so the sound is played shortly after entering the tunnel
|
||||||
@@ -3098,7 +3114,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
|
|||||||
y += offset.y;
|
y += offset.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int z = GetSlopePixelZ(x, y) - v->z_pos;
|
int z = GetSlopePixelZ(x, y, true) - v->z_pos;
|
||||||
|
|
||||||
if (abs(z) > 2) return VETSB_CANNOT_ENTER;
|
if (abs(z) > 2) return VETSB_CANNOT_ENTER;
|
||||||
|
|
||||||
@@ -3188,8 +3204,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
|
|||||||
Train *t = Train::From(v);
|
Train *t = Train::From(v);
|
||||||
t->track = TRACK_BIT_WORMHOLE;
|
t->track = TRACK_BIT_WORMHOLE;
|
||||||
SetBit(t->First()->flags, VRF_CONSIST_SPEED_REDUCTION);
|
SetBit(t->First()->flags, VRF_CONSIST_SPEED_REDUCTION);
|
||||||
ClrBit(t->gv_flags, GVF_GOINGUP_BIT);
|
PrepareToEnterBridge(t);
|
||||||
ClrBit(t->gv_flags, GVF_GOINGDOWN_BIT);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3205,9 +3220,7 @@ static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex ti
|
|||||||
}
|
}
|
||||||
rv->InvalidateImageCache();
|
rv->InvalidateImageCache();
|
||||||
rv->state = RVSB_WORMHOLE;
|
rv->state = RVSB_WORMHOLE;
|
||||||
/* There are no slopes inside bridges / tunnels. */
|
PrepareToEnterBridge(rv);
|
||||||
ClrBit(rv->gv_flags, GVF_GOINGUP_BIT);
|
|
||||||
ClrBit(rv->gv_flags, GVF_GOINGDOWN_BIT);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,7 +25,7 @@ static void DrawTile_Void(TileInfo *ti, DrawTileProcParams params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int GetSlopePixelZ_Void(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Void(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
/* This function may be called on tiles outside the map, don't assume
|
/* This function may be called on tiles outside the map, don't assume
|
||||||
* that 'tile' is a valid tile index. See GetSlopePixelZOutsideMap. */
|
* that 'tile' is a valid tile index. See GetSlopePixelZOutsideMap. */
|
||||||
|
@@ -997,7 +997,7 @@ void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int GetSlopePixelZ_Water(TileIndex tile, uint x, uint y)
|
static int GetSlopePixelZ_Water(TileIndex tile, uint x, uint y, bool ground_vehicle)
|
||||||
{
|
{
|
||||||
int z;
|
int z;
|
||||||
Slope tileh = GetTilePixelSlope(tile, &z);
|
Slope tileh = GetTilePixelSlope(tile, &z);
|
||||||
|
Reference in New Issue
Block a user