OpenTTD Source: src/pathfinder/yapf/yapf_ship.cpp Source File

OpenTTD Source 14.1

yapf_ship.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 "../../ship.h"
12 #include "../../industry.h"
13 #include "../../vehicle_func.h"
14
15 #include "yapf.hpp"
16 #include "yapf_node_ship.hpp"
17 #include "yapf_ship_regions.h"
18 #include "../water_regions.h"
19
20 #include "../../safeguards.h"
21
22 constexpr int NUMBER_OR_WATER_REGIONS_LOOKAHEAD = 4;
23 constexpr int MAX_SHIP_PF_NODES = (NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1) * WATER_REGION_NUMBER_OF_TILES * 4; // 4 possible exit dirs per tile.
24
25 constexpr int SHIP_LOST_PATH_LENGTH = 8; // The length of the (aimless) path assigned when a ship is lost.
26
27 template <class Types>
28 class CYapfDestinationTileWaterT
29 {
30 public:
31 typedef typename Types::Tpf Tpf;
32 typedef typename Types::TrackFollower TrackFollower;
33 typedef typename Types::NodeList::Titem Node;
34 typedef typename Node::Key Key;
35
36 protected:
37 TileIndex m_destTile;
38 TrackdirBits m_destTrackdirs;
39 StationID m_destStation;
40
41 bool m_has_intermediate_dest = false;
42 TileIndex m_intermediate_dest_tile;
43 WaterRegionPatchDesc m_intermediate_dest_region_patch;
44
45 public:
46 void SetDestination(const Ship *v)
47 {
48 if (v->current_order.IsType(OT_GOTO_STATION)) {
49 m_destStation = v->current_order.GetDestination();
50 m_destTile = CalcClosestStationTile(m_destStation, v->tile, STATION_DOCK);
51 m_destTrackdirs = INVALID_TRACKDIR_BIT;
52 } else {
53 m_destStation = INVALID_STATION;
54 m_destTile = v->dest_tile;
55 m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0));
56 }
57 }
58
59 void SetIntermediateDestination(const WaterRegionPatchDesc &water_region_patch)
60 {
61 m_has_intermediate_dest = true;
62 m_intermediate_dest_tile = GetWaterRegionCenterTile(water_region_patch);
63 m_intermediate_dest_region_patch = water_region_patch;
64 }
65
66 protected:
68 inline Tpf& Yapf()
69 {
70 return *static_cast<Tpf*>(this);
71 }
72
73 public:
75 inline bool PfDetectDestination(Node &n)
76 {
77 return PfDetectDestinationTile(n.m_segment_last_tile, n.m_segment_last_td);
78 }
79
80 inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
81 {
82 if (m_has_intermediate_dest) {
83 /* GetWaterRegionInfo is much faster than GetWaterRegionPatchInfo so we try that first. */
84 if (GetWaterRegionInfo(tile) != m_intermediate_dest_region_patch) return false;
85 return GetWaterRegionPatchInfo(tile) == m_intermediate_dest_region_patch;
86 }
87
88 if (m_destStation != INVALID_STATION) return IsDockingTile(tile) && IsShipDestinationTile(tile, m_destStation);
89
90 return tile == m_destTile && ((m_destTrackdirs & TrackdirToTrackdirBits(trackdir)) != TRACKDIR_BIT_NONE);
91 }
92
97 inline bool PfCalcEstimate(Node &n)
98 {
99 const TileIndex destination_tile = m_has_intermediate_dest ? m_intermediate_dest_tile : m_destTile;
100
101 static const int dg_dir_to_x_offs[] = { -1, 0, 1, 0 };
102 static const int dg_dir_to_y_offs[] = { 0, 1, 0, -1 };
103 if (PfDetectDestination(n)) {
104 n.m_estimate = n.m_cost;
105 return true;
106 }
107
108 TileIndex tile = n.m_segment_last_tile;
109 DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td);
110 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
111 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
112 int x2 = 2 * TileX(destination_tile);
113 int y2 = 2 * TileY(destination_tile);
114 int dx = abs(x1 - x2);
115 int dy = abs(y1 - y2);
116 int dmin = std::min(dx, dy);
117 int dxy = abs(dx - dy);
118 int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
119 n.m_estimate = n.m_cost + d;
120 assert(n.m_estimate >= n.m_parent->m_estimate);
121 return true;
122 }
123 };
124
126 template <class Types>
127 class CYapfFollowShipT
128 {
129 public:
130 typedef typename Types::Tpf Tpf;
131 typedef typename Types::TrackFollower TrackFollower;
132 typedef typename Types::NodeList::Titem Node;
133 typedef typename Node::Key Key;
134
135 protected:
137 inline Tpf &Yapf()
138 {
139 return *static_cast<Tpf*>(this);
140 }
141
142 std::vector<WaterRegionDesc> m_water_region_corridor;
143
144 public:
150 inline void PfFollowNode(Node &old_node)
151 {
152 TrackFollower F(Yapf().GetVehicle());
153 if (F.Follow(old_node.m_key.m_tile, old_node.m_key.m_td)) {
154 if (m_water_region_corridor.empty()
155 || std::find(m_water_region_corridor.begin(), m_water_region_corridor.end(),
156 GetWaterRegionInfo(F.m_new_tile)) != m_water_region_corridor.end()) {
157 Yapf().AddMultipleNodes(&old_node, F);
158 }
159 }
160 }
161
163 inline void RestrictSearch(const std::vector<WaterRegionPatchDesc> &path)
164 {
165 m_water_region_corridor.clear();
166 for (const WaterRegionPatchDesc &path_entry : path) m_water_region_corridor.push_back(path_entry);
167 }
168
170 inline char TransportTypeChar() const
171 {
172 return 'w';
173 }
174
176 static Trackdir GetRandomTrackdir(TrackdirBits trackdirs)
177 {
178 const int strip_amount = RandomRange(CountBits(trackdirs));
179 for (int s = 0; s < strip_amount; ++s) RemoveFirstTrackdir(&trackdirs);
180 return FindFirstTrackdir(trackdirs);
181 }
182
184 static std::pair<TileIndex, Trackdir> GetRandomFollowUpTileTrackdir(const Ship *v, TileIndex tile, Trackdir dir)
185 {
186 TrackFollower follower(v);
187 if (follower.Follow(tile, dir)) {
188 TrackdirBits dirs = follower.m_new_td_bits;
189 const TrackdirBits dirs_without_90_degree = dirs & ~TrackdirCrossesTrackdirs(dir);
190 if (dirs_without_90_degree != TRACKDIR_BIT_NONE) dirs = dirs_without_90_degree;
191 return { follower.m_new_tile, GetRandomTrackdir(dirs) };
192 }
193 return { follower.m_new_tile, INVALID_TRACKDIR };
194 }
195
197 static Trackdir CreateRandomPath(const Ship *v, ShipPathCache &path_cache, int path_length)
198 {
199 std::pair<TileIndex, Trackdir> tile_dir = { v->tile, v->GetVehicleTrackdir()};
200 for (int i = 0; i < path_length; ++i) {
201 tile_dir = GetRandomFollowUpTileTrackdir(v, tile_dir.first, tile_dir.second);
202 if (tile_dir.second == INVALID_TRACKDIR) break;
203 path_cache.push_back(tile_dir.second);
204 }
205
206 if (path_cache.empty()) return INVALID_TRACKDIR;
207
208 const Trackdir result = path_cache.front();
209 path_cache.pop_front();
210 return result;
211 }
212
213 static Trackdir ChooseShipTrack(const Ship *v, TileIndex tile, TrackdirBits forward_dirs, TrackdirBits reverse_dirs,
214 bool &path_found, ShipPathCache &path_cache, Trackdir &best_origin_dir)
215 {
216 const std::vector<WaterRegionPatchDesc> high_level_path = YapfShipFindWaterRegionPath(v, tile, NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1);
217 if (high_level_path.empty()) {
218 path_found = false;
219 /* Make the ship move around aimlessly. This prevents repeated pathfinder calls and clearly indicates that the ship is lost. */
220 return CreateRandomPath(v, path_cache, SHIP_LOST_PATH_LENGTH);
221 }
222
223 /* Try one time without restricting the search area, which generally results in better and more natural looking paths.
224 * However the pathfinder can hit the node limit in certain situations such as long aqueducts or maze-like terrain.
225 * If that happens we run the pathfinder again, but restricted only to the regions provided by the region pathfinder. */
226 for (int attempt = 0; attempt < 2; ++attempt) {
227 Tpf pf(MAX_SHIP_PF_NODES);
228
229 /* Set origin and destination nodes */
230 pf.SetOrigin(v->tile, forward_dirs | reverse_dirs);
231 pf.SetDestination(v);
232 const bool is_intermediate_destination = static_cast<int>(high_level_path.size()) >= NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1;
233 if (is_intermediate_destination) pf.SetIntermediateDestination(high_level_path.back());
234
235 /* Restrict the search area to prevent the low level pathfinder from expanding too many nodes. This can happen
236 * when the terrain is very "maze-like" or when the high level path "teleports" via a very long aqueduct. */
237 if (attempt > 0) pf.RestrictSearch(high_level_path);
238
239 /* Find best path. */
240 path_found = pf.FindPath(v);
241 Node *node = pf.GetBestNode();
242 if (attempt == 0 && !path_found) continue; // Try again with restricted search area.
243
244 /* Make the ship move around aimlessly. This prevents repeated pathfinder calls and clearly indicates that the ship is lost. */
245 if (!path_found) return CreateRandomPath(v, path_cache, SHIP_LOST_PATH_LENGTH);
246
247 /* Return only the path within the current water region if an intermediate destination was returned. If not, cache the entire path
248 * to the final destination tile. The low-level pathfinder might actually prefer a different docking tile in a nearby region. Without
249 * caching the full path the ship can get stuck in a loop. */
250 const WaterRegionPatchDesc end_water_patch = GetWaterRegionPatchInfo(node->GetTile());
251 assert(GetWaterRegionPatchInfo(tile) == high_level_path.front());
252 const WaterRegionPatchDesc start_water_patch = high_level_path.front();
253 while (node->m_parent) {
254 const WaterRegionPatchDesc node_water_patch = GetWaterRegionPatchInfo(node->GetTile());
255
256 const bool node_water_patch_on_high_level_path = std::find(high_level_path.begin(), high_level_path.end(), node_water_patch) != high_level_path.end();
257 const bool add_full_path = !is_intermediate_destination && node_water_patch != end_water_patch;
258
259 /* The cached path must always lead to a region patch that's on the high level path.
260 * This is what can happen when that's not the case https://github.com/OpenTTD/OpenTTD/issues/12176. */
261 if (add_full_path || !node_water_patch_on_high_level_path || node_water_patch == start_water_patch) {
262 path_cache.push_front(node->GetTrackdir());
263 } else {
264 path_cache.clear();
265 }
266 node = node->m_parent;
267 }
268 assert(node->GetTile() == v->tile);
269
270 /* Return INVALID_TRACKDIR to trigger a ship reversal if that is the best option. */
271 best_origin_dir = node->GetTrackdir();
272 if ((TrackdirToTrackdirBits(best_origin_dir) & forward_dirs) == TRACKDIR_BIT_NONE) {
273 path_cache.clear();
274 return INVALID_TRACKDIR;
275 }
276
277 /* A empty path means we are already at the destination. The pathfinder shouldn't have been called at all.
278 * Return a random reachable trackdir to hopefully nudge the ship out of this strange situation. */
279 if (path_cache.empty()) return CreateRandomPath(v, path_cache, 1);
280
281 /* Take out the last trackdir as the result. */
282 const Trackdir result = path_cache.front();
283 path_cache.pop_front();
284
285 /* Clear path cache when in final water region patch. This is to allow ships to spread over different docking tiles dynamically. */
286 if (start_water_patch == end_water_patch) path_cache.clear();
287
288 return result;
289 }
290
291 return INVALID_TRACKDIR;
292 }
293
301 static bool CheckShipReverse(const Ship *v, Trackdir *trackdir)
302 {
303 bool path_found = false;
304 ShipPathCache dummy_cache;
305 Trackdir best_origin_dir = INVALID_TRACKDIR;
306
307 if (trackdir == nullptr) {
308 /* The normal case, typically called when ships leave a dock. */
309 const Trackdir reverse_dir = ReverseTrackdir(v->GetVehicleTrackdir());
310 const TrackdirBits forward_dirs = TrackdirToTrackdirBits(v->GetVehicleTrackdir());
311 const TrackdirBits reverse_dirs = TrackdirToTrackdirBits(reverse_dir);
312 (void)ChooseShipTrack(v, v->tile, forward_dirs, reverse_dirs, path_found, dummy_cache, best_origin_dir);
313 return path_found && best_origin_dir == reverse_dir;
314 } else {
315 /* This gets called when a ship suddenly can't move forward, e.g. due to terraforming. */
316 const DiagDirection entry = ReverseDiagDir(VehicleExitDir(v->direction, v->state));
317 const TrackdirBits reverse_dirs = DiagdirReachesTrackdirs(entry) & TrackStatusToTrackdirBits(GetTileTrackStatus(v->tile, TRANSPORT_WATER, 0, entry));
318 (void)ChooseShipTrack(v, v->tile, TRACKDIR_BIT_NONE, reverse_dirs, path_found, dummy_cache, best_origin_dir);
319 *trackdir = path_found && best_origin_dir != INVALID_TRACKDIR ? best_origin_dir : GetRandomTrackdir(reverse_dirs);
320 return true;
321 }
322 }
323 };
324
326 template <class Types>
327 class CYapfCostShipT
328 {
329 public:
330 typedef typename Types::Tpf Tpf;
331 typedef typename Types::TrackFollower TrackFollower;
332 typedef typename Types::NodeList::Titem Node;
333 typedef typename Node::Key Key;
334
336 Tpf &Yapf()
337 {
338 return *static_cast<Tpf*>(this);
339 }
340
341 public:
342 inline int CurveCost(Trackdir td1, Trackdir td2)
343 {
344 assert(IsValidTrackdir(td1));
345 assert(IsValidTrackdir(td2));
346
347 if (HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
348 /* 90-deg curve penalty. */
349 return Yapf().PfGetSettings().ship_curve90_penalty;
350 } else if (td2 != NextTrackdir(td1)) {
351 /* 45-deg curve penalty. */
352 return Yapf().PfGetSettings().ship_curve45_penalty;
353 }
354 return 0;
355 }
356
357 static Vehicle *CountShipProc(Vehicle *v, void *data)
358 {
359 uint *count = (uint*)data;
360 /* Ignore other vehicles (aircraft) and ships inside depot. */
361 if (v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0) (*count)++;
362
363 return nullptr;
364 }
365
371 inline bool PfCalcCost(Node &n, const TrackFollower *tf)
372 {
373 /* Base tile cost depending on distance. */
374 int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH;
375 /* Additional penalty for curves. */
376 c += CurveCost(n.m_parent->GetTrackdir(), n.GetTrackdir());
377
378 if (IsDockingTile(n.GetTile())) {
379 /* Check docking tile for occupancy. */
380 uint count = 0;
381 HasVehicleOnPos(n.GetTile(), &count, &CountShipProc);
382 c += count * 3 * YAPF_TILE_LENGTH;
383 }
384
385 /* Skipped tile cost for aqueducts. */
386 c += YAPF_TILE_LENGTH * tf->m_tiles_skipped;
387
388 /* Ocean/canal speed penalty. */
389 const ShipVehicleInfo *svi = ShipVehInfo(Yapf().GetVehicle()->engine_type);
390 byte speed_frac = (GetEffectiveWaterClass(n.GetTile()) == WATER_CLASS_SEA) ? svi->ocean_speed_frac : svi->canal_speed_frac;
391 if (speed_frac > 0) c += YAPF_TILE_LENGTH * (1 + tf->m_tiles_skipped) * speed_frac / (256 - speed_frac);
392
393 /* Apply it. */
394 n.m_cost = n.m_parent->m_cost + c;
395 return true;
396 }
397 };
398
403 template <class Tpf_, class Ttrack_follower, class Tnode_list>
404 struct CYapfShip_TypesT
405 {
406 typedef CYapfShip_TypesT<Tpf_, Ttrack_follower, Tnode_list> Types;
407 typedef Tpf_ Tpf;
408 typedef Ttrack_follower TrackFollower;
409 typedef Tnode_list NodeList;
410 typedef Ship VehicleType;
411
413 typedef CYapfBaseT<Types> PfBase;
414 typedef CYapfFollowShipT<Types> PfFollow;
415 typedef CYapfOriginTileT<Types> PfOrigin;
416 typedef CYapfDestinationTileWaterT<Types> PfDestination;
417 typedef CYapfSegmentCostCacheNoneT<Types> PfCache;
418 typedef CYapfCostShipT<Types> PfCost;
419 };
420
421 struct CYapfShip : CYapfT<CYapfShip_TypesT<CYapfShip, CFollowTrackWater, CShipNodeListExitDir > >
422 {
423 explicit CYapfShip(int max_nodes) { m_max_search_nodes = max_nodes; }
424 };
425
427 Track YapfShipChooseTrack(const Ship *v, TileIndex tile, bool &path_found, ShipPathCache &path_cache)
428 {
429 Trackdir best_origin_dir = INVALID_TRACKDIR;
430 const TrackdirBits origin_dirs = TrackdirToTrackdirBits(v->GetVehicleTrackdir());
431 const Trackdir td_ret = CYapfShip::ChooseShipTrack(v, tile, origin_dirs, TRACKDIR_BIT_NONE, path_found, path_cache, best_origin_dir);
432 return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;
433 }
434
435 bool YapfShipCheckReverse(const Ship *v, Trackdir *trackdir)
436 {
437 return CYapfShip::CheckShipReverse(v, trackdir);
438 }
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:437
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:71
CYapfShip_TypesT
Config struct of YAPF for ships.
Definition: yapf_ship.cpp:404
TrackStatusToTrackdirBits
TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
Returns the present-trackdir-information of a TrackStatus.
Definition: track_func.h:352
HasVehicleOnPos
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition: vehicle.cpp:520
WaterRegionPatchDesc
Describes a single interconnected patch of water within a particular water region.
Definition: water_regions.h:26
ShipVehicleInfo::canal_speed_frac
byte canal_speed_frac
Fraction of maximum speed for canal/river tiles.
Definition: engine_type.h:78
Ship::GetVehicleTrackdir
Trackdir GetVehicleTrackdir() const override
Returns the Trackdir on which the vehicle is currently located.
Definition: ship_cmd.cpp:294
CYapfDestinationTileWaterT::PfCalcEstimate
bool PfCalcEstimate(Node &n)
Called by YAPF to calculate cost estimate.
Definition: yapf_ship.cpp:97
Order::GetDestination
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:104
TrackdirToTrack
Track TrackdirToTrack(Trackdir trackdir)
Returns the Track that a given Trackdir represents.
Definition: track_func.h:262
TrackdirToExitdir
DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition: track_func.h:439
TrackdirToTrackdirBits
TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
Maps a Trackdir to the corresponding TrackdirBits value.
Definition: track_func.h:111
yapf.hpp
CYapfDestinationTileWaterT::Key
Node::Key Key
key to hash tables.
Definition: yapf_ship.cpp:34
Vehicle::vehstatus
byte vehstatus
Status.
Definition: vehicle_base.h:349
CYapfShip_TypesT::Tpf
Tpf_ Tpf
Pathfinder type.
Definition: yapf_ship.cpp:407
YapfShipCheckReverse
bool YapfShipCheckReverse(const Ship *v, Trackdir *trackdir)
Returns true if it is better to reverse the ship before leaving depot using YAPF.
Definition: yapf_ship.cpp:435
CYapfShip_TypesT::PfFollow
CYapfFollowShipT< Types > PfFollow
Node follower.
Definition: yapf_ship.cpp:414
yapf_node_ship.hpp
FindFirstTrackdir
Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
Returns first Trackdir from TrackdirBits or INVALID_TRACKDIR.
Definition: track_func.h:211
CYapfDestinationTileWaterT::PfDetectDestination
bool PfDetectDestination(Node &n)
Called by YAPF to detect if node ends in the desired destination.
Definition: yapf_ship.cpp:75
GetEffectiveWaterClass
WaterClass GetEffectiveWaterClass(TileIndex tile)
Determine the effective WaterClass for a ship travelling on a tile.
Definition: ship_cmd.cpp:55
CYapfShip_TypesT::TrackFollower
Ttrack_follower TrackFollower
Track follower helper class.
Definition: yapf_ship.cpp:408
GetWaterRegionCenterTile
TileIndex GetWaterRegionCenterTile(const WaterRegionDesc &water_region)
Returns the center tile of a particular water region.
Definition: water_regions.cpp:288
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 > >
CYapfT
YAPF template that uses Ttypes template argument to determine all YAPF components (base classes) from...
Definition: yapf_common.hpp:183
NextTrackdir
Trackdir NextTrackdir(Trackdir trackdir)
Maps a trackdir to the trackdir that you will end up on if you go straight ahead.
Definition: track_func.h:403
CYapfDestinationTileWaterT::Node
Types::NodeList::Titem Node
this will be our node type.
Definition: yapf_ship.cpp:33
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:240
CYapfFollowShipT::RestrictSearch
void RestrictSearch(const std::vector< WaterRegionPatchDesc > &path)
Restricts the search by creating corridor or water regions through which the ship is allowed to trave...
Definition: yapf_ship.cpp:163
RandomRange
static uint32_t RandomRange(uint32_t limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:81
CYapfCostShipT::Yapf
Tpf & Yapf()
to access inherited path finder
Definition: yapf_ship.cpp:336
GetTileTrackStatus
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:556
CYapfOriginTileT
YAPF origin provider base class - used when origin is one tile / multiple trackdirs.
Definition: yapf_common.hpp:15
CYapfFollowShipT::Tpf
Types::Tpf Tpf
the pathfinder class (derived from THIS class).
Definition: yapf_ship.cpp:130
GetWaterRegionPatchInfo
WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
Returns basic water region patch information for the provided tile.
Definition: water_regions.cpp:306
VS_HIDDEN
@ VS_HIDDEN
Vehicle is not visible.
Definition: vehicle_base.h:33
CYapfDestinationTileWaterT::Yapf
Tpf & Yapf()
To access inherited path finder.
Definition: yapf_ship.cpp:68
GetWaterRegionInfo
WaterRegionDesc GetWaterRegionInfo(TileIndex tile)
Returns basic water region information for the provided tile.
Definition: water_regions.cpp:297
Vehicle::dest_tile
TileIndex dest_tile
Heading for this tile.
Definition: vehicle_base.h:267
CYapfShip_TypesT::PfCost
CYapfCostShipT< Types > PfCost
Cost provider.
Definition: yapf_ship.cpp:418
yapf_ship_regions.h
CYapfCostShipT::Tpf
Types::Tpf Tpf
the pathfinder class (derived from THIS class).
Definition: yapf_ship.cpp:330
CYapfFollowShipT::PfFollowNode
void PfFollowNode(Node &old_node)
Called by YAPF to move from the given node to the next tile.
Definition: yapf_ship.cpp:150
YAPF_TILE_LENGTH
static const int YAPF_TILE_LENGTH
Length (penalty) of one tile with YAPF.
Definition: pathfinder_type.h:29
Vehicle::tile
TileIndex tile
Current tile index.
Definition: vehicle_base.h:260
TRACKDIR_BIT_NONE
@ TRACKDIR_BIT_NONE
No track build.
Definition: track_type.h:99
ReverseDiagDir
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition: direction_func.h:118
Vehicle::current_order
Order current_order
The current order (+ status, like: loading)
Definition: vehicle_base.h:350
CYapfCostShipT::Key
Node::Key Key
key to hash tables.
Definition: yapf_ship.cpp:333
CYapfDestinationTileWaterT
Definition: yapf_ship.cpp:28
ChooseShipTrack
static Track ChooseShipTrack(Ship *v, TileIndex tile, TrackBits tracks)
Runs the pathfinder to choose a track to continue along.
Definition: ship_cmd.cpp:507
ReverseTrackdir
Trackdir ReverseTrackdir(Trackdir trackdir)
Maps a trackdir to the reverse trackdir.
Definition: track_func.h:247
DiagdirReachesTrackdirs
TrackdirBits DiagdirReachesTrackdirs(DiagDirection diagdir)
Returns all trackdirs that can be reached when entering a tile from a given (diagonal) direction.
Definition: track_func.h:555
CYapfFollowShipT::Key
Node::Key Key
key to hash tables.
Definition: yapf_ship.cpp:133
VehicleExitDir
DiagDirection VehicleExitDir(Direction direction, TrackBits track)
Determine the side in which the vehicle will leave the tile.
Definition: track_func.h:714
RemoveFirstTrackdir
Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
Removes first Trackdir from TrackdirBits and returns it.
Definition: track_func.h:156
INVALID_TRACKDIR
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition: track_type.h:86
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:73
CYapfShip_TypesT::Types
CYapfShip_TypesT< Tpf_, Ttrack_follower, Tnode_list > Types
Shortcut for this struct type.
Definition: yapf_ship.cpp:406
CountBits
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
Definition: bitmath_func.hpp:243
WATER_CLASS_SEA
@ WATER_CLASS_SEA
Sea.
Definition: water_map.h:48
Vehicle::direction
Direction direction
facing
Definition: vehicle_base.h:303
CYapfShip_TypesT::PfBase
CYapfBaseT< Types > PfBase
Pathfinder components (modules).
Definition: yapf_ship.cpp:413
CYapfSegmentCostCacheNoneT
CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements PfNodeCacheFetc...
Definition: yapf_costcache.hpp:21
Ship
All ships have this type.
Definition: ship.h:24
CYapfFollowShipT::Yapf
Tpf & Yapf()
to access inherited path finder
Definition: yapf_ship.cpp:137
IsDockingTile
bool IsDockingTile(Tile t)
Checks whether the tile is marked as a dockling tile.
Definition: water_map.h:374
YapfShipChooseTrack
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, bool &path_found, ShipPathCache &path_cache)
Ship controller helper - path finder invoker.
Definition: yapf_ship.cpp:427
abs
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:23
CYapfCostShipT::Node
Types::NodeList::Titem Node
this will be our node type.
Definition: yapf_ship.cpp:332
CalcClosestStationTile
TileIndex CalcClosestStationTile(StationID station, TileIndex tile, StationType station_type)
Calculates the tile of given station that is closest to a given tile for this we assume the station i...
Definition: pathfinder_func.h:25
CYapfFollowShipT
Node Follower module of YAPF for ships.
Definition: yapf_ship.cpp:127
Ship::state
TrackBits state
The "track" the ship is following.
Definition: ship.h:25
CYapfShip_TypesT::PfCache
CYapfSegmentCostCacheNoneT< Types > PfCache
Segment cost cache provider.
Definition: yapf_ship.cpp:417
ShipVehicleInfo
Information about a ship vehicle.
Definition: engine_type.h:67
CYapfFollowShipT::CheckShipReverse
static bool CheckShipReverse(const Ship *v, Trackdir *trackdir)
Check whether a ship should reverse to reach its destination.
Definition: yapf_ship.cpp:301
CYapfShip_TypesT::PfOrigin
CYapfOriginTileT< Types > PfOrigin
Origin provider.
Definition: yapf_ship.cpp:415
CYapfCostShipT::PfCalcCost
bool PfCalcCost(Node &n, const TrackFollower *tf)
Called by YAPF to calculate the cost from the origin to the given node.
Definition: yapf_ship.cpp:371
IsDiagonalTrackdir
bool IsDiagonalTrackdir(Trackdir trackdir)
Checks if a given Trackdir is diagonal.
Definition: track_func.h:631
CYapfFollowShipT::GetRandomFollowUpTileTrackdir
static std::pair< TileIndex, Trackdir > GetRandomFollowUpTileTrackdir(const Ship *v, TileIndex tile, Trackdir dir)
Returns a random tile/trackdir that can be reached from the current tile/trackdir,...
Definition: yapf_ship.cpp:184
CYapfFollowShipT::CreateRandomPath
static Trackdir CreateRandomPath(const Ship *v, ShipPathCache &path_cache, int path_length)
Creates a random path, avoids 90 degree turns.
Definition: yapf_ship.cpp:197
CYapfCostShipT
Cost Provider module of YAPF for ships.
Definition: yapf_ship.cpp:327
YapfShipFindWaterRegionPath
std::vector< WaterRegionPatchDesc > YapfShipFindWaterRegionPath(const Ship *v, TileIndex start_tile, int max_returned_path_length)
Finds a path at the water region level.
Definition: yapf_ship_regions.cpp:310
YAPF_TILE_CORNER_LENGTH
static const int YAPF_TILE_CORNER_LENGTH
Length (penalty) of a corner with YAPF.
Definition: pathfinder_type.h:32
IsShipDestinationTile
bool IsShipDestinationTile(TileIndex tile, StationID station)
Test if a tile is a docking tile for the given station.
Definition: ship_cmd.cpp:663
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:67
CYapfBaseT
CYapfBaseT - A-star type path finder base class.
Definition: yapf_base.hpp:47
CYapfDestinationTileWaterT::Tpf
Types::Tpf Tpf
the pathfinder class (derived from THIS class).
Definition: yapf_ship.cpp:31
TrackdirCrossesTrackdirs
TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir)
Maps a trackdir to all trackdirs that make 90 deg turns with it.
Definition: track_func.h:606
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:51
LinkGraph::BaseNode
Node of the link graph.
Definition: linkgraph.h:90
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
CYapfShip_TypesT::PfDestination
CYapfDestinationTileWaterT< Types > PfDestination
Destination/distance provider.
Definition: yapf_ship.cpp:416
Track
Track
These are used to specify a single track.
Definition: track_type.h:19
HasTrackdir
bool HasTrackdir(TrackdirBits trackdirs, Trackdir trackdir)
Checks whether a TrackdirBits has a given Trackdir.
Definition: track_func.h:340
IsValidTrackdir
bool IsValidTrackdir(Trackdir trackdir)
Checks if a Trackdir is valid for non-road vehicles.
Definition: track_func.h:52
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
CYapfShip
Definition: yapf_ship.cpp:421
CYapfFollowShipT::Node
Types::NodeList::Titem Node
this will be our node type.
Definition: yapf_ship.cpp:132
Vehicle::first
Vehicle * first
NOSAVE: pointer to the first vehicle in the chain.
Definition: vehicle_base.h:246
CYapfFollowShipT::GetRandomTrackdir
static Trackdir GetRandomTrackdir(TrackdirBits trackdirs)
Returns a random trackdir out of a set of trackdirs.
Definition: yapf_ship.cpp:176
INVALID_TRACKDIR_BIT
@ INVALID_TRACKDIR_BIT
Flag for an invalid trackdirbit value.
Definition: track_type.h:114
CYapfFollowShipT::TransportTypeChar
char TransportTypeChar() const
Return debug report character to identify the transportation type.
Definition: yapf_ship.cpp:170
ShipVehicleInfo::ocean_speed_frac
byte ocean_speed_frac
Fraction of maximum speed for ocean tiles.
Definition: engine_type.h:77
INVALID_TRACK
@ INVALID_TRACK
Flag for an invalid track.
Definition: track_type.h:28