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.h Map writing/reading functions for tiles. */
13 #include "slope_type.h"
15 #include "core/bitmath_func.hpp"
16 #include "settings_type.h"
19 * Returns the height of a tile
21 * This function returns the height of the northern corner of a tile.
22 * This is saved in the global map-array. It does not take affect by
23 * any slope-data of the tile.
25 * @param tile The tile to get the height from
26 * @return the height of the tile
27 * @pre tile < Map::Size()
29 debug_inline
static uint
TileHeight(Tile tile
)
31 assert(tile
< Map::Size());
36 * Returns the height of a tile, also for tiles outside the map (virtual "black" tiles).
38 * @param x X coordinate of the tile, may be outside the map.
39 * @param y Y coordinate of the tile, may be outside the map.
40 * @return The height in the same unit as TileHeight.
42 inline uint
TileHeightOutsideMap(int x
, int y
)
44 return TileHeight(TileXY(Clamp(x
, 0, Map::MaxX()), Clamp(y
, 0, Map::MaxY())));
48 * Sets the height of a tile.
50 * This function sets the height of the northern corner of a tile.
52 * @param tile The tile to change the height
53 * @param height The new height value of the tile
54 * @pre tile < Map::Size()
55 * @pre height <= MAX_TILE_HEIGHT
57 inline void SetTileHeight(Tile tile
, uint height
)
59 assert(tile
< Map::Size());
60 assert(height
<= MAX_TILE_HEIGHT
);
61 tile
.height() = height
;
65 * Returns the height of a tile in pixels.
67 * This function returns the height of the northern corner of a tile in pixels.
69 * @param tile The tile to get the height
70 * @return The height of the tile in pixel
72 inline uint
TilePixelHeight(Tile tile
)
74 return TileHeight(tile
) * TILE_HEIGHT
;
78 * Returns the height of a tile in pixels, also for tiles outside the map (virtual "black" tiles).
80 * @param x X coordinate of the tile, may be outside the map.
81 * @param y Y coordinate of the tile, may be outside the map.
82 * @return The height in pixels in the same unit as TilePixelHeight.
84 inline uint
TilePixelHeightOutsideMap(int x
, int y
)
86 return TileHeightOutsideMap(x
, y
) * TILE_HEIGHT
;
90 * Get the tiletype of a given tile.
92 * @param tile The tile to get the TileType
93 * @return The tiletype of the tile
94 * @pre tile < Map::Size()
96 debug_inline
static TileType
GetTileType(Tile tile
)
98 assert(tile
< Map::Size());
99 return (TileType
)GB(tile
.type(), 4, 4);
103 * Check if a tile is within the map (not a border)
105 * @param tile The tile to check
106 * @return Whether the tile is in the interior of the map
107 * @pre tile < Map::Size()
109 inline bool IsInnerTile(Tile tile
)
111 assert(tile
< Map::Size());
113 uint x
= TileX(tile
);
114 uint y
= TileY(tile
);
116 return x
< Map::MaxX() && y
< Map::MaxY() && ((x
> 0 && y
> 0) || !_settings_game
.construction
.freeform_edges
);
120 * Set the type of a tile
122 * This functions sets the type of a tile. If the type
123 * MP_VOID is selected the tile must be at the south-west or
124 * south-east edges of the map and vice versa.
126 * @param tile The tile to save the new type
127 * @param type The type to save
128 * @pre tile < Map::Size()
129 * @pre type MP_VOID <=> tile is on the south-east or south-west edge.
131 inline void SetTileType(Tile tile
, TileType type
)
133 assert(tile
< Map::Size());
134 /* VOID tiles (and no others) are exactly allowed at the lower left and right
135 * edges of the map. If _settings_game.construction.freeform_edges is true,
136 * the upper edges of the map are also VOID tiles. */
137 assert(IsInnerTile(tile
) == (type
!= MP_VOID
));
138 SB(tile
.type(), 4, 4, type
);
142 * Checks if a tile is a given tiletype.
144 * This function checks if a tile has the given tiletype.
146 * @param tile The tile to check
147 * @param type The type to check against
148 * @return true If the type matches against the type of the tile
150 debug_inline
static bool IsTileType(Tile tile
, TileType type
)
152 return GetTileType(tile
) == type
;
156 * Checks if a tile is valid
158 * @param tile The tile to check
159 * @return True if the tile is on the map and not one of MP_VOID.
161 inline bool IsValidTile(Tile tile
)
163 return tile
< Map::Size() && !IsTileType(tile
, MP_VOID
);
167 * Returns the owner of a tile
169 * This function returns the owner of a tile. This cannot used
170 * for tiles which type is one of MP_HOUSE, MP_VOID and MP_INDUSTRY
171 * as no company owned any of these buildings.
173 * @param tile The tile to check
174 * @return The owner of the tile
175 * @pre IsValidTile(tile)
176 * @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY
178 inline Owner
GetTileOwner(Tile tile
)
180 assert(IsValidTile(tile
));
181 assert(!IsTileType(tile
, MP_HOUSE
));
182 assert(!IsTileType(tile
, MP_INDUSTRY
));
184 return (Owner
)GB(tile
.m1(), 0, 5);
188 * Sets the owner of a tile
190 * This function sets the owner status of a tile. Note that you cannot
191 * set a owner for tiles of type MP_HOUSE, MP_VOID and MP_INDUSTRY.
193 * @param tile The tile to change the owner status.
194 * @param owner The new owner.
195 * @pre IsValidTile(tile)
196 * @pre The type of the tile must not be MP_HOUSE and MP_INDUSTRY
198 inline void SetTileOwner(Tile tile
, Owner owner
)
200 assert(IsValidTile(tile
));
201 assert(!IsTileType(tile
, MP_HOUSE
));
202 assert(!IsTileType(tile
, MP_INDUSTRY
));
204 SB(tile
.m1(), 0, 5, owner
);
208 * Checks if a tile belongs to the given owner
210 * @param tile The tile to check
211 * @param owner The owner to check against
212 * @return True if a tile belongs the the given owner
214 inline bool IsTileOwner(Tile tile
, Owner owner
)
216 return GetTileOwner(tile
) == owner
;
220 * Set the tropic zone
221 * @param tile the tile to set the zone of
222 * @param type the new type
223 * @pre tile < Map::Size()
225 inline void SetTropicZone(Tile tile
, TropicZone type
)
227 assert(tile
< Map::Size());
228 assert(!IsTileType(tile
, MP_VOID
) || type
== TROPICZONE_NORMAL
);
229 SB(tile
.type(), 0, 2, type
);
233 * Get the tropic zone
234 * @param tile the tile to get the zone of
235 * @pre tile < Map::Size()
236 * @return the zone type
238 inline TropicZone
GetTropicZone(Tile tile
)
240 assert(tile
< Map::Size());
241 return (TropicZone
)GB(tile
.type(), 0, 2);
245 * Get the current animation frame
247 * @pre IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_STATION)
248 * @return frame number
250 inline uint8_t GetAnimationFrame(Tile t
)
252 assert(IsTileType(t
, MP_HOUSE
) || IsTileType(t
, MP_OBJECT
) || IsTileType(t
, MP_INDUSTRY
) || IsTileType(t
, MP_STATION
));
257 * Set a new animation frame
259 * @param frame the new frame number
260 * @pre IsTileType(t, MP_HOUSE) || IsTileType(t, MP_OBJECT) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_STATION)
262 inline void SetAnimationFrame(Tile t
, uint8_t frame
)
264 assert(IsTileType(t
, MP_HOUSE
) || IsTileType(t
, MP_OBJECT
) || IsTileType(t
, MP_INDUSTRY
) || IsTileType(t
, MP_STATION
));
268 std::tuple
<Slope
, int> GetTileSlopeZ(TileIndex tile
);
269 int GetTileZ(TileIndex tile
);
270 int GetTileMaxZ(TileIndex tile
);
272 bool IsTileFlat(TileIndex tile
, int *h
= nullptr);
275 * Return the slope of a given tile inside the map.
276 * @param tile Tile to compute slope of
277 * @return Slope of the tile, except for the HALFTILE part
279 inline Slope
GetTileSlope(TileIndex tile
)
281 return std::get
<0>(GetTileSlopeZ(tile
));
285 * Return the slope of a given tile
286 * @param tile Tile to compute slope of
287 * @return Slope of the tile, except for the HALFTILE part, and the z height.
289 inline std::tuple
<Slope
, int> GetTilePixelSlope(TileIndex tile
)
291 auto [s
, h
] = GetTileSlopeZ(tile
);
292 return {s
, h
* TILE_HEIGHT
};
295 std::tuple
<Slope
, int> GetTilePixelSlopeOutsideMap(int x
, int y
);
298 * Get bottom height of the tile
299 * @param tile Tile to compute height of
300 * @return Minimum height of the tile
302 inline int GetTilePixelZ(TileIndex tile
)
304 return GetTileZ(tile
) * TILE_HEIGHT
;
308 * Get top height of the tile
309 * @param tile Tile to compute height of
310 * @return Maximum height of the tile
312 inline int GetTileMaxPixelZ(TileIndex tile
)
314 return GetTileMaxZ(tile
) * TILE_HEIGHT
;
318 * Calculate a hash value from a tile position
320 * @param x The X coordinate
321 * @param y The Y coordinate
322 * @return The hash of the tile
324 inline uint
TileHash(uint x
, uint y
)
334 * Get the last two bits of the TileHash
335 * from a tile position.
338 * @param x The X coordinate
339 * @param y The Y coordinate
340 * @return The last two bits from hash of the tile
342 inline uint
TileHash2Bit(uint x
, uint y
)
344 return GB(TileHash(x
, y
), 0, 2);
347 #endif /* TILE_MAP_H */