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(Vehicle* v)
00015 {
00016 m_compatible_railtypes = v->u.rail.compatible_railtypes;
00017 }
00018
00019 bool IsCompatibleRailType(RailType rt)
00020 {
00021 return HasBit(m_compatible_railtypes, rt);
00022 }
00023 };
00024
00025 template <class Types>
00026 class CYapfDestinationAnyDepotRailT
00027 : public CYapfDestinationRailBase
00028 {
00029 public:
00030 typedef typename Types::Tpf Tpf;
00031 typedef typename Types::NodeList::Titem Node;
00032 typedef typename Node::Key Key;
00033
00035 Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00036
00038 FORCEINLINE bool PfDetectDestination(Node& n)
00039 {
00040 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00041 }
00042
00044 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00045 {
00046 bool bDest = IsTileDepotType(tile, TRANSPORT_RAIL);
00047 return bDest;
00048 }
00049
00052 FORCEINLINE bool PfCalcEstimate(Node& n)
00053 {
00054 n.m_estimate = n.m_cost;
00055 return true;
00056 }
00057 };
00058
00059 template <class Types>
00060 class CYapfDestinationTileOrStationRailT
00061 : public CYapfDestinationRailBase
00062 {
00063 public:
00064 typedef typename Types::Tpf Tpf;
00065 typedef typename Types::NodeList::Titem Node;
00066 typedef typename Node::Key Key;
00067
00068 protected:
00069 TileIndex m_destTile;
00070 TrackdirBits m_destTrackdirs;
00071 StationID m_dest_station_id;
00072
00074 Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00075
00076 static TileIndex CalcStationCenterTile(StationID station)
00077 {
00078 const Station* st = GetStation(station);
00079
00080 uint x = TileX(st->train_tile) + st->trainst_w / 2;
00081 uint y = TileY(st->train_tile) + st->trainst_h / 2;
00082
00083 return TileXY(x, y);
00084 }
00085
00086 public:
00087 void SetDestination(Vehicle* v)
00088 {
00089 switch (v->current_order.type) {
00090 case OT_GOTO_STATION:
00091 m_destTile = CalcStationCenterTile(v->current_order.dest);
00092 m_dest_station_id = v->current_order.dest;
00093 m_destTrackdirs = INVALID_TRACKDIR_BIT;
00094 break;
00095
00096 case OT_GOTO_WAYPOINT: {
00097 Waypoint *wp = GetWaypoint(v->current_order.dest);
00098 if (wp == NULL) {
00099
00100 DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, player %d)", v->current_order.dest, v->unitnumber, (PlayerID)v->owner);
00101 break;
00102 }
00103 m_destTile = wp->xy;
00104 if (m_destTile != v->dest_tile) {
00105
00106 DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, player %d)", v->dest_tile, v->unitnumber, (PlayerID)v->owner);
00107 }
00108 m_dest_station_id = INVALID_STATION;
00109 m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy)));
00110 break;
00111 }
00112
00113 default:
00114 m_destTile = v->dest_tile;
00115 m_dest_station_id = INVALID_STATION;
00116 m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
00117 break;
00118 }
00119 CYapfDestinationRailBase::SetDestination(v);
00120 }
00121
00123 FORCEINLINE bool PfDetectDestination(Node& n)
00124 {
00125 return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00126 }
00127
00129 FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00130 {
00131 bool bDest;
00132 if (m_dest_station_id != INVALID_STATION) {
00133 bDest = IsRailwayStationTile(tile)
00134 && (GetStationIndex(tile) == m_dest_station_id)
00135 && (GetRailStationTrack(tile) == TrackdirToTrack(td));
00136 } else {
00137 bDest = (tile == m_destTile)
00138 && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
00139 }
00140 return bDest;
00141 }
00142
00145 FORCEINLINE bool PfCalcEstimate(Node& n)
00146 {
00147 static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00148 static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00149 if (PfDetectDestination(n)) {
00150 n.m_estimate = n.m_cost;
00151 return true;
00152 }
00153
00154 TileIndex tile = n.GetLastTile();
00155 DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
00156 int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00157 int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00158 int x2 = 2 * TileX(m_destTile);
00159 int y2 = 2 * TileY(m_destTile);
00160 int dx = abs(x1 - x2);
00161 int dy = abs(y1 - y2);
00162 int dmin = min(dx, dy);
00163 int dxy = abs(dx - dy);
00164 int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00165 n.m_estimate = n.m_cost + d;
00166 assert(n.m_estimate >= n.m_parent->m_estimate);
00167 return true;
00168 }
00169 };
00170
00171
00172 #endif