OpenTTD
yapf_destrail.hpp
Go to the documentation of this file.
1 /* $Id: yapf_destrail.hpp 27363 2015-08-08 13:19:38Z alberth $ */
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  /* FALL THROUGH */
144  case OT_GOTO_STATION:
145  m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
146  m_dest_station_id = v->current_order.GetDestination();
147  m_destTrackdirs = INVALID_TRACKDIR_BIT;
148  break;
149 
150  default:
151  m_destTile = v->dest_tile;
152  m_dest_station_id = INVALID_STATION;
154  break;
155  }
156  CYapfDestinationRailBase::SetDestination(v);
157  }
158 
160  inline bool PfDetectDestination(Node &n)
161  {
162  return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
163  }
164 
166  inline bool PfDetectDestination(TileIndex tile, Trackdir td)
167  {
168  bool bDest;
169  if (m_dest_station_id != INVALID_STATION) {
170  bDest = HasStationTileRail(tile)
171  && (GetStationIndex(tile) == m_dest_station_id)
172  && (GetRailStationTrack(tile) == TrackdirToTrack(td));
173  } else {
174  bDest = (tile == m_destTile)
175  && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
176  }
177  return bDest;
178  }
179 
184  inline bool PfCalcEstimate(Node &n)
185  {
186  static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
187  static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
188  if (PfDetectDestination(n)) {
189  n.m_estimate = n.m_cost;
190  return true;
191  }
192 
193  TileIndex tile = n.GetLastTile();
194  DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
195  int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
196  int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
197  int x2 = 2 * TileX(m_destTile);
198  int y2 = 2 * TileY(m_destTile);
199  int dx = abs(x1 - x2);
200  int dy = abs(y1 - y2);
201  int dmin = min(dx, dy);
202  int dxy = abs(dx - dy);
203  int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
204  n.m_estimate = n.m_cost + d;
205  assert(n.m_estimate >= n.m_parent->m_estimate);
206  return true;
207  }
208 };
209 
210 #endif /* YAPF_DESTRAIL_HPP */