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() {return *static_cast<Tpf*>(this);}
00042
00044 FORCEINLINE bool PfDetectDestination(Node& n)
00045 {
00046 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00047 }
00048
00050 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00051 {
00052 bool bDest = IsRailDepotTile(tile);
00053 return bDest;
00054 }
00055
00058 FORCEINLINE bool PfCalcEstimate(Node& n)
00059 {
00060 n.m_estimate = n.m_cost;
00061 return true;
00062 }
00063 };
00064
00065 template <class Types>
00066 class CYapfDestinationAnySafeTileRailT
00067 : public CYapfDestinationRailBase
00068 {
00069 public:
00070 typedef typename Types::Tpf Tpf;
00071 typedef typename Types::NodeList::Titem Node;
00072 typedef typename Node::Key Key;
00073 typedef typename Types::TrackFollower TrackFollower;
00074
00076 Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00077
00079 FORCEINLINE bool PfDetectDestination(Node& n)
00080 {
00081 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00082 }
00083
00085 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00086 {
00087 return
00088 IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
00089 IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
00090 }
00091
00094 FORCEINLINE bool PfCalcEstimate(Node& n)
00095 {
00096 n.m_estimate = n.m_cost;
00097 return true;
00098 }
00099 };
00100
00101 template <class Types>
00102 class CYapfDestinationTileOrStationRailT
00103 : public CYapfDestinationRailBase
00104 {
00105 public:
00106 typedef typename Types::Tpf Tpf;
00107 typedef typename Types::NodeList::Titem Node;
00108 typedef typename Node::Key Key;
00109
00110 protected:
00111 TileIndex m_destTile;
00112 TrackdirBits m_destTrackdirs;
00113 StationID m_dest_station_id;
00114
00116 Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00117
00118 static TileIndex CalcStationCenterTile(StationID station)
00119 {
00120 const Station *st = GetStation(station);
00121
00122
00123 if (!IsValidTile(st->train_tile)) return st->xy;
00124
00125 uint x = TileX(st->train_tile) + st->trainst_w / 2;
00126 uint y = TileY(st->train_tile) + st->trainst_h / 2;
00127
00128 return TileXY(x, y);
00129 }
00130
00131 public:
00132 void SetDestination(const Vehicle *v)
00133 {
00134 switch (v->current_order.GetType()) {
00135 case OT_GOTO_STATION:
00136 m_destTile = CalcStationCenterTile(v->current_order.GetDestination());
00137 m_dest_station_id = v->current_order.GetDestination();
00138 m_destTrackdirs = INVALID_TRACKDIR_BIT;
00139 break;
00140
00141 case OT_GOTO_WAYPOINT: {
00142 Waypoint *wp = GetWaypoint(v->current_order.GetDestination());
00143 if (wp == NULL) {
00144
00145 DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, company %d)", v->current_order.GetDestination(), v->unitnumber, (CompanyID)v->owner);
00146 break;
00147 }
00148 m_destTile = wp->xy;
00149 if (m_destTile != v->dest_tile) {
00150
00151 DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, company %d)", v->dest_tile, v->unitnumber, (CompanyID)v->owner);
00152 }
00153 m_dest_station_id = INVALID_STATION;
00154 m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy)));
00155 break;
00156 }
00157
00158 default:
00159 m_destTile = v->dest_tile;
00160 m_dest_station_id = INVALID_STATION;
00161 m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
00162 break;
00163 }
00164 CYapfDestinationRailBase::SetDestination(v);
00165 }
00166
00168 FORCEINLINE bool PfDetectDestination(Node& n)
00169 {
00170 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00171 }
00172
00174 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00175 {
00176 bool bDest;
00177 if (m_dest_station_id != INVALID_STATION) {
00178 bDest = IsRailwayStationTile(tile)
00179 && (GetStationIndex(tile) == m_dest_station_id)
00180 && (GetRailStationTrack(tile) == TrackdirToTrack(td));
00181 } else {
00182 bDest = (tile == m_destTile)
00183 && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
00184 }
00185 return bDest;
00186 }
00187
00190 FORCEINLINE bool PfCalcEstimate(Node& n)
00191 {
00192 static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00193 static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00194 if (PfDetectDestination(n)) {
00195 n.m_estimate = n.m_cost;
00196 return true;
00197 }
00198
00199 TileIndex tile = n.GetLastTile();
00200 DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
00201 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00202 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00203 int x2 = 2 * TileX(m_destTile);
00204 int y2 = 2 * TileY(m_destTile);
00205 int dx = abs(x1 - x2);
00206 int dy = abs(y1 - y2);
00207 int dmin = min(dx, dy);
00208 int dxy = abs(dx - dy);
00209 int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00210 n.m_estimate = n.m_cost + d;
00211 assert(n.m_estimate >= n.m_parent->m_estimate);
00212 return true;
00213 }
00214 };
00215
00216
00217 #endif