# yapf_destrail.hpp

Go to the documentation of this file.

    00001 /* $Id: yapf_destrail.hpp 15718 2009-03-15 00:32:18Z 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()
    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           /* Invalid waypoint in orders! */
    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           /* Something is wrong with orders! */
    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 /* YAPF_DESTRAIL_HPP */