yapf_road.cpp

Go to the documentation of this file.
00001 /* $Id: yapf_road.cpp 17516 2009-09-12 20:44:12Z rubidium $ */
00002 
00005 #include "../stdafx.h"
00006 #include "../depot_base.h"
00007 #include "../station_base.h"
00008 #include "../roadveh.h"
00009 #include "../cargotype.h"
00010 #include "../newgrf_cargo.h"
00011 
00012 #include "yapf.hpp"
00013 #include "yapf_node_road.hpp"
00014 
00015 
00016 template <class Types>
00017 class CYapfCostRoadT
00018 {
00019 public:
00020   typedef typename Types::Tpf Tpf; 
00021   typedef typename Types::TrackFollower TrackFollower; 
00022   typedef typename Types::NodeList::Titem Node; 
00023   typedef typename Node::Key Key;    
00024 
00025 protected:
00027   Tpf& Yapf()
00028   {
00029     return *static_cast<Tpf*>(this);
00030   }
00031 
00032   int SlopeCost(TileIndex tile, TileIndex next_tile, Trackdir trackdir)
00033   {
00034     /* height of the center of the current tile */
00035     int x1 = TileX(tile) * TILE_SIZE;
00036     int y1 = TileY(tile) * TILE_SIZE;
00037     int z1 = GetSlopeZ(x1 + TILE_SIZE / 2, y1 + TILE_SIZE / 2);
00038 
00039     /* height of the center of the next tile */
00040     int x2 = TileX(next_tile) * TILE_SIZE;
00041     int y2 = TileY(next_tile) * TILE_SIZE;
00042     int z2 = GetSlopeZ(x2 + TILE_SIZE / 2, y2 + TILE_SIZE / 2);
00043 
00044     if (z2 - z1 > 1) {
00045       /* Slope up */
00046       return Yapf().PfGetSettings().road_slope_penalty;
00047     }
00048     return 0;
00049   }
00050 
00052   FORCEINLINE int OneTileCost(TileIndex tile, Trackdir trackdir)
00053   {
00054     int cost = 0;
00055     /* set base cost */
00056     if (IsDiagonalTrackdir(trackdir)) {
00057       cost += YAPF_TILE_LENGTH;
00058       switch (GetTileType(tile)) {
00059         case MP_ROAD:
00060           /* Increase the cost for level crossings */
00061           if (IsLevelCrossing(tile)) {
00062             cost += Yapf().PfGetSettings().road_crossing_penalty;
00063           }
00064           break;
00065 
00066         case MP_STATION:
00067           if (IsDriveThroughStopTile(tile)) {
00068             cost += Yapf().PfGetSettings().road_stop_penalty;
00069           }
00070           break;
00071 
00072         default:
00073           break;
00074       }
00075     } else {
00076       /* non-diagonal trackdir */
00077       cost = YAPF_TILE_CORNER_LENGTH + Yapf().PfGetSettings().road_curve_penalty;
00078     }
00079     return cost;
00080   }
00081 
00082 public:
00086   FORCEINLINE bool PfCalcCost(Node& n, const TrackFollower *tf)
00087   {
00088     int segment_cost = 0;
00089     /* start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment */
00090     TileIndex tile = n.m_key.m_tile;
00091     Trackdir trackdir = n.m_key.m_td;
00092     while (true) {
00093       /* base tile cost depending on distance between edges */
00094       segment_cost += Yapf().OneTileCost(tile, trackdir);
00095 
00096       const Vehicle *v = Yapf().GetVehicle();
00097       /* we have reached the vehicle's destination - segment should end here to avoid target skipping */
00098       if (Yapf().PfDetectDestinationTile(tile, trackdir)) break;
00099 
00100       /* stop if we have just entered the depot */
00101       if (IsRoadDepotTile(tile) && trackdir == DiagDirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) {
00102         /* next time we will reverse and leave the depot */
00103         break;
00104       }
00105 
00106       /* if there are no reachable trackdirs on new tile, we have end of road */
00107       TrackFollower F(Yapf().GetVehicle());
00108       if (!F.Follow(tile, trackdir)) break;
00109 
00110       /* if there are more trackdirs available & reachable, we are at the end of segment */
00111       if (KillFirstBit(F.m_new_td_bits) != TRACKDIR_BIT_NONE) break;
00112 
00113       Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits);
00114 
00115       /* stop if RV is on simple loop with no junctions */
00116       if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false;
00117 
00118       /* if we skipped some tunnel tiles, add their cost */
00119       segment_cost += F.m_tiles_skipped * YAPF_TILE_LENGTH;
00120 
00121       /* add hilly terrain penalty */
00122       segment_cost += Yapf().SlopeCost(tile, F.m_new_tile, trackdir);
00123 
00124       /* add min/max speed penalties */
00125       int min_speed = 0;
00126       int max_speed = F.GetSpeedLimit(&min_speed);
00127       if (max_speed < v->max_speed) segment_cost += 1 * (v->max_speed - max_speed);
00128       if (min_speed > v->max_speed) segment_cost += 10 * (min_speed - v->max_speed);
00129 
00130       /* move to the next tile */
00131       tile = F.m_new_tile;
00132       trackdir = new_td;
00133     };
00134 
00135     /* save end of segment back to the node */
00136     n.m_segment_last_tile = tile;
00137     n.m_segment_last_td = trackdir;
00138 
00139     /* save also tile cost */
00140     int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0;
00141     n.m_cost = parent_cost + segment_cost;
00142     return true;
00143   }
00144 };
00145 
00146 
00147 template <class Types>
00148 class CYapfDestinationAnyDepotRoadT
00149 {
00150 public:
00151   typedef typename Types::Tpf Tpf;                     
00152   typedef typename Types::TrackFollower TrackFollower;
00153   typedef typename Types::NodeList::Titem Node;        
00154   typedef typename Node::Key Key;                      
00155 
00157   Tpf& Yapf()
00158   {
00159     return *static_cast<Tpf*>(this);
00160   }
00161 
00163   FORCEINLINE bool PfDetectDestination(Node& n)
00164   {
00165     bool bDest = IsRoadDepotTile(n.m_segment_last_tile);
00166     return bDest;
00167   }
00168 
00169   FORCEINLINE bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
00170   {
00171     return IsRoadDepotTile(tile);
00172   }
00173 
00176   FORCEINLINE bool PfCalcEstimate(Node& n)
00177   {
00178     n.m_estimate = n.m_cost;
00179     return true;
00180   }
00181 };
00182 
00183 
00184 template <class Types>
00185 class CYapfDestinationAnyRoadVehicleCompatibleStopOfGivenStationT
00186 {
00187 public:
00188   typedef typename Types::Tpf Tpf;                     
00189   typedef typename Types::TrackFollower TrackFollower;
00190   typedef typename Types::NodeList::Titem Node;        
00191   typedef typename Node::Key Key;                      
00192 
00193   TileIndex      m_destTile;
00194   StationID      m_dest_station;
00195   bool           m_bus;
00196   bool           m_non_artic;
00197 
00199   Tpf& Yapf()
00200   {
00201     return *static_cast<Tpf*>(this);
00202   }
00203 
00204   void SetDestination(const Vehicle *v, StationID sid, TileIndex destTile)
00205   {
00206     m_dest_station = sid;
00207     m_destTile     = destTile;
00208     m_bus          = IsCargoInClass(v->cargo_type, CC_PASSENGERS);
00209     m_non_artic    = !RoadVehHasArticPart(v);
00210   }
00211 
00213   FORCEINLINE bool PfDetectDestination(Node& n)
00214   {
00215     return PfDetectDestinationTile(n.m_segment_last_tile, INVALID_TRACKDIR);
00216   }
00217 
00218   FORCEINLINE bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
00219   {
00220     return
00221       IsTileType(tile, MP_STATION) &&
00222       GetStationIndex(tile) == m_dest_station &&
00223       (m_bus ? IsBusStop(tile) : IsTruckStop(tile)) &&
00224       (m_non_artic || IsDriveThroughStopTile(tile));
00225   }
00226 
00229   FORCEINLINE bool PfCalcEstimate(Node& n)
00230   {
00231     static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00232     static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00233     if (PfDetectDestination(n)) {
00234       n.m_estimate = n.m_cost;
00235       return true;
00236     }
00237 
00238     TileIndex tile = n.m_segment_last_tile;
00239     DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td);
00240     int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00241     int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00242     int x2 = 2 * TileX(m_destTile);
00243     int y2 = 2 * TileY(m_destTile);
00244     int dx = abs(x1 - x2);
00245     int dy = abs(y1 - y2);
00246     int dmin = min(dx, dy);
00247     int dxy = abs(dx - dy);
00248     int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00249     n.m_estimate = n.m_cost + d;
00250     assert(n.m_estimate >= n.m_parent->m_estimate);
00251     return true;
00252   }
00253 };
00254 
00255 
00256 template <class Types>
00257 class CYapfDestinationTileRoadT
00258 {
00259 public:
00260   typedef typename Types::Tpf Tpf;                     
00261   typedef typename Types::TrackFollower TrackFollower;
00262   typedef typename Types::NodeList::Titem Node;        
00263   typedef typename Node::Key Key;                      
00264 
00265 protected:
00266   TileIndex    m_destTile;
00267   TrackdirBits m_destTrackdirs;
00268 
00269 public:
00270   void SetDestination(TileIndex tile, TrackdirBits trackdirs)
00271   {
00272     m_destTile = tile;
00273     m_destTrackdirs = trackdirs;
00274   }
00275 
00276 protected:
00278   Tpf& Yapf()
00279   {
00280     return *static_cast<Tpf*>(this);
00281   }
00282 
00283 public:
00285   FORCEINLINE bool PfDetectDestination(Node& n)
00286   {
00287     bool bDest = (n.m_segment_last_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.m_segment_last_td)) != TRACKDIR_BIT_NONE);
00288     return bDest;
00289   }
00290 
00291   FORCEINLINE bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
00292   {
00293     return tile == m_destTile && ((m_destTrackdirs & TrackdirToTrackdirBits(trackdir)) != TRACKDIR_BIT_NONE);
00294   }
00295 
00298   inline bool PfCalcEstimate(Node& n)
00299   {
00300     static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00301     static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00302     if (PfDetectDestination(n)) {
00303       n.m_estimate = n.m_cost;
00304       return true;
00305     }
00306 
00307     TileIndex tile = n.m_segment_last_tile;
00308     DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td);
00309     int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00310     int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00311     int x2 = 2 * TileX(m_destTile);
00312     int y2 = 2 * TileY(m_destTile);
00313     int dx = abs(x1 - x2);
00314     int dy = abs(y1 - y2);
00315     int dmin = min(dx, dy);
00316     int dxy = abs(dx - dy);
00317     int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00318     n.m_estimate = n.m_cost + d;
00319     assert(n.m_estimate >= n.m_parent->m_estimate);
00320     return true;
00321   }
00322 };
00323 
00324 
00325 
00326 template <class Types>
00327 class CYapfFollowRoadT
00328 {
00329 public:
00330   typedef typename Types::Tpf Tpf;                     
00331   typedef typename Types::TrackFollower TrackFollower;
00332   typedef typename Types::NodeList::Titem Node;        
00333   typedef typename Node::Key Key;                      
00334 
00335 protected:
00337   FORCEINLINE Tpf& Yapf()
00338   {
00339     return *static_cast<Tpf*>(this);
00340   }
00341 
00342 public:
00343 
00347   inline void PfFollowNode(Node& old_node)
00348   {
00349     TrackFollower F(Yapf().GetVehicle());
00350     if (F.Follow(old_node.m_segment_last_tile, old_node.m_segment_last_td)) {
00351       Yapf().AddMultipleNodes(&old_node, F);
00352     }
00353   }
00354 
00356   FORCEINLINE char TransportTypeChar() const
00357   {
00358     return 'r';
00359   }
00360 
00361   static Trackdir stChooseRoadTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir)
00362   {
00363     Tpf pf;
00364     return pf.ChooseRoadTrack(v, tile, enterdir);
00365   }
00366 
00367   FORCEINLINE Trackdir ChooseRoadTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir)
00368   {
00369     /* handle special case - when next tile is destination tile */
00370     if (tile == v->dest_tile) {
00371       /* choose diagonal trackdir reachable from enterdir */
00372       return DiagDirToDiagTrackdir(enterdir);
00373     }
00374     /* our source tile will be the next vehicle tile (should be the given one) */
00375     TileIndex src_tile = tile;
00376     /* get available trackdirs on the start tile */
00377     TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes));
00378     /* select reachable trackdirs only */
00379     src_trackdirs &= DiagdirReachesTrackdirs(enterdir);
00380 
00381     /* get available trackdirs on the destination tile */
00382     TileIndex dest_tile = v->dest_tile;
00383     TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(dest_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes));
00384 
00385     /* set origin and destination nodes */
00386     Yapf().SetOrigin(src_tile, src_trackdirs);
00387     Yapf().SetDestination(dest_tile, dest_trackdirs);
00388 
00389     /* find the best path */
00390     Yapf().FindPath(v);
00391 
00392     /* if path not found - return INVALID_TRACKDIR */
00393     Trackdir next_trackdir = INVALID_TRACKDIR;
00394     Node *pNode = Yapf().GetBestNode();
00395     if (pNode != NULL) {
00396       /* path was found or at least suggested
00397        * walk through the path back to its origin */
00398       while (pNode->m_parent != NULL) {
00399         pNode = pNode->m_parent;
00400       }
00401       /* return trackdir from the best origin node (one of start nodes) */
00402       Node& best_next_node = *pNode;
00403       assert(best_next_node.GetTile() == tile);
00404       next_trackdir = best_next_node.GetTrackdir();
00405     }
00406     return next_trackdir;
00407   }
00408 
00409   static uint stDistanceToTile(const Vehicle *v, TileIndex tile)
00410   {
00411     Tpf pf;
00412     return pf.DistanceToTile(v, tile);
00413   }
00414 
00415   FORCEINLINE uint DistanceToTile(const Vehicle *v, TileIndex dst_tile)
00416   {
00417     /* handle special case - when current tile is the destination tile */
00418     if (dst_tile == v->tile) {
00419       /* distance is zero in this case */
00420       return 0;
00421     }
00422 
00423     if (!SetOriginFromVehiclePos(v)) return UINT_MAX;
00424 
00425     /* set destination tile, trackdir
00426      *   get available trackdirs on the destination tile */
00427     TrackdirBits dst_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes));
00428     Yapf().SetDestination(dst_tile, dst_td_bits);
00429 
00430     /* if path not found - return distance = UINT_MAX */
00431     uint dist = UINT_MAX;
00432 
00433     /* find the best path */
00434     if (!Yapf().FindPath(v)) return dist;
00435 
00436     Node *pNode = Yapf().GetBestNode();
00437     if (pNode != NULL) {
00438       /* path was found
00439        * get the path cost estimate */
00440       dist = pNode->GetCostEstimate();
00441     }
00442 
00443     return dist;
00444   }
00445 
00447   FORCEINLINE bool SetOriginFromVehiclePos(const Vehicle *v)
00448   {
00449     /* set origin (tile, trackdir) */
00450     TileIndex src_tile = v->tile;
00451     Trackdir src_td = GetVehicleTrackdir(v);
00452     if ((TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(src_td)) == 0) {
00453       /* sometimes the roadveh is not on the road (it resides on non-existing track)
00454        * how should we handle that situation? */
00455       return false;
00456     }
00457     Yapf().SetOrigin(src_tile, TrackdirToTrackdirBits(src_td));
00458     return true;
00459   }
00460 
00461   static Depot *stFindNearestDepot(const Vehicle *v, TileIndex tile, Trackdir td)
00462   {
00463     Tpf pf;
00464     return pf.FindNearestDepot(v, tile, td);
00465   }
00466 
00467   FORCEINLINE Depot *FindNearestDepot(const Vehicle *v, TileIndex tile, Trackdir td)
00468   {
00469     /* set origin and destination nodes */
00470     Yapf().SetOrigin(tile, TrackdirToTrackdirBits(td));
00471 
00472     /* find the best path */
00473     bool bFound = Yapf().FindPath(v);
00474     if (!bFound) return false;
00475 
00476     /* some path found
00477      * get found depot tile */
00478     Node *n = Yapf().GetBestNode();
00479     TileIndex depot_tile = n->m_segment_last_tile;
00480     assert(IsRoadDepotTile(depot_tile));
00481     Depot *ret = GetDepotByTile(depot_tile);
00482     return ret;
00483   }
00484 
00485   static bool stFindNearestRoadVehicleCompatibleStop(const Vehicle *v, TileIndex tile, TileIndex destTile, Trackdir td, StationID sid, TileIndex *stop_tile)
00486   {
00487     Tpf pf;
00488     return pf.FindNearestRoadVehicleCompatibleStop(v, tile, destTile, td, sid, stop_tile);
00489   }
00490 
00491   FORCEINLINE bool FindNearestRoadVehicleCompatibleStop(const Vehicle *v, TileIndex tile, TileIndex destTile, Trackdir td, StationID sid, TileIndex *stop_tile)
00492   {
00493     /* set origin and destination nodes */
00494     Yapf().SetOrigin(tile, TrackdirToTrackdirBits(td));
00495     Yapf().SetDestination(v, sid, destTile);
00496 
00497     /* find the best path */
00498     bool bFound = Yapf().FindPath(v);
00499     if (!bFound) return false;
00500 
00501     /* some path found
00502      * get found depot tile */
00503     const Node *n = Yapf().GetBestNode();
00504 
00505     *stop_tile = n->m_segment_last_tile;
00506     return true;
00507   }
00508 };
00509 
00510 template <class Tpf_, class Tnode_list, template <class Types> class Tdestination>
00511 struct CYapfRoad_TypesT
00512 {
00513   typedef CYapfRoad_TypesT<Tpf_, Tnode_list, Tdestination>  Types;
00514 
00515   typedef Tpf_                              Tpf;
00516   typedef CFollowTrackRoad                  TrackFollower;
00517   typedef Tnode_list                        NodeList;
00518   typedef CYapfBaseT<Types>                 PfBase;
00519   typedef CYapfFollowRoadT<Types>           PfFollow;
00520   typedef CYapfOriginTileT<Types>           PfOrigin;
00521   typedef Tdestination<Types>               PfDestination;
00522   typedef CYapfSegmentCostCacheNoneT<Types> PfCache;
00523   typedef CYapfCostRoadT<Types>             PfCost;
00524 };
00525 
00526 struct CYapfRoad1         : CYapfT<CYapfRoad_TypesT<CYapfRoad1        , CRoadNodeListTrackDir, CYapfDestinationTileRoadT    > > {};
00527 struct CYapfRoad2         : CYapfT<CYapfRoad_TypesT<CYapfRoad2        , CRoadNodeListExitDir , CYapfDestinationTileRoadT    > > {};
00528 
00529 struct CYapfRoadAnyDepot1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot1, CRoadNodeListTrackDir, CYapfDestinationAnyDepotRoadT> > {};
00530 struct CYapfRoadAnyDepot2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot2, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
00531 
00532 struct CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation1, CRoadNodeListTrackDir, CYapfDestinationAnyRoadVehicleCompatibleStopOfGivenStationT> > {};
00533 struct CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation2, CRoadNodeListExitDir , CYapfDestinationAnyRoadVehicleCompatibleStopOfGivenStationT> > {};
00534 
00535 
00536 Trackdir YapfChooseRoadTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir)
00537 {
00538   /* default is YAPF type 2 */
00539   typedef Trackdir (*PfnChooseRoadTrack)(const Vehicle*, TileIndex, DiagDirection);
00540   PfnChooseRoadTrack pfnChooseRoadTrack = &CYapfRoad2::stChooseRoadTrack; // default: ExitDir, allow 90-deg
00541 
00542   /* check if non-default YAPF type should be used */
00543   if (_settings_game.pf.yapf.disable_node_optimization) {
00544     pfnChooseRoadTrack = &CYapfRoad1::stChooseRoadTrack; // Trackdir, allow 90-deg
00545   }
00546 
00547   Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir);
00548   return td_ret;
00549 }
00550 
00551 uint YapfRoadVehDistanceToTile(const Vehicle *v, TileIndex tile)
00552 {
00553   /* default is YAPF type 2 */
00554   typedef uint (*PfnDistanceToTile)(const Vehicle*, TileIndex);
00555   PfnDistanceToTile pfnDistanceToTile = &CYapfRoad2::stDistanceToTile; // default: ExitDir, allow 90-deg
00556 
00557   /* check if non-default YAPF type should be used */
00558   if (_settings_game.pf.yapf.disable_node_optimization) {
00559     pfnDistanceToTile = &CYapfRoad1::stDistanceToTile; // Trackdir, allow 90-deg
00560   }
00561 
00562   /* measure distance in YAPF units */
00563   uint dist = pfnDistanceToTile(v, tile);
00564   /* convert distance to tiles */
00565   if (dist != UINT_MAX) {
00566     dist = (dist + YAPF_TILE_LENGTH - 1) / YAPF_TILE_LENGTH;
00567   }
00568 
00569   return dist;
00570 }
00571 
00572 Depot *YapfFindNearestRoadDepot(const Vehicle *v)
00573 {
00574   TileIndex tile = v->tile;
00575   Trackdir trackdir = GetVehicleTrackdir(v);
00576   if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(trackdir)) == 0) {
00577     return NULL;
00578   }
00579 
00580   /* handle the case when our vehicle is already in the depot tile */
00581   if (IsRoadDepotTile(tile)) {
00582     /* only what we need to return is the Depot* */
00583     return GetDepotByTile(tile);
00584   }
00585 
00586   /* default is YAPF type 2 */
00587   typedef Depot *(*PfnFindNearestDepot)(const Vehicle*, TileIndex, Trackdir);
00588   PfnFindNearestDepot pfnFindNearestDepot = &CYapfRoadAnyDepot2::stFindNearestDepot;
00589 
00590   /* check if non-default YAPF type should be used */
00591   if (_settings_game.pf.yapf.disable_node_optimization) {
00592     pfnFindNearestDepot = &CYapfRoadAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg
00593   }
00594 
00595   Depot *ret = pfnFindNearestDepot(v, tile, trackdir);
00596   return ret;
00597 }
00598 
00599 bool YapfFindNearestRoadVehicleCompatibleStop(const Vehicle *v, StationID station, TileIndex *stop_tile)
00600 {
00601   *stop_tile = INVALID_TILE;
00602 
00603   const RoadStop *rs = GetStation(station)->GetPrimaryRoadStop(v);
00604   if (rs == NULL) return false;
00605 
00606   TileIndex tile = v->tile;
00607   Trackdir trackdir = GetVehicleTrackdir(v);
00608   if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(trackdir)) == 0) {
00609     return false;
00610   }
00611 
00612   /* default is YAPF type 2 */
00613   typedef bool (*PfnFindNearestRoadVehicleCompatibleStop)(const Vehicle*, TileIndex, TileIndex, Trackdir, StationID, TileIndex*);
00614   PfnFindNearestRoadVehicleCompatibleStop pfnFindNearestRoadVehicleCompatibleStop = &CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation2::stFindNearestRoadVehicleCompatibleStop;
00615 
00616   /* check if non-default YAPF type should be used */
00617   if (_settings_game.pf.yapf.disable_node_optimization) {
00618     pfnFindNearestRoadVehicleCompatibleStop = &CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation1::stFindNearestRoadVehicleCompatibleStop; // Trackdir, allow 90-deg
00619   }
00620 
00621   bool ret = pfnFindNearestRoadVehicleCompatibleStop(v, tile, rs->xy, trackdir, station, stop_tile);
00622   return ret;
00623 }

Generated on Mon Dec 14 21:00:05 2009 for OpenTTD by  doxygen 1.5.6