yapf_destrail.hpp
Go to the documentation of this file.00001
00002
00005 #ifndef YAPF_DESTRAIL_HPP
00006 #define YAPF_DESTRAIL_HPP
00007
00008 class CYapfDestinationRailBase
00009 {
00010 protected:
00011 RailTypes m_compatible_railtypes;
00012
00013 public:
00014 void SetDestination(const Vehicle *v, bool override_rail_type = false)
00015 {
00016 m_compatible_railtypes = v->u.rail.compatible_railtypes;
00017 if (override_rail_type) m_compatible_railtypes |= GetRailTypeInfo(v->u.rail.railtype)->compatible_railtypes;
00018 }
00019
00020 bool IsCompatibleRailType(RailType rt)
00021 {
00022 return HasBit(m_compatible_railtypes, rt);
00023 }
00024
00025 RailTypes GetCompatibleRailTypes() const
00026 {
00027 return m_compatible_railtypes;
00028 }
00029 };
00030
00031 template <class Types>
00032 class CYapfDestinationAnyDepotRailT
00033 : public CYapfDestinationRailBase
00034 {
00035 public:
00036 typedef typename Types::Tpf Tpf;
00037 typedef typename Types::NodeList::Titem Node;
00038 typedef typename Node::Key Key;
00039
00041 Tpf& Yapf()
00042 {
00043 return *static_cast<Tpf*>(this);
00044 }
00045
00047 FORCEINLINE bool PfDetectDestination(Node& n)
00048 {
00049 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00050 }
00051
00053 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00054 {
00055 bool bDest = IsRailDepotTile(tile);
00056 return bDest;
00057 }
00058
00061 FORCEINLINE bool PfCalcEstimate(Node& n)
00062 {
00063 n.m_estimate = n.m_cost;
00064 return true;
00065 }
00066 };
00067
00068 template <class Types>
00069 class CYapfDestinationAnySafeTileRailT
00070 : public CYapfDestinationRailBase
00071 {
00072 public:
00073 typedef typename Types::Tpf Tpf;
00074 typedef typename Types::NodeList::Titem Node;
00075 typedef typename Node::Key Key;
00076 typedef typename Types::TrackFollower TrackFollower;
00077
00079 Tpf& Yapf()
00080 {
00081 return *static_cast<Tpf*>(this);
00082 }
00083
00085 FORCEINLINE bool PfDetectDestination(Node& n)
00086 {
00087 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00088 }
00089
00091 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00092 {
00093 return
00094 IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
00095 IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
00096 }
00097
00100 FORCEINLINE bool PfCalcEstimate(Node& n)
00101 {
00102 n.m_estimate = n.m_cost;
00103 return true;
00104 }
00105 };
00106
00107 template <class Types>
00108 class CYapfDestinationTileOrStationRailT
00109 : public CYapfDestinationRailBase
00110 {
00111 public:
00112 typedef typename Types::Tpf Tpf;
00113 typedef typename Types::NodeList::Titem Node;
00114 typedef typename Node::Key Key;
00115
00116 protected:
00117 TileIndex m_destTile;
00118 TrackdirBits m_destTrackdirs;
00119 StationID m_dest_station_id;
00120
00122 Tpf& Yapf()
00123 {
00124 return *static_cast<Tpf*>(this);
00125 }
00126
00127 public:
00128 void SetDestination(const Vehicle *v)
00129 {
00130 switch (v->current_order.GetType()) {
00131 case OT_GOTO_STATION:
00132 m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile);
00133 m_dest_station_id = v->current_order.GetDestination();
00134 m_destTrackdirs = INVALID_TRACKDIR_BIT;
00135 break;
00136
00137 case OT_GOTO_WAYPOINT: {
00138 Waypoint *wp = GetWaypoint(v->current_order.GetDestination());
00139 if (wp == NULL) {
00140
00141 DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, company %d)", v->current_order.GetDestination(), v->unitnumber, (CompanyID)v->owner);
00142 break;
00143 }
00144 m_destTile = wp->xy;
00145 if (m_destTile != v->dest_tile) {
00146
00147 DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, company %d)", v->dest_tile, v->unitnumber, (CompanyID)v->owner);
00148 }
00149 m_dest_station_id = INVALID_STATION;
00150 m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy)));
00151 break;
00152 }
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 = IsRailwayStationTile(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 int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00189 static 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