2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
8 /** @file tile_map.cpp Global tile accessors. */
13 #include "safeguards.h"
16 * Get a tile's slope given the heigh of its four corners.
17 * @param hnorth The height at the northern corner in the same unit as TileHeight.
18 * @param hwest The height at the western corner in the same unit as TileHeight.
19 * @param heast The height at the eastern corner in the same unit as TileHeight.
20 * @param hsouth The height at the southern corner in the same unit as TileHeight.
21 * @param[out] h The lowest height of the four corners.
24 static Slope
GetTileSlopeGivenHeight(int hnorth
, int hwest
, int heast
, int hsouth
, int *h
)
26 /* Due to the fact that tiles must connect with each other without leaving gaps, the
27 * biggest difference in height between any corner and 'min' is between 0, 1, or 2.
29 * Also, there is at most 1 corner with height difference of 2.
31 int hminnw
= std::min(hnorth
, hwest
);
32 int hmines
= std::min(heast
, hsouth
);
33 int hmin
= std::min(hminnw
, hmines
);
35 if (h
!= nullptr) *h
= hmin
;
37 int hmaxnw
= std::max(hnorth
, hwest
);
38 int hmaxes
= std::max(heast
, hsouth
);
39 int hmax
= std::max(hmaxnw
, hmaxes
);
43 if (hnorth
!= hmin
) r
|= SLOPE_N
;
44 if (hwest
!= hmin
) r
|= SLOPE_W
;
45 if (heast
!= hmin
) r
|= SLOPE_E
;
46 if (hsouth
!= hmin
) r
|= SLOPE_S
;
48 if (hmax
- hmin
== 2) r
|= SLOPE_STEEP
;
54 * Return the slope of a given tile inside the map.
55 * @param tile Tile to compute slope of
56 * @param h If not \c nullptr, pointer to storage of z height
57 * @return Slope of the tile, except for the HALFTILE part
59 Slope
GetTileSlope(TileIndex tile
, int *h
)
61 uint x1
= TileX(tile
);
62 uint y1
= TileY(tile
);
63 uint x2
= std::min(x1
+ 1, MapMaxX());
64 uint y2
= std::min(y1
+ 1, MapMaxY());
66 int hnorth
= TileHeight(tile
); // Height of the North corner.
67 int hwest
= TileHeight(TileXY(x2
, y1
)); // Height of the West corner.
68 int heast
= TileHeight(TileXY(x1
, y2
)); // Height of the East corner.
69 int hsouth
= TileHeight(TileXY(x2
, y2
)); // Height of the South corner.
71 return GetTileSlopeGivenHeight(hnorth
, hwest
, heast
, hsouth
, h
);
75 * Return the slope of a given tile, also for tiles outside the map (virtual "black" tiles).
77 * @param x X coordinate of the tile to compute slope of, may be outside the map.
78 * @param y Y coordinate of the tile to compute slope of, may be outside the map.
79 * @param h If not \c nullptr, pointer to storage of z height.
80 * @return Slope of the tile, except for the HALFTILE part.
82 Slope
GetTilePixelSlopeOutsideMap(int x
, int y
, int *h
)
84 int hnorth
= TileHeightOutsideMap(x
, y
); // N corner.
85 int hwest
= TileHeightOutsideMap(x
+ 1, y
); // W corner.
86 int heast
= TileHeightOutsideMap(x
, y
+ 1); // E corner.
87 int hsouth
= TileHeightOutsideMap(x
+ 1, y
+ 1); // S corner.
89 Slope s
= GetTileSlopeGivenHeight(hnorth
, hwest
, heast
, hsouth
, h
);
90 if (h
!= nullptr) *h
*= TILE_HEIGHT
;
95 * Check if a given tile is flat
96 * @param tile Tile to check
97 * @param h If not \c nullptr, pointer to storage of z height (only if tile is flat)
98 * @return Whether the tile is flat
100 bool IsTileFlat(TileIndex tile
, int *h
)
102 uint x1
= TileX(tile
);
103 uint y1
= TileY(tile
);
104 uint x2
= std::min(x1
+ 1, MapMaxX());
105 uint y2
= std::min(y1
+ 1, MapMaxY());
107 uint z
= TileHeight(tile
);
108 if (TileHeight(TileXY(x2
, y1
)) != z
) return false;
109 if (TileHeight(TileXY(x1
, y2
)) != z
) return false;
110 if (TileHeight(TileXY(x2
, y2
)) != z
) return false;
112 if (h
!= nullptr) *h
= z
;
117 * Get bottom height of the tile
118 * @param tile Tile to compute height of
119 * @return Minimum height of the tile
121 int GetTileZ(TileIndex tile
)
123 uint x1
= TileX(tile
);
124 uint y1
= TileY(tile
);
125 uint x2
= std::min(x1
+ 1, MapMaxX());
126 uint y2
= std::min(y1
+ 1, MapMaxY());
129 TileHeight(tile
), // N corner
130 TileHeight(TileXY(x2
, y1
)), // W corner
131 TileHeight(TileXY(x1
, y2
)), // E corner
132 TileHeight(TileXY(x2
, y2
)), // S corner
137 * Get top height of the tile inside the map.
138 * @param t Tile to compute height of
139 * @return Maximum height of the tile
141 int GetTileMaxZ(TileIndex t
)
145 uint x2
= std::min(x1
+ 1, MapMaxX());
146 uint y2
= std::min(y1
+ 1, MapMaxY());
149 TileHeight(t
), // N corner
150 TileHeight(TileXY(x2
, y1
)), // W corner
151 TileHeight(TileXY(x1
, y2
)), // E corner
152 TileHeight(TileXY(x2
, y2
)), // S corner