yapf_destrail.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef YAPF_DESTRAIL_HPP
00013 #define YAPF_DESTRAIL_HPP
00014
00015 class CYapfDestinationRailBase
00016 {
00017 protected:
00018 RailTypes m_compatible_railtypes;
00019
00020 public:
00021 void SetDestination(const Train *v, bool override_rail_type = false)
00022 {
00023 m_compatible_railtypes = v->compatible_railtypes;
00024 if (override_rail_type) m_compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
00025 }
00026
00027 bool IsCompatibleRailType(RailType rt)
00028 {
00029 return HasBit(m_compatible_railtypes, rt);
00030 }
00031
00032 RailTypes GetCompatibleRailTypes() const
00033 {
00034 return m_compatible_railtypes;
00035 }
00036 };
00037
00038 template <class Types>
00039 class CYapfDestinationAnyDepotRailT
00040 : public CYapfDestinationRailBase
00041 {
00042 public:
00043 typedef typename Types::Tpf Tpf;
00044 typedef typename Types::NodeList::Titem Node;
00045 typedef typename Node::Key Key;
00046
00048 Tpf& Yapf()
00049 {
00050 return *static_cast<Tpf*>(this);
00051 }
00052
00054 FORCEINLINE bool PfDetectDestination(Node& n)
00055 {
00056 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00057 }
00058
00060 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00061 {
00062 bool bDest = IsRailDepotTile(tile);
00063 return bDest;
00064 }
00065
00068 FORCEINLINE bool PfCalcEstimate(Node& n)
00069 {
00070 n.m_estimate = n.m_cost;
00071 return true;
00072 }
00073 };
00074
00075 template <class Types>
00076 class CYapfDestinationAnySafeTileRailT
00077 : public CYapfDestinationRailBase
00078 {
00079 public:
00080 typedef typename Types::Tpf Tpf;
00081 typedef typename Types::NodeList::Titem Node;
00082 typedef typename Node::Key Key;
00083 typedef typename Types::TrackFollower TrackFollower;
00084
00086 Tpf& Yapf()
00087 {
00088 return *static_cast<Tpf*>(this);
00089 }
00090
00092 FORCEINLINE bool PfDetectDestination(Node& n)
00093 {
00094 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00095 }
00096
00098 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00099 {
00100 return
00101 IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
00102 IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
00103 }
00104
00107 FORCEINLINE bool PfCalcEstimate(Node& n)
00108 {
00109 n.m_estimate = n.m_cost;
00110 return true;
00111 }
00112 };
00113
00114 template <class Types>
00115 class CYapfDestinationTileOrStationRailT
00116 : public CYapfDestinationRailBase
00117 {
00118 public:
00119 typedef typename Types::Tpf Tpf;
00120 typedef typename Types::NodeList::Titem Node;
00121 typedef typename Node::Key Key;
00122
00123 protected:
00124 TileIndex m_destTile;
00125 TrackdirBits m_destTrackdirs;
00126 StationID m_dest_station_id;
00127
00129 Tpf& Yapf()
00130 {
00131 return *static_cast<Tpf*>(this);
00132 }
00133
00134 public:
00135 void SetDestination(const Train *v)
00136 {
00137 switch (v->current_order.GetType()) {
00138 case OT_GOTO_WAYPOINT:
00139 if (!Waypoint::Get(v->current_order.GetDestination())->IsSingleTile()) {
00140
00141
00142
00143
00144
00145 Yapf().DisableCache(true);
00146 }
00147
00148 case OT_GOTO_STATION:
00149 m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
00150 m_dest_station_id = v->current_order.GetDestination();
00151 m_destTrackdirs = INVALID_TRACKDIR_BIT;
00152 break;
00153
00154 default:
00155 m_destTile = v->dest_tile;
00156 m_dest_station_id = INVALID_STATION;
00157 m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
00158 break;
00159 }
00160 CYapfDestinationRailBase::SetDestination(v);
00161 }
00162
00164 FORCEINLINE bool PfDetectDestination(Node& n)
00165 {
00166 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00167 }
00168
00170 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00171 {
00172 bool bDest;
00173 if (m_dest_station_id != INVALID_STATION) {
00174 bDest = HasStationTileRail(tile)
00175 && (GetStationIndex(tile) == m_dest_station_id)
00176 && (GetRailStationTrack(tile) == TrackdirToTrack(td));
00177 } else {
00178 bDest = (tile == m_destTile)
00179 && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
00180 }
00181 return bDest;
00182 }
00183
00186 FORCEINLINE bool PfCalcEstimate(Node& n)
00187 {
00188 static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00189 static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00190 if (PfDetectDestination(n)) {
00191 n.m_estimate = n.m_cost;
00192 return true;
00193 }
00194
00195 TileIndex tile = n.GetLastTile();
00196 DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
00197 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00198 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00199 int x2 = 2 * TileX(m_destTile);
00200 int y2 = 2 * TileY(m_destTile);
00201 int dx = abs(x1 - x2);
00202 int dy = abs(y1 - y2);
00203 int dmin = min(dx, dy);
00204 int dxy = abs(dx - dy);
00205 int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00206 n.m_estimate = n.m_cost + d;
00207 assert(n.m_estimate >= n.m_parent->m_estimate);
00208 return true;
00209 }
00210 };
00211
00212 #endif