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 inline bool PfDetectDestination(Node& n)
00055 {
00056 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00057 }
00058
00060 inline bool PfDetectDestination(TileIndex tile, Trackdir td)
00061 {
00062 bool bDest = IsRailDepotTile(tile);
00063 return bDest;
00064 }
00065
00070 inline bool PfCalcEstimate(Node& n)
00071 {
00072 n.m_estimate = n.m_cost;
00073 return true;
00074 }
00075 };
00076
00077 template <class Types>
00078 class CYapfDestinationAnySafeTileRailT
00079 : public CYapfDestinationRailBase
00080 {
00081 public:
00082 typedef typename Types::Tpf Tpf;
00083 typedef typename Types::NodeList::Titem Node;
00084 typedef typename Node::Key Key;
00085 typedef typename Types::TrackFollower TrackFollower;
00086
00088 Tpf& Yapf()
00089 {
00090 return *static_cast<Tpf*>(this);
00091 }
00092
00094 inline bool PfDetectDestination(Node& n)
00095 {
00096 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00097 }
00098
00100 inline bool PfDetectDestination(TileIndex tile, Trackdir td)
00101 {
00102 return IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
00103 IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
00104 }
00105
00110 inline bool PfCalcEstimate(Node& n)
00111 {
00112 n.m_estimate = n.m_cost;
00113 return true;
00114 }
00115 };
00116
00117 template <class Types>
00118 class CYapfDestinationTileOrStationRailT
00119 : public CYapfDestinationRailBase
00120 {
00121 public:
00122 typedef typename Types::Tpf Tpf;
00123 typedef typename Types::NodeList::Titem Node;
00124 typedef typename Node::Key Key;
00125
00126 protected:
00127 TileIndex m_destTile;
00128 TrackdirBits m_destTrackdirs;
00129 StationID m_dest_station_id;
00130
00132 Tpf& Yapf()
00133 {
00134 return *static_cast<Tpf*>(this);
00135 }
00136
00137 public:
00138 void SetDestination(const Train *v)
00139 {
00140 switch (v->current_order.GetType()) {
00141 case OT_GOTO_WAYPOINT:
00142 if (!Waypoint::Get(v->current_order.GetDestination())->IsSingleTile()) {
00143
00144
00145
00146
00147
00148 Yapf().DisableCache(true);
00149 }
00150
00151 case OT_GOTO_STATION:
00152 m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
00153 m_dest_station_id = v->current_order.GetDestination();
00154 m_destTrackdirs = INVALID_TRACKDIR_BIT;
00155 break;
00156
00157 default:
00158 m_destTile = v->dest_tile;
00159 m_dest_station_id = INVALID_STATION;
00160 m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
00161 break;
00162 }
00163 CYapfDestinationRailBase::SetDestination(v);
00164 }
00165
00167 inline bool PfDetectDestination(Node& n)
00168 {
00169 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00170 }
00171
00173 inline bool PfDetectDestination(TileIndex tile, Trackdir td)
00174 {
00175 bool bDest;
00176 if (m_dest_station_id != INVALID_STATION) {
00177 bDest = HasStationTileRail(tile)
00178 && (GetStationIndex(tile) == m_dest_station_id)
00179 && (GetRailStationTrack(tile) == TrackdirToTrack(td));
00180 } else {
00181 bDest = (tile == m_destTile)
00182 && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
00183 }
00184 return bDest;
00185 }
00186
00191 inline bool PfCalcEstimate(Node& n)
00192 {
00193 static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00194 static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00195 if (PfDetectDestination(n)) {
00196 n.m_estimate = n.m_cost;
00197 return true;
00198 }
00199
00200 TileIndex tile = n.GetLastTile();
00201 DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
00202 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00203 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00204 int x2 = 2 * TileX(m_destTile);
00205 int y2 = 2 * TileY(m_destTile);
00206 int dx = abs(x1 - x2);
00207 int dy = abs(y1 - y2);
00208 int dmin = min(dx, dy);
00209 int dxy = abs(dx - dy);
00210 int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00211 n.m_estimate = n.m_cost + d;
00212 assert(n.m_estimate >= n.m_parent->m_estimate);
00213 return true;
00214 }
00215 };
00216
00217 #endif