Update: Translations from eints
[openttd-github.git] / src / pathfinder / yapf / yapf_destrail.hpp
blobf39a8a2c4b40e7bd1d598d6fda27f484feaa9057
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 */
8 /** @file yapf_destrail.hpp Determining the destination for rail vehicles. */
10 #ifndef YAPF_DESTRAIL_HPP
11 #define YAPF_DESTRAIL_HPP
13 class CYapfDestinationRailBase {
14 protected:
15 RailTypes m_compatible_railtypes;
17 public:
18 void SetDestination(const Train *v, bool override_rail_type = false)
20 m_compatible_railtypes = v->compatible_railtypes;
21 if (override_rail_type) m_compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
24 bool IsCompatibleRailType(RailType rt)
26 return HasBit(m_compatible_railtypes, rt);
29 RailTypes GetCompatibleRailTypes() const
31 return m_compatible_railtypes;
35 template <class Types>
36 class CYapfDestinationAnyDepotRailT : public CYapfDestinationRailBase {
37 public:
38 typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
39 typedef typename Types::NodeList::Titem Node; ///< this will be our node type
40 typedef typename Node::Key Key; ///< key to hash tables
42 /** to access inherited path finder */
43 Tpf &Yapf()
45 return *static_cast<Tpf *>(this);
48 /** Called by YAPF to detect if node ends in the desired destination */
49 inline bool PfDetectDestination(Node &n)
51 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
54 /** Called by YAPF to detect if node ends in the desired destination */
55 inline bool PfDetectDestination(TileIndex tile, Trackdir)
57 bool bDest = IsRailDepotTile(tile);
58 return bDest;
61 /**
62 * Called by YAPF to calculate cost estimate. Calculates distance to the destination
63 * adds it to the actual cost from origin and stores the sum to the Node::m_estimate
65 inline bool PfCalcEstimate(Node &n)
67 n.m_estimate = n.m_cost;
68 return true;
72 template <class Types>
73 class CYapfDestinationAnySafeTileRailT : public CYapfDestinationRailBase {
74 public:
75 typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
76 typedef typename Types::NodeList::Titem Node; ///< this will be our node type
77 typedef typename Node::Key Key; ///< key to hash tables
78 typedef typename Types::TrackFollower TrackFollower; ///< TrackFollower. Need to typedef for gcc 2.95
80 /** to access inherited path finder */
81 Tpf &Yapf()
83 return *static_cast<Tpf *>(this);
86 /** Called by YAPF to detect if node ends in the desired destination */
87 inline bool PfDetectDestination(Node &n)
89 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
92 /** Called by YAPF to detect if node ends in the desired destination */
93 inline bool PfDetectDestination(TileIndex tile, Trackdir td)
95 return IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
96 IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
99 /**
100 * Called by YAPF to calculate cost estimate. Calculates distance to the destination
101 * adds it to the actual cost from origin and stores the sum to the Node::m_estimate.
103 inline bool PfCalcEstimate(Node &n)
105 n.m_estimate = n.m_cost;
106 return true;
110 template <class Types>
111 class CYapfDestinationTileOrStationRailT : public CYapfDestinationRailBase {
112 public:
113 typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
114 typedef typename Types::NodeList::Titem Node; ///< this will be our node type
115 typedef typename Node::Key Key; ///< key to hash tables
117 protected:
118 TileIndex m_destTile;
119 TrackdirBits m_destTrackdirs;
120 StationID m_dest_station_id;
121 bool m_any_depot;
123 /** to access inherited path finder */
124 Tpf &Yapf()
126 return *static_cast<Tpf *>(this);
129 public:
130 void SetDestination(const Train *v)
132 m_any_depot = false;
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);
143 [[fallthrough]];
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;
151 case OT_GOTO_DEPOT:
152 if (v->current_order.GetDepotActionType() & ODATFB_NEAREST_DEPOT) {
153 m_any_depot = true;
155 [[fallthrough]];
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;
163 CYapfDestinationRailBase::SetDestination(v);
166 /** Called by YAPF to detect if node ends in the desired destination */
167 inline bool PfDetectDestination(Node &n)
169 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
172 /** Called by YAPF to detect if node ends in the desired destination */
173 inline bool PfDetectDestination(TileIndex tile, Trackdir td)
175 if (m_dest_station_id != INVALID_STATION) {
176 return HasStationTileRail(tile)
177 && (GetStationIndex(tile) == m_dest_station_id)
178 && (GetRailStationTrack(tile) == TrackdirToTrack(td));
181 if (m_any_depot) {
182 return IsRailDepotTile(tile);
185 return (tile == m_destTile) && HasTrackdir(m_destTrackdirs, td);
189 * Called by YAPF to calculate cost estimate. Calculates distance to the destination
190 * adds it to the actual cost from origin and stores the sum to the Node::m_estimate
192 inline bool PfCalcEstimate(Node &n)
194 static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
195 static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
196 if (PfDetectDestination(n)) {
197 n.m_estimate = n.m_cost;
198 return true;
201 TileIndex tile = n.GetLastTile();
202 DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
203 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
204 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
205 int x2 = 2 * TileX(m_destTile);
206 int y2 = 2 * TileY(m_destTile);
207 int dx = abs(x1 - x2);
208 int dy = abs(y1 - y2);
209 int dmin = std::min(dx, dy);
210 int dxy = abs(dx - dy);
211 int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
212 n.m_estimate = n.m_cost + d;
213 assert(n.m_estimate >= n.m_parent->m_estimate);
214 return true;
218 #endif /* YAPF_DESTRAIL_HPP */