yapf_destrail.hpp

Go to the documentation of this file.
00001 /* $Id: yapf_destrail.hpp 19141 2010-02-15 23:55:04Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
00008  */
00009 
00012 #ifndef  YAPF_DESTRAIL_HPP
00013 #define  YAPF_DESTRAIL_HPP
00014 
00015 class CYapfDestinationRailBase
00016 {
00017 protected:
00018   RailTypes m_compatible_railtypes;
00019 
00020 public:
00021   void SetDestination(const Train *v, bool override_rail_type = false)
00022   {
00023     m_compatible_railtypes = v->compatible_railtypes;
00024     if (override_rail_type) m_compatible_railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes;
00025   }
00026 
00027   bool IsCompatibleRailType(RailType rt)
00028   {
00029     return HasBit(m_compatible_railtypes, rt);
00030   }
00031 
00032   RailTypes GetCompatibleRailTypes() const
00033   {
00034     return m_compatible_railtypes;
00035   }
00036 };
00037 
00038 template <class Types>
00039 class CYapfDestinationAnyDepotRailT
00040   : public CYapfDestinationRailBase
00041 {
00042 public:
00043   typedef typename Types::Tpf Tpf;              
00044   typedef typename Types::NodeList::Titem Node; 
00045   typedef typename Node::Key Key;               
00046 
00048   Tpf& Yapf()
00049   {
00050     return *static_cast<Tpf*>(this);
00051   }
00052 
00054   FORCEINLINE bool PfDetectDestination(Node& n)
00055   {
00056     return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00057   }
00058 
00060   FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00061   {
00062     bool bDest = IsRailDepotTile(tile);
00063     return bDest;
00064   }
00065 
00068   FORCEINLINE bool PfCalcEstimate(Node& n)
00069   {
00070     n.m_estimate = n.m_cost;
00071     return true;
00072   }
00073 };
00074 
00075 template <class Types>
00076 class CYapfDestinationAnySafeTileRailT
00077   : public CYapfDestinationRailBase
00078 {
00079 public:
00080   typedef typename Types::Tpf Tpf;              
00081   typedef typename Types::NodeList::Titem Node; 
00082   typedef typename Node::Key Key;               
00083   typedef typename Types::TrackFollower TrackFollower; 
00084 
00086   Tpf& Yapf()
00087   {
00088     return *static_cast<Tpf*>(this);
00089   }
00090 
00092   FORCEINLINE bool PfDetectDestination(Node& n)
00093   {
00094     return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00095   }
00096 
00098   FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00099   {
00100     return
00101       IsSafeWaitingPosition(Yapf().GetVehicle(), tile, td, true, !TrackFollower::Allow90degTurns()) &&
00102       IsWaitingPositionFree(Yapf().GetVehicle(), tile, td, !TrackFollower::Allow90degTurns());
00103   }
00104 
00107   FORCEINLINE bool PfCalcEstimate(Node& n)
00108   {
00109     n.m_estimate = n.m_cost;
00110     return true;
00111   }
00112 };
00113 
00114 template <class Types>
00115 class CYapfDestinationTileOrStationRailT
00116   : public CYapfDestinationRailBase
00117 {
00118 public:
00119   typedef typename Types::Tpf Tpf;              
00120   typedef typename Types::NodeList::Titem Node; 
00121   typedef typename Node::Key Key;               
00122 
00123 protected:
00124   TileIndex    m_destTile;
00125   TrackdirBits m_destTrackdirs;
00126   StationID    m_dest_station_id;
00127 
00129   Tpf& Yapf()
00130   {
00131     return *static_cast<Tpf*>(this);
00132   }
00133 
00134 public:
00135   void SetDestination(const Train *v)
00136   {
00137     switch (v->current_order.GetType()) {
00138       case OT_GOTO_WAYPOINT:
00139         if (!Waypoint::Get(v->current_order.GetDestination())->IsSingleTile()) {
00140           /* In case of 'complex' waypoints we need to do a look
00141            * ahead. This look ahead messes a bit about, which
00142            * means that it 'corrupts' the cache. To prevent this
00143            * we disable caching when we're looking for a complex
00144            * waypoint. */
00145           Yapf().DisableCache(true);
00146         }
00147         /* FALL THROUGH */
00148       case OT_GOTO_STATION:
00149         m_destTile = CalcClosestStationTile(v->current_order.GetDestination(), v->tile, v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT);
00150         m_dest_station_id = v->current_order.GetDestination();
00151         m_destTrackdirs = INVALID_TRACKDIR_BIT;
00152         break;
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 = HasStationTileRail(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 const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00189     static const 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 Sun Nov 14 14:41:54 2010 for OpenTTD by  doxygen 1.6.1