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 */

Generated on Wed Jun 3 19:05:17 2009 for OpenTTD by  doxygen 1.5.6