OpenTTD: src/pathfinder/yapf/yapf_destrail.hpp Source File

OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

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