Fix: Don't allow right-click to close world generation progress window. (#13084)
[openttd-github.git] / src / tile_map.h
blob6fbb3a53fa17b909d750c66c5b0b5f4e36a501ef
1 /*
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/>.
6 */
8 /** @file tile_map.h Map writing/reading functions for tiles. */
10 #ifndef TILE_MAP_H
11 #define TILE_MAP_H
13 #include "slope_type.h"
14 #include "map_func.h"
15 #include "core/bitmath_func.hpp"
16 #include "settings_type.h"
18 /**
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());
32 return tile.height();
35 /**
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())));
47 /**
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;
64 /**
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;
77 /**
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;
89 /**
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
246 * @param t the tile
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));
253 return t.m7();
257 * Set a new animation frame
258 * @param t the tile
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));
265 t.m7() = frame;
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)
326 uint hash = x >> 4;
327 hash ^= x >> 6;
328 hash ^= y >> 4;
329 hash -= y >> 6;
330 return hash;
334 * Get the last two bits of the TileHash
335 * from a tile position.
337 * @see TileHash()
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 */