OpenTTD Source: src/pathfinder/water_regions.cpp Source File

OpenTTD Source 14.0-beta1

water_regions.cpp
Go to the documentation of this file.
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 */
7
10 #include "stdafx.h"
11 #include "map_func.h"
12 #include "water_regions.h"
13 #include "map_func.h"
14 #include "tilearea_type.h"
15 #include "track_func.h"
16 #include "transport_type.h"
17 #include "landscape.h"
18 #include "tunnelbridge_map.h"
19 #include "follow_track.hpp"
20 #include "ship.h"
21 #include "debug.h"
22
23 using TWaterRegionTraversabilityBits = uint16_t;
24 constexpr TWaterRegionPatchLabel FIRST_REGION_LABEL = 1;
25 constexpr TWaterRegionPatchLabel INVALID_WATER_REGION_PATCH = 0;
26
27 static_assert(sizeof(TWaterRegionTraversabilityBits) * 8 == WATER_REGION_EDGE_LENGTH);
28 static_assert(sizeof(TWaterRegionPatchLabel) == sizeof(byte)); // Important for the hash calculation.
29
30 static inline TrackBits GetWaterTracks(TileIndex tile) { return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)); }
31 static inline bool IsAqueductTile(TileIndex tile) { return IsBridgeTile(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_WATER; }
32
33 static inline int GetWaterRegionX(TileIndex tile) { return TileX(tile) / WATER_REGION_EDGE_LENGTH; }
34 static inline int GetWaterRegionY(TileIndex tile) { return TileY(tile) / WATER_REGION_EDGE_LENGTH; }
35
36 static inline int GetWaterRegionMapSizeX() { return Map::SizeX() / WATER_REGION_EDGE_LENGTH; }
37 static inline int GetWaterRegionMapSizeY() { return Map::SizeY() / WATER_REGION_EDGE_LENGTH; }
38
39 static inline TWaterRegionIndex GetWaterRegionIndex(int region_x, int region_y) { return GetWaterRegionMapSizeX() * region_y + region_x; }
40 static inline TWaterRegionIndex GetWaterRegionIndex(TileIndex tile) { return GetWaterRegionIndex(GetWaterRegionX(tile), GetWaterRegionY(tile)); }
41
48 class WaterRegion
49 {
50 private:
51 std::array<TWaterRegionTraversabilityBits, DIAGDIR_END> edge_traversability_bits{};
52 bool has_cross_region_aqueducts = false;
53 TWaterRegionPatchLabel number_of_patches = 0; // 0 = no water, 1 = one single patch of water, etc...
54 const OrthogonalTileArea tile_area;
55 std::array<TWaterRegionPatchLabel, WATER_REGION_NUMBER_OF_TILES> tile_patch_labels{};
56 bool initialized = false;
57
64 inline int GetLocalIndex(TileIndex tile) const
65 {
66 assert(this->tile_area.Contains(tile));
67 return (TileX(tile) - TileX(this->tile_area.tile)) + WATER_REGION_EDGE_LENGTH * (TileY(tile) - TileY(this->tile_area.tile));
68 }
69
70 public:
71 WaterRegion(int region_x, int region_y)
72 : tile_area(TileXY(region_x * WATER_REGION_EDGE_LENGTH, region_y * WATER_REGION_EDGE_LENGTH), WATER_REGION_EDGE_LENGTH, WATER_REGION_EDGE_LENGTH)
73 {}
74
75 OrthogonalTileIterator begin() const { return this->tile_area.begin(); }
76 OrthogonalTileIterator end() const { return this->tile_area.end(); }
77
78 bool IsInitialized() const { return this->initialized; }
79
80 void Invalidate() { this->initialized = false; }
81
89 TWaterRegionTraversabilityBits GetEdgeTraversabilityBits(DiagDirection side) const { return edge_traversability_bits[side]; }
90
95 int NumberOfPatches() const { return this->number_of_patches; }
96
100 bool HasCrossRegionAqueducts() const { return this->has_cross_region_aqueducts; }
101
107 TWaterRegionPatchLabel GetLabel(TileIndex tile) const
108 {
109 assert(this->tile_area.Contains(tile));
110 return this->tile_patch_labels[GetLocalIndex(tile)];
111 }
112
117 void ForceUpdate()
118 {
119 Debug(map, 3, "Updating water region ({},{})", GetWaterRegionX(this->tile_area.tile), GetWaterRegionY(this->tile_area.tile));
120 this->has_cross_region_aqueducts = false;
121
122 this->tile_patch_labels.fill(INVALID_WATER_REGION_PATCH);
123
124 for (const TileIndex tile : this->tile_area) {
125 if (IsAqueductTile(tile)) {
126 const TileIndex other_aqueduct_end = GetOtherBridgeEnd(tile);
127 if (!tile_area.Contains(other_aqueduct_end)) {
128 this->has_cross_region_aqueducts = true;
129 break;
130 }
131 }
132 }
133
134 TWaterRegionPatchLabel current_label = 1;
135 TWaterRegionPatchLabel highest_assigned_label = 0;
136
137 /* Perform connected component labeling. This uses a flooding algorithm that expands until no
138 * additional tiles can be added. Only tiles inside the water region are considered. */
139 for (const TileIndex start_tile : tile_area) {
140 static std::vector<TileIndex> tiles_to_check;
141 tiles_to_check.clear();
142 tiles_to_check.push_back(start_tile);
143
144 bool increase_label = false;
145 while (!tiles_to_check.empty()) {
146 const TileIndex tile = tiles_to_check.back();
147 tiles_to_check.pop_back();
148
149 const TrackdirBits valid_dirs = TrackBitsToTrackdirBits(GetWaterTracks(tile));
150 if (valid_dirs == TRACKDIR_BIT_NONE) continue;
151
152 if (this->tile_patch_labels[GetLocalIndex(tile)] != INVALID_WATER_REGION_PATCH) continue;
153
154 this->tile_patch_labels[GetLocalIndex(tile)] = current_label;
155 highest_assigned_label = current_label;
156 increase_label = true;
157
158 for (const Trackdir dir : SetTrackdirBitIterator(valid_dirs)) {
159 /* By using a TrackFollower we "play by the same rules" as the actual ship pathfinder */
160 CFollowTrackWater ft;
161 if (ft.Follow(tile, dir) && this->tile_area.Contains(ft.m_new_tile)) tiles_to_check.push_back(ft.m_new_tile);
162 }
163 }
164
165 if (increase_label) current_label++;
166 }
167
168 this->number_of_patches = highest_assigned_label;
169 this->initialized = true;
170
171 /* Calculate the traversability (whether the tile can be entered / exited) for all edges. Note that
172 * we always follow the same X and Y scanning direction, this is important for comparisons later on! */
173 this->edge_traversability_bits.fill(0);
174 const int top_x = TileX(tile_area.tile);
175 const int top_y = TileY(tile_area.tile);
176 for (int i = 0; i < WATER_REGION_EDGE_LENGTH; ++i) {
177 if (GetWaterTracks(TileXY(top_x + i, top_y)) & TRACK_BIT_3WAY_NW) SetBit(this->edge_traversability_bits[DIAGDIR_NW], i); // NW edge
178 if (GetWaterTracks(TileXY(top_x + i, top_y + WATER_REGION_EDGE_LENGTH - 1)) & TRACK_BIT_3WAY_SE) SetBit(this->edge_traversability_bits[DIAGDIR_SE], i); // SE edge
179 if (GetWaterTracks(TileXY(top_x, top_y + i)) & TRACK_BIT_3WAY_NE) SetBit(this->edge_traversability_bits[DIAGDIR_NE], i); // NE edge
180 if (GetWaterTracks(TileXY(top_x + WATER_REGION_EDGE_LENGTH - 1, top_y + i)) & TRACK_BIT_3WAY_SW) SetBit(this->edge_traversability_bits[DIAGDIR_SW], i); // SW edge
181 }
182 }
183
187 inline void UpdateIfNotInitialized()
188 {
189 if (!this->initialized) ForceUpdate();
190 }
191 };
192
193 std::vector<WaterRegion> _water_regions;
194
195 TileIndex GetTileIndexFromLocalCoordinate(int region_x, int region_y, int local_x, int local_y)
196 {
197 assert(local_x >= 0 && local_x < WATER_REGION_EDGE_LENGTH);
198 assert(local_y >= 0 && local_y < WATER_REGION_EDGE_LENGTH);
199 return TileXY(WATER_REGION_EDGE_LENGTH * region_x + local_x, WATER_REGION_EDGE_LENGTH * region_y + local_y);
200 }
201
202 TileIndex GetEdgeTileCoordinate(int region_x, int region_y, DiagDirection side, int x_or_y)
203 {
204 assert(x_or_y >= 0 && x_or_y < WATER_REGION_EDGE_LENGTH);
205 switch (side) {
206 case DIAGDIR_NE: return GetTileIndexFromLocalCoordinate(region_x, region_y, 0, x_or_y);
207 case DIAGDIR_SW: return GetTileIndexFromLocalCoordinate(region_x, region_y, WATER_REGION_EDGE_LENGTH - 1, x_or_y);
208 case DIAGDIR_NW: return GetTileIndexFromLocalCoordinate(region_x, region_y, x_or_y, 0);
209 case DIAGDIR_SE: return GetTileIndexFromLocalCoordinate(region_x, region_y, x_or_y, WATER_REGION_EDGE_LENGTH - 1);
210 default: NOT_REACHED();
211 }
212 }
213
214 WaterRegion &GetUpdatedWaterRegion(uint16_t region_x, uint16_t region_y)
215 {
216 WaterRegion &result = _water_regions[GetWaterRegionIndex(region_x, region_y)];
217 result.UpdateIfNotInitialized();
218 return result;
219 }
220
221 WaterRegion &GetUpdatedWaterRegion(TileIndex tile)
222 {
223 WaterRegion &result = _water_regions[GetWaterRegionIndex(tile)];
224 result.UpdateIfNotInitialized();
225 return result;
226 }
227
232 TWaterRegionIndex GetWaterRegionIndex(const WaterRegionDesc &water_region)
233 {
234 return GetWaterRegionIndex(water_region.x, water_region.y);
235 }
236
241 int CalculateWaterRegionPatchHash(const WaterRegionPatchDesc &water_region_patch)
242 {
243 return water_region_patch.label | GetWaterRegionIndex(water_region_patch) << 8;
244 }
245
251 TileIndex GetWaterRegionCenterTile(const WaterRegionDesc &water_region)
252 {
253 return TileXY(water_region.x * WATER_REGION_EDGE_LENGTH + (WATER_REGION_EDGE_LENGTH / 2), water_region.y * WATER_REGION_EDGE_LENGTH + (WATER_REGION_EDGE_LENGTH / 2));
254 }
255
260 WaterRegionDesc GetWaterRegionInfo(TileIndex tile)
261 {
262 return WaterRegionDesc{ GetWaterRegionX(tile), GetWaterRegionY(tile) };
263 }
264
269 WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
270 {
271 WaterRegion &region = GetUpdatedWaterRegion(tile);
272 return WaterRegionPatchDesc{ GetWaterRegionX(tile), GetWaterRegionY(tile), region.GetLabel(tile)};
273 }
274
279 void InvalidateWaterRegion(TileIndex tile)
280 {
281 const int index = GetWaterRegionIndex(tile);
282 _water_regions[index].Invalidate();
283
284 Debug(map, 3, "Invalidated water region ({},{})", GetWaterRegionX(tile), GetWaterRegionY(tile));
285 }
286
294 static inline void VisitAdjacentWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, DiagDirection side, TVisitWaterRegionPatchCallBack &func)
295 {
296 const WaterRegion &current_region = GetUpdatedWaterRegion(water_region_patch.x, water_region_patch.y);
297
298 const TileIndexDiffC offset = TileIndexDiffCByDiagDir(side);
299 const int nx = water_region_patch.x + offset.x;
300 const int ny = water_region_patch.y + offset.y;
301
302 if (nx < 0 || ny < 0 || nx >= GetWaterRegionMapSizeX() || ny >= GetWaterRegionMapSizeY()) return;
303
304 const WaterRegion &neighboring_region = GetUpdatedWaterRegion(nx, ny);
305 const DiagDirection opposite_side = ReverseDiagDir(side);
306
307 /* Indicates via which local x or y coordinates (depends on the "side" parameter) we can cross over into the adjacent region. */
308 const TWaterRegionTraversabilityBits traversability_bits = current_region.GetEdgeTraversabilityBits(side)
309 & neighboring_region.GetEdgeTraversabilityBits(opposite_side);
310 if (traversability_bits == 0) return;
311
312 if (current_region.NumberOfPatches() == 1 && neighboring_region.NumberOfPatches() == 1) {
313 func(WaterRegionPatchDesc{ nx, ny, FIRST_REGION_LABEL }); // No further checks needed because we know there is just one patch for both adjacent regions
314 return;
315 }
316
317 /* Multiple water patches can be reached from the current patch. Check each edge tile individually. */
318 static std::vector<TWaterRegionPatchLabel> unique_labels; // static and vector-instead-of-map for performance reasons
319 unique_labels.clear();
320 for (int x_or_y = 0; x_or_y < WATER_REGION_EDGE_LENGTH; ++x_or_y) {
321 if (!HasBit(traversability_bits, x_or_y)) continue;
322
323 const TileIndex current_edge_tile = GetEdgeTileCoordinate(water_region_patch.x, water_region_patch.y, side, x_or_y);
324 const TWaterRegionPatchLabel current_label = current_region.GetLabel(current_edge_tile);
325 if (current_label != water_region_patch.label) continue;
326
327 const TileIndex neighbor_edge_tile = GetEdgeTileCoordinate(nx, ny, opposite_side, x_or_y);
328 const TWaterRegionPatchLabel neighbor_label = neighboring_region.GetLabel(neighbor_edge_tile);
329 if (std::find(unique_labels.begin(), unique_labels.end(), neighbor_label) == unique_labels.end()) unique_labels.push_back(neighbor_label);
330 }
331 for (TWaterRegionPatchLabel unique_label : unique_labels) func(WaterRegionPatchDesc{ nx, ny, unique_label });
332 }
333
340 void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback)
341 {
342 const WaterRegion &current_region = GetUpdatedWaterRegion(water_region_patch.x, water_region_patch.y);
343
344 /* Visit adjacent water region patches in each cardinal direction */
345 for (DiagDirection side = DIAGDIR_BEGIN; side < DIAGDIR_END; side++) VisitAdjacentWaterRegionPatchNeighbors(water_region_patch, side, callback);
346
347 /* Visit neigboring water patches accessible via cross-region aqueducts */
348 if (current_region.HasCrossRegionAqueducts()) {
349 for (const TileIndex tile : current_region) {
350 if (GetWaterRegionPatchInfo(tile) == water_region_patch && IsAqueductTile(tile)) {
351 const TileIndex other_end_tile = GetOtherBridgeEnd(tile);
352 if (GetWaterRegionIndex(tile) != GetWaterRegionIndex(other_end_tile)) callback(GetWaterRegionPatchInfo(other_end_tile));
353 }
354 }
355 }
356 }
357
361 void AllocateWaterRegions()
362 {
363 _water_regions.clear();
364 _water_regions.reserve(static_cast<size_t>(GetWaterRegionMapSizeX()) * GetWaterRegionMapSizeY());
365
366 Debug(map, 2, "Allocating {} x {} water regions", GetWaterRegionMapSizeX(), GetWaterRegionMapSizeY());
367
368 for (int region_y = 0; region_y < GetWaterRegionMapSizeY(); region_y++) {
369 for (int region_x = 0; region_x < GetWaterRegionMapSizeX(); region_x++) {
370 _water_regions.emplace_back(region_x, region_y);
371 }
372 }
373 }
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:437
TileIndexDiffCByDiagDir
TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
Returns the TileIndexDiffC offset from a DiagDirection.
Definition: map_func.h:490
DIAGDIR_SE
@ DIAGDIR_SE
Southeast.
Definition: direction_type.h:76
transport_type.h
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
GetOtherBridgeEnd
TileIndex GetOtherBridgeEnd(TileIndex tile)
Starting at one bridge end finds the other bridge end.
Definition: bridge_map.cpp:59
TRACK_BIT_3WAY_SW
@ TRACK_BIT_3WAY_SW
"Arrow" to the south-west
Definition: track_type.h:48
WaterRegion::ForceUpdate
void ForceUpdate()
Performs the connected component labeling and other data gathering.
Definition: water_regions.cpp:117
WaterRegionPatchDesc
Describes a single interconnected patch of water within a particular water region.
Definition: water_regions.h:25
tunnelbridge_map.h
WaterRegion::UpdateIfNotInitialized
void UpdateIfNotInitialized()
Updates the patch labels and other data, but only if the region is not yet initialized.
Definition: water_regions.cpp:187
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition: direction_type.h:79
map_func.h
ship.h
WaterRegionPatchDesc::y
int y
The Y coordinate of the water region, i.e. Y=2 is the 3rd water region along the Y-axis.
Definition: water_regions.h:28
GetWaterRegionCenterTile
TileIndex GetWaterRegionCenterTile(const WaterRegionDesc &water_region)
Returns the center tile of a particular water region.
Definition: water_regions.cpp:251
TRANSPORT_WATER
@ TRANSPORT_WATER
Transport over water.
Definition: transport_type.h:29
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
DIAGDIR_NW
@ DIAGDIR_NW
Northwest.
Definition: direction_type.h:78
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
GetTileTrackStatus
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:556
OrthogonalTileIterator
Iterator to iterate over a tile area (rectangle) of the map.
Definition: tilearea_type.h:185
DIAGDIR_SW
@ DIAGDIR_SW
Southwest.
Definition: direction_type.h:77
GetWaterRegionPatchInfo
WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
Returns basic water region patch information for the provided tile.
Definition: water_regions.cpp:269
GetWaterRegionInfo
WaterRegionDesc GetWaterRegionInfo(TileIndex tile)
Returns basic water region information for the provided tile.
Definition: water_regions.cpp:260
TrackBitsToTrackdirBits
TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
Converts TrackBits to TrackdirBits while allowing both directions.
Definition: track_func.h:319
SetBitIterator
Iterable ensemble of each set bit in a value.
Definition: bitmath_func.hpp:282
WaterRegion
Represents a square section of the map of a fixed size.
Definition: water_regions.cpp:48
WaterRegion::GetLocalIndex
int GetLocalIndex(TileIndex tile) const
Returns the local index of the tile within the region.
Definition: water_regions.cpp:64
TRACKDIR_BIT_NONE
@ TRACKDIR_BIT_NONE
No track build.
Definition: track_type.h:99
OrthogonalTileArea::begin
OrthogonalTileIterator begin() const
Returns an iterator to the beginning of the tile area.
Definition: tilearea.cpp:153
ReverseDiagDir
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition: direction_func.h:118
OrthogonalTileArea
Represents the covered area of e.g.
Definition: tilearea_type.h:18
water_regions.h
IsBridgeTile
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition: bridge_map.h:35
follow_track.hpp
VisitWaterRegionPatchNeighbors
void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback)
Calls the provided callback function on all accessible water region patches in each cardinal directio...
Definition: water_regions.cpp:340
OrthogonalTileArea::end
OrthogonalTileIterator end() const
Returns an iterator to the end of the tile area.
Definition: tilearea.cpp:162
WaterRegion::GetEdgeTraversabilityBits
TWaterRegionTraversabilityBits GetEdgeTraversabilityBits(DiagDirection side) const
Returns a set of bits indicating whether an edge tile on a particular side is traversable or not.
Definition: water_regions.cpp:89
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:73
TrackStatusToTrackBits
TrackBits TrackStatusToTrackBits(TrackStatus ts)
Returns the present-track-information of a TrackStatus.
Definition: track_func.h:363
stdafx.h
WaterRegionDesc
Describes a single square water region.
Definition: water_regions.h:39
landscape.h
CalculateWaterRegionPatchHash
int CalculateWaterRegionPatchHash(const WaterRegionPatchDesc &water_region_patch)
Calculates a number that uniquely identifies the provided water region patch.
Definition: water_regions.cpp:241
WaterRegionDesc::y
int y
The Y coordinate of the water region, i.e. Y=2 is the 3rd water region along the Y-axis.
Definition: water_regions.h:42
GetWaterRegionIndex
TWaterRegionIndex GetWaterRegionIndex(const WaterRegionDesc &water_region)
Returns the index of the water region.
Definition: water_regions.cpp:232
TileIndexDiffC
A pair-construct of a TileIndexDiff.
Definition: map_type.h:31
Map::SizeX
static debug_inline uint SizeX()
Get the size of the map along the X.
Definition: map_func.h:270
tilearea_type.h
TRACK_BIT_3WAY_NE
@ TRACK_BIT_3WAY_NE
"Arrow" to the north-east
Definition: track_type.h:46
OrthogonalTileArea::tile
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:19
TRACK_BIT_3WAY_SE
@ TRACK_BIT_3WAY_SE
"Arrow" to the south-east
Definition: track_type.h:47
GetTunnelBridgeTransportType
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
Definition: tunnelbridge_map.h:39
InvalidateWaterRegion
void InvalidateWaterRegion(TileIndex tile)
Marks the water region that tile is part of as invalid.
Definition: water_regions.cpp:279
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition: direction_type.h:74
track_func.h
AllocateWaterRegions
void AllocateWaterRegions()
Allocates the appropriate amount of water regions for the current map size.
Definition: water_regions.cpp:361
CFollowTrackT::m_new_tile
TileIndex m_new_tile
the new tile (the vehicle has entered)
Definition: follow_track.hpp:43
TileIndexDiffC::y
int16_t y
The y value of the coordinate.
Definition: map_type.h:33
TrackBits
TrackBits
Allow incrementing of Track variables.
Definition: track_type.h:35
WaterRegionPatchDesc::label
TWaterRegionPatchLabel label
Unique label identifying the patch within the region.
Definition: water_regions.h:29
CFollowTrackT::Follow
bool Follow(TileIndex old_tile, Trackdir old_td)
main follower routine.
Definition: follow_track.hpp:119
TileXY
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition: map_func.h:385
WaterRegion::GetLabel
TWaterRegionPatchLabel GetLabel(TileIndex tile) const
Returns the patch label that was assigned to the tile.
Definition: water_regions.cpp:107
WaterRegionDesc::x
int x
The X coordinate of the water region, i.e. X=2 is the 3rd water region along the X-axis.
Definition: water_regions.h:41
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:67
TrackdirBits
TrackdirBits
Allow incrementing of Trackdir variables.
Definition: track_type.h:98
TileX
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:427
VisitAdjacentWaterRegionPatchNeighbors
static void VisitAdjacentWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, DiagDirection side, TVisitWaterRegionPatchCallBack &func)
Calls the provided callback function for all water region patches accessible from one particular side...
Definition: water_regions.cpp:294
DIAGDIR_NE
@ DIAGDIR_NE
Northeast, upper right on your monitor.
Definition: direction_type.h:75
TRACK_BIT_3WAY_NW
@ TRACK_BIT_3WAY_NW
"Arrow" to the north-west
Definition: track_type.h:49
WaterRegion::HasCrossRegionAqueducts
bool HasCrossRegionAqueducts() const
Definition: water_regions.cpp:100
TileIndexDiffC::x
int16_t x
The x value of the coordinate.
Definition: map_type.h:32
WaterRegion::NumberOfPatches
int NumberOfPatches() const
Definition: water_regions.cpp:95
CFollowTrackT
Track follower helper template class (can serve pathfinders and vehicle controllers).
Definition: follow_track.hpp:28
Map::SizeY
static uint SizeY()
Get the size of the map along the Y.
Definition: map_func.h:279
OrthogonalTileArea::Contains
bool Contains(TileIndex tile) const
Does this tile area contain a tile?
Definition: tilearea.cpp:104
debug.h
WaterRegionPatchDesc::x
int x
The X coordinate of the water region, i.e. X=2 is the 3rd water region along the X-axis.
Definition: water_regions.h:27
HasBit
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103