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

Generated on Mon Feb 16 23:12:13 2009 for openttd by  doxygen 1.5.6