OpenTTD Source  20241121-master-g67a0fccfad
yapf_destrail.hpp
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 #ifndef YAPF_DESTRAIL_HPP
11 #define YAPF_DESTRAIL_HPP
12 
13 #include "../../train.h"
14 #include "../pathfinder_func.h"
15 #include "../pathfinder_type.h"
16 
18 protected:
19  RailTypes compatible_railtypes;
20 
21 public:
22  void SetDestination(const Train *v, bool override_rail_type = false)
23  {
24  this->compatible_railtypes = v->compatible_railtypes;
25  if (override_rail_type) this->compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
26  }
27 
28  bool IsCompatibleRailType(RailType rt)
29  {
30  return HasBit(this->compatible_railtypes, rt);
31  }
32 
33  RailTypes GetCompatibleRailTypes() const
34  {
35  return this->compatible_railtypes;
36  }
37 };
38 
39 template <class Types>
41 public:
42  typedef typename Types::Tpf Tpf;
43  typedef typename Types::NodeList::Item Node;
44  typedef typename Node::Key Key;
45 
47  Tpf &Yapf()
48  {
49  return *static_cast<Tpf *>(this);
50  }
51 
53  inline bool PfDetectDestination(Node &n)
54  {
55  return this->PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
56  }
57 
60  {
61  return IsRailDepotTile(tile);
62  }
63 
68  inline bool PfCalcEstimate(Node &n)
69  {
70  n.estimate = n.cost;
71  return true;
72  }
73 };
74 
75 template <class Types>
77 public:
78  typedef typename Types::Tpf Tpf;
79  typedef typename Types::NodeList::Item Node;
80  typedef typename Node::Key Key;
81  typedef typename Types::TrackFollower TrackFollower;
82 
84  Tpf &Yapf()
85  {
86  return *static_cast<Tpf *>(this);
87  }
88 
90  inline bool PfDetectDestination(Node &n)
91  {
92  return this->PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
93  }
94 
96  inline bool PfDetectDestination(TileIndex tile, Trackdir td)
97  {
98  return IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
99  IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
100  }
101 
106  inline bool PfCalcEstimate(Node &n)
107  {
108  n.estimate = n.cost;
109  return true;
110  }
111 };
112 
113 template <class Types>
115 public:
116  typedef typename Types::Tpf Tpf;
117  typedef typename Types::NodeList::Item Node;
118  typedef typename Node::Key Key;
119 
120 protected:
121  TileIndex dest_tile;
122  TrackdirBits dest_trackdirs;
123  StationID dest_station_id;
124  bool any_depot;
125 
128  {
129  return *static_cast<Tpf *>(this);
130  }
131 
132 public:
133  void SetDestination(const Train *v)
134  {
135  this->any_depot = false;
136  switch (v->current_order.GetType()) {
137  case OT_GOTO_WAYPOINT:
139  /* In case of 'complex' waypoints we need to do a look
140  * ahead. This look ahead messes a bit about, which
141  * means that it 'corrupts' the cache. To prevent this
142  * we disable caching when we're looking for a complex
143  * waypoint. */
144  Yapf().DisableCache(true);
145  }
146  [[fallthrough]];
147 
148  case OT_GOTO_STATION:
149  this->dest_tile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
150  this->dest_station_id = v->current_order.GetDestination();
151  this->dest_trackdirs = INVALID_TRACKDIR_BIT;
152  break;
153 
154  case OT_GOTO_DEPOT:
156  this->any_depot = true;
157  }
158  [[fallthrough]];
159 
160  default:
161  this->dest_tile = v->dest_tile;
162  this->dest_station_id = INVALID_STATION;
164  break;
165  }
166  this->CYapfDestinationRailBase::SetDestination(v);
167  }
168 
170  inline bool PfDetectDestination(Node &n)
171  {
172  return this->PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
173  }
174 
176  inline bool PfDetectDestination(TileIndex tile, Trackdir td)
177  {
178  if (this->dest_station_id != INVALID_STATION) {
179  return HasStationTileRail(tile)
180  && (GetStationIndex(tile) == this->dest_station_id)
181  && (GetRailStationTrack(tile) == TrackdirToTrack(td));
182  }
183 
184  if (this->any_depot) {
185  return IsRailDepotTile(tile);
186  }
187 
188  return (tile == this->dest_tile) && HasTrackdir(this->dest_trackdirs, td);
189  }
190 
195  inline bool PfCalcEstimate(Node &n)
196  {
197  static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
198  static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
199  if (this->PfDetectDestination(n)) {
200  n.estimate = n.cost;
201  return true;
202  }
203 
204  TileIndex tile = n.GetLastTile();
205  DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
206  int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
207  int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
208  int x2 = 2 * TileX(this->dest_tile);
209  int y2 = 2 * TileY(this->dest_tile);
210  int dx = abs(x1 - x2);
211  int dy = abs(y1 - y2);
212  int dmin = std::min(dx, dy);
213  int dxy = abs(dx - dy);
214  int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
215  n.estimate = n.cost + d;
216  assert(n.estimate >= n.parent->estimate);
217  return true;
218  }
219 };
220 
221 #endif /* YAPF_DESTRAIL_HPP */
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Types::NodeList::Item Node
this will be our node type
bool PfCalcEstimate(Node &n)
Called by YAPF to calculate cost estimate.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Node::Key Key
key to hash tables
bool PfDetectDestination(TileIndex tile, Trackdir)
Called by YAPF to detect if node ends in the desired destination.
Tpf & Yapf()
to access inherited path finder
bool PfDetectDestination(Node &n)
Called by YAPF to detect if node ends in the desired destination.
Types::TrackFollower TrackFollower
TrackFollower. Need to typedef for gcc 2.95.
bool PfDetectDestination(TileIndex tile, Trackdir td)
Called by YAPF to detect if node ends in the desired destination.
Tpf & Yapf()
to access inherited path finder
bool PfCalcEstimate(Node &n)
Called by YAPF to calculate cost estimate.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
bool PfDetectDestination(Node &n)
Called by YAPF to detect if node ends in the desired destination.
Types::NodeList::Item Node
this will be our node type
Node::Key Key
key to hash tables
Node::Key Key
key to hash tables
bool PfDetectDestination(TileIndex tile, Trackdir td)
Called by YAPF to detect if node ends in the desired destination.
bool PfDetectDestination(Node &n)
Called by YAPF to detect if node ends in the desired destination.
Types::Tpf Tpf
the pathfinder class (derived from THIS class)
Tpf & Yapf()
to access inherited path finder
Types::NodeList::Item Node
this will be our node type
bool PfCalcEstimate(Node &n)
Called by YAPF to calculate cost estimate.
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel
Definition: rail.h:191
DiagDirection
Enumeration for diagonal directions.
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:554
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:415
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:23
@ ODATFB_NEAREST_DEPOT
Send the vehicle to the nearest depot.
Definition: order_type.h:105
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...
static const int YAPF_TILE_CORNER_LENGTH
Length (penalty) of a corner with YAPF.
static const int YAPF_TILE_LENGTH
Length (penalty) of one tile with YAPF.
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg)
Check if a safe position is free.
Definition: pbs.cpp:426
bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg)
Determine whether a certain track on a tile is a safe position to end a path.
Definition: pbs.cpp:380
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:307
static debug_inline bool IsRailDepotTile(Tile t)
Is this tile rail tile and a rail depot?
Definition: rail_map.h:105
RailTypes
Allow incrementing of Track variables.
Definition: rail_type.h:44
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:27
Track GetRailStationTrack(Tile t)
Get the rail track of a rail station tile.
Definition: station_map.h:515
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition: station_map.h:28
bool HasStationTileRail(Tile t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint?
Definition: station_map.h:146
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:103
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:70
OrderType GetType() const
Get the type of order of this order.
Definition: order_base.h:76
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition: order_base.h:146
static Waypoint * Get(size_t index)
Gets station with given index.
'Train' is either a loco or a wagon.
Definition: train.h:89
Order current_order
The current order (+ status, like: loading)
Definition: vehicle_base.h:356
TileIndex tile
Current tile index.
Definition: vehicle_base.h:264
TileIndex dest_tile
Heading for this tile.
Definition: vehicle_base.h:271
bool IsSingleTile() const
Is this a single tile waypoint?
Definition: waypoint_base.h:62
Track TrackdirToTrack(Trackdir trackdir)
Returns the Track that a given Trackdir represents.
Definition: track_func.h:262
TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
Returns the present-trackdir-information of a TrackStatus.
Definition: track_func.h:352
bool HasTrackdir(TrackdirBits trackdirs, Trackdir trackdir)
Checks whether a TrackdirBits has a given Trackdir.
Definition: track_func.h:340
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
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:67
TrackdirBits
Allow incrementing of Trackdir variables.
Definition: track_type.h:98
@ INVALID_TRACKDIR_BIT
Flag for an invalid trackdirbit value.
Definition: track_type.h:114
@ TRANSPORT_RAIL
Transport by train.