# yapf_destrail.hpp

Go to the documentation of this file.

    00001 /* $Id: yapf_destrail.hpp 14949 2009-01-10 00:31:47Z rubidium $ */
    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     /* If the rail station is (temporarily) not present, use the station sign to drive near the station */
    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     // return the tile of our target coordinates
    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           /* Invalid waypoint in orders! */
    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           /* Something is wrong with orders! */
    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 /* YAPF_DESTRAIL_HPP */