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