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/>.
10 /** @file yapf_destrail.hpp Determining the destination for rail vehicles. */
12 #ifndef YAPF_DESTRAIL_HPP
13 #define YAPF_DESTRAIL_HPP
15 class CYapfDestinationRailBase
{
17 RailTypes m_compatible_railtypes
;
20 void SetDestination(const Train
*v
, bool override_rail_type
= false)
22 m_compatible_railtypes
= v
->compatible_railtypes
;
23 if (override_rail_type
) m_compatible_railtypes
|= GetRailTypeInfo(v
->railtype
)->compatible_railtypes
;
26 bool IsCompatibleRailType(RailType rt
)
28 return HasBit(m_compatible_railtypes
, rt
);
31 RailTypes
GetCompatibleRailTypes() const
33 return m_compatible_railtypes
;
37 template <class Types
>
38 class CYapfDestinationAnyDepotRailT
: public CYapfDestinationRailBase
{
40 typedef typename
Types::Tpf Tpf
; ///< the pathfinder class (derived from THIS class)
41 typedef typename
Types::NodeList::Titem Node
; ///< this will be our node type
42 typedef typename
Node::Key Key
; ///< key to hash tables
44 /** to access inherited path finder */
47 return *static_cast<Tpf
*>(this);
50 /** Called by YAPF to detect if node ends in the desired destination */
51 inline bool PfDetectDestination(Node
&n
)
53 return PfDetectDestination(n
.GetLastTile(), n
.GetLastTrackdir());
56 /** Called by YAPF to detect if node ends in the desired destination */
57 inline bool PfDetectDestination(TileIndex tile
, Trackdir td
)
59 bool bDest
= IsRailDepotTile(tile
);
64 * Called by YAPF to calculate cost estimate. Calculates distance to the destination
65 * adds it to the actual cost from origin and stores the sum to the Node::m_estimate
67 inline bool PfCalcEstimate(Node
&n
)
69 n
.m_estimate
= n
.m_cost
;
74 template <class Types
>
75 class CYapfDestinationAnySafeTileRailT
: public CYapfDestinationRailBase
{
77 typedef typename
Types::Tpf Tpf
; ///< the pathfinder class (derived from THIS class)
78 typedef typename
Types::NodeList::Titem Node
; ///< this will be our node type
79 typedef typename
Node::Key Key
; ///< key to hash tables
80 typedef typename
Types::TrackFollower TrackFollower
; ///< TrackFollower. Need to typedef for gcc 2.95
82 /** to access inherited path finder */
85 return *static_cast<Tpf
*>(this);
88 /** Called by YAPF to detect if node ends in the desired destination */
89 inline bool PfDetectDestination(Node
&n
)
91 return PfDetectDestination(n
.GetLastTile(), n
.GetLastTrackdir());
94 /** Called by YAPF to detect if node ends in the desired destination */
95 inline bool PfDetectDestination(TileIndex tile
, Trackdir td
)
97 return IsSafeWaitingPosition(Yapf().GetVehicle(), tile
, td
, true, !TrackFollower::Allow90degTurns()) &&
98 IsWaitingPositionFree(Yapf().GetVehicle(), tile
, td
, !TrackFollower::Allow90degTurns());
102 * Called by YAPF to calculate cost estimate. Calculates distance to the destination
103 * adds it to the actual cost from origin and stores the sum to the Node::m_estimate.
105 inline bool PfCalcEstimate(Node
&n
)
107 n
.m_estimate
= n
.m_cost
;
112 template <class Types
>
113 class CYapfDestinationTileOrStationRailT
: public CYapfDestinationRailBase
{
115 typedef typename
Types::Tpf Tpf
; ///< the pathfinder class (derived from THIS class)
116 typedef typename
Types::NodeList::Titem Node
; ///< this will be our node type
117 typedef typename
Node::Key Key
; ///< key to hash tables
120 TileIndex m_destTile
;
121 TrackdirBits m_destTrackdirs
;
122 StationID m_dest_station_id
;
124 /** to access inherited path finder */
127 return *static_cast<Tpf
*>(this);
131 void SetDestination(const Train
*v
)
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
141 Yapf().DisableCache(true);
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
;
151 m_destTile
= v
->dest_tile
;
152 m_dest_station_id
= INVALID_STATION
;
153 m_destTrackdirs
= TrackStatusToTrackdirBits(GetTileTrackStatus(v
->dest_tile
, TRANSPORT_RAIL
, 0));
156 CYapfDestinationRailBase::SetDestination(v
);
159 /** Called by YAPF to detect if node ends in the desired destination */
160 inline bool PfDetectDestination(Node
&n
)
162 return PfDetectDestination(n
.GetLastTile(), n
.GetLastTrackdir());
165 /** Called by YAPF to detect if node ends in the desired destination */
166 inline bool PfDetectDestination(TileIndex tile
, Trackdir td
)
169 if (m_dest_station_id
!= INVALID_STATION
) {
170 bDest
= HasStationTileRail(tile
)
171 && (GetStationIndex(tile
) == m_dest_station_id
)
172 && (GetRailStationTrack(tile
) == TrackdirToTrack(td
));
174 bDest
= (tile
== m_destTile
)
175 && ((m_destTrackdirs
& TrackdirToTrackdirBits(td
)) != TRACKDIR_BIT_NONE
);
181 * Called by YAPF to calculate cost estimate. Calculates distance to the destination
182 * adds it to the actual cost from origin and stores the sum to the Node::m_estimate
184 inline bool PfCalcEstimate(Node
&n
)
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
;
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
);
210 #endif /* YAPF_DESTRAIL_HPP */