OpenTTD
yapf_destrail.hpp
Go to the documentation of this file.
1 /* $Id: yapf_destrail.hpp 27893 2017-08-13 18:38:42Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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  */
9 
12 #ifndef YAPF_DESTRAIL_HPP
13 #define YAPF_DESTRAIL_HPP
14 
16 protected:
17  RailTypes m_compatible_railtypes;
18 
19 public:
20  void SetDestination(const Train *v, bool override_rail_type = false)
21  {
22  m_compatible_railtypes = v->compatible_railtypes;
23  if (override_rail_type) m_compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
24  }
25 
26  bool IsCompatibleRailType(RailType rt)
27  {
28  return HasBit(m_compatible_railtypes, rt);
29  }
30 
31  RailTypes GetCompatibleRailTypes() const
32  {
33  return m_compatible_railtypes;
34  }
35 };
36 
37 template <class Types>
39 public:
40  typedef typename Types::Tpf Tpf;
41  typedef typename Types::NodeList::Titem Node;
42  typedef typename Node::Key Key;
43 
45  Tpf& Yapf()
46  {
47  return *static_cast<Tpf *>(this);
48  }
49 
51  inline bool PfDetectDestination(Node &n)
52  {
53  return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
54  }
55 
57  inline bool PfDetectDestination(TileIndex tile, Trackdir td)
58  {
59  bool bDest = IsRailDepotTile(tile);
60  return bDest;
61  }
62 
67  inline bool PfCalcEstimate(Node &n)
68  {
69  n.m_estimate = n.m_cost;
70  return true;
71  }
72 };
73 
74 template <class Types>
76 public:
77  typedef typename Types::Tpf Tpf;
78  typedef typename Types::NodeList::Titem Node;
79  typedef typename Node::Key Key;
80  typedef typename Types::TrackFollower TrackFollower;
81 
83  Tpf& Yapf()
84  {
85  return *static_cast<Tpf *>(this);
86  }
87 
89  inline bool PfDetectDestination(Node &n)
90  {
91  return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
92  }
93 
95  inline bool PfDetectDestination(TileIndex tile, Trackdir td)
96  {
97  return IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
98  IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
99  }
100 
105  inline bool PfCalcEstimate(Node &n)
106  {
107  n.m_estimate = n.m_cost;
108  return true;
109  }
110 };
111 
112 template <class Types>
114 public:
115  typedef typename Types::Tpf Tpf;
116  typedef typename Types::NodeList::Titem Node;
117  typedef typename Node::Key Key;
118 
119 protected:
120  TileIndex m_destTile;
121  TrackdirBits m_destTrackdirs;
122  StationID m_dest_station_id;
123 
126  {
127  return *static_cast<Tpf *>(this);
128  }
129 
130 public:
131  void SetDestination(const Train *v)
132  {
133  switch (v->current_order.GetType()) {
134  case OT_GOTO_WAYPOINT:
135  if (!Waypoint::Get(v->current_order.GetDestination())->IsSingleTile()) {
136  /* In case of 'complex' waypoints we need to do a look
137  * ahead. This look ahead messes a bit about, which
138  * means that it 'corrupts' the cache. To prevent this
139  * we disable caching when we're looking for a complex
140  * waypoint. */
141  Yapf().DisableCache(true);
142  }
143  FALLTHROUGH;
144 
145  case OT_GOTO_STATION:
146  m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
147  m_dest_station_id = v->current_order.GetDestination();
148  m_destTrackdirs = INVALID_TRACKDIR_BIT;
149  break;
150 
151  default:
152  m_destTile = v->dest_tile;
153  m_dest_station_id = INVALID_STATION;
155  break;
156  }
157  CYapfDestinationRailBase::SetDestination(v);
158  }
159 
161  inline bool PfDetectDestination(Node &n)
162  {
163  return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
164  }
165 
167  inline bool PfDetectDestination(TileIndex tile, Trackdir td)
168  {
169  bool bDest;
170  if (m_dest_station_id != INVALID_STATION) {
171  bDest = HasStationTileRail(tile)
172  && (GetStationIndex(tile) == m_dest_station_id)
173  && (GetRailStationTrack(tile) == TrackdirToTrack(td));
174  } else {
175  bDest = (tile == m_destTile)
176  && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
177  }
178  return bDest;
179  }
180 
185  inline bool PfCalcEstimate(Node &n)
186  {
187  static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
188  static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
189  if (PfDetectDestination(n)) {
190  n.m_estimate = n.m_cost;
191  return true;
192  }
193 
194  TileIndex tile = n.GetLastTile();
195  DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
196  int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
197  int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
198  int x2 = 2 * TileX(m_destTile);
199  int y2 = 2 * TileY(m_destTile);
200  int dx = abs(x1 - x2);
201  int dy = abs(y1 - y2);
202  int dmin = min(dx, dy);
203  int dxy = abs(dx - dy);
204  int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
205  n.m_estimate = n.m_cost + d;
206  assert(n.m_estimate >= n.m_parent->m_estimate);
207  return true;
208  }
209 };
210 
211 #endif /* YAPF_DESTRAIL_HPP */