Loading

Revision differences

Old revision #ppqwyyw9sNew revision #pbcgoaplf
  1Index: src/pathfinder/npf/npf.cpp  
  2===================================================================  
  3--- src/pathfinder/npf/npf.cpp    (revision 27833)  
  4+++ src/pathfinder/npf/npf.cpp    (working copy)  
  5@@ -536,8 +536,13 @@  
  6     AyStarUserData *user = (AyStarUserData *)as->user_data;  
  7     /* It's not worth caching the result with NPF_FLAG_IS_TARGET here as below,  
  8      * since checking the cache not that much faster than the actual check */  
  9-    return IsDepotTypeTile(current->path.node.tile, user->type) ?  
  10-        AYSTAR_FOUND_END_NODE : AYSTAR_DONE;  
  11+    if (user->type != TRANSPORT_WATER) {  
  12+        return IsDepotTypeTile(current->path.node.tile, user->type) ?  
  13+            AYSTAR_FOUND_END_NODE : AYSTAR_DONE;  
  14+    } else {  
  15+        return IsShipDepotTile(current->path.node.tile) && GetShipDepotPart(current->path.node.tile) == DEPOT_PART_NORTH && IsTileOwner(current->path.node.tile, user->owner) ?  
  16+            AYSTAR_FOUND_END_NODE : AYSTAR_DONE;  
  17+    }  
  18 }  
  19   
  20 /** Find any safe and free tile. */  
  21@@ -1161,6 +1166,24 @@  
  22   
  23 /*** Ships ***/  
  24   
  25+FindDepotData NPFShipFindNearestDepot(const Ship *v, int max_distance)  
  26+{  
  27+    Trackdir trackdir = v->GetVehicleTrackdir();  
  28+    Trackdir trackdir_rev = ReverseTrackdir(trackdir);  
  29+    NPFFindStationOrTileData fstd;  
  30+    fstd.v = v;  
  31+    fstd.reserve_path = false;  
  32+  
  33+    assert(trackdir != INVALID_TRACKDIR);  
  34+    AyStarUserData user = { v->owner, TRANSPORT_WATER, INVALID_RAILTYPES, ROADTYPES_NONE };  
  35+    NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, v->tile, trackdir_rev, false, &fstd, &user, NPF_INFINITE_PENALTY);  
  36+    if (ftd.best_bird_dist != 0) return FindDepotData();  
  37+  
  38+    /* Found target */  
  39+    /* Our caller wants the distance to depot. We provide it in distance manhattan */  
  40+    return FindDepotData(ftd.node.tile, DistanceManhattan(v->tile, ftd.node.tile), NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE));  
  41+}  
  42+  
  43 Track NPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)  
  44 {  
  45     NPFFindStationOrTileData fstd;  
  46Index: src/pathfinder/npf/npf_func.h  
  47===================================================================  
  48--- src/pathfinder/npf/npf_func.h    (revision 27833)  
  49+++ src/pathfinder/npf/npf_func.h    (working copy)  
  50@@ -39,6 +39,14 @@  
  51 Trackdir NPFRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found);  
  52   
  53 /**  
  54+ * Used when user sends ship to the nearest depot or if ship needs servicing using NPF  
  55+ * @param v            ship that needs to go to some depot  
  56+ * @param max_distance not used  
  57+ * @return             the data about the depot  
  58+ */  
  59+FindDepotData NPFShipFindNearestDepot(const Ship *v, int max_distance);  
  60+  
  61+/**  
  62  * Finds the best path for given ship using NPF.  
  63  * @param v        the ship that needs to find a path  
  64  * @param tile     the tile to find the path from (should be next tile the ship is about to enter)  
  65Index: src/pathfinder/opf/opf_ship.cpp  
  66===================================================================  
  67--- src/pathfinder/opf/opf_ship.cpp    (revision 27833)  
  68+++ src/pathfinder/opf/opf_ship.cpp    (working copy)  
  69@@ -14,6 +14,7 @@  
  70 #include "../../tunnelbridge.h"  
  71 #include "../../ship.h"  
  72 #include "../../core/random_func.hpp"  
  73+#include "../pathfinder_type.h"  
  74   
  75 #include "../../safeguards.h"  
  76   
  77@@ -212,3 +213,8 @@  
  78     if (dist <= distr) return track;  
  79     return INVALID_TRACK; // We could better reverse  
  80 }  
  81+  
  82+FindDepotData OPFShipFindNearestDepot(const Ship *v, int max_distance) // todo  
  83+{  
  84+    return FindDepotData();  
  85+}  
  86Index: src/pathfinder/opf/opf_ship.h  
  87===================================================================  
  88--- src/pathfinder/opf/opf_ship.h    (revision 27833)  
  89+++ src/pathfinder/opf/opf_ship.h    (working copy)  
  90@@ -28,4 +28,13 @@  
  91  */  
  92 Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found);  
  93   
  94+/**  
  95+ * Used when user sends ship to the nearest depot or if ship needs servicing using OPF.  
  96+ * @todo               this is just a placeholder, it's currently not implemented  
  97+ * @param v            vehicle that needs to go to some depot  
  98+ * @param max_distance not used  
  99+ * @return             the data about the depot  
  100+ */  
  101+FindDepotData OPFShipFindNearestDepot(const Ship *v, int max_distance);  
  102+  
  103 #endif /* OPF_SHIP_H */  
1Index: src/pathfinder/yapf/yapf.h  104Index: src/pathfinder/yapf/yapf.h  
2===================================================================  105===================================================================  
3--- src/pathfinder/yapf/yapf.h    (revision 27829)  3--- src/pathfinder/yapf/yapf.h    (revision 27833)
4+++ src/pathfinder/yapf/yapf.h    (working copy)  107+++ src/pathfinder/yapf/yapf.h    (working copy)  
5@@ -97,4 +97,14 @@  5@@ -97,4 +97,12 @@
6  */  109  */  
7 bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype);  110 bool YapfTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir td, bool override_railtype);  
8   111   
9+/**  112+/**  
10+ * Used when user sends ship to the nearest depot or if ship needs servicing using YAPF.  113+ * Used when user sends ship to the nearest depot or if ship needs servicing using YAPF.  
11+ * @param v            vehicle that needs to go to some depot  114+ * @param v            vehicle that needs to go to some depot  
12+ * @param max_distance max distance (in pathfinder penalty) from the current vehicle position  12+ * @param max_distance not used
13+ *                     (used also as optimization - the pathfinder can stop path finding if max_penalty    
14+ *                     was reached and no depot was seen)    
15+ * @return             the data about the depot  116+ * @return             the data about the depot  
16+ */  117+ */  
17+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance);  118+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance);  
18+  119+  
19 #endif /* YAPF_H */  120 #endif /* YAPF_H */  
20Index: src/pathfinder/yapf/yapf_node_ship.hpp    
21===================================================================    
22--- src/pathfinder/yapf/yapf_node_ship.hpp    (revision 27829)    
23+++ src/pathfinder/yapf/yapf_node_ship.hpp    (working copy)    
24@@ -14,8 +14,20 @@    
25     
26 /** Yapf Node for ships */    
27 template <class Tkey_>    
28-struct CYapfShipNodeT : CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> > { };    
29+struct CYapfShipNodeT : CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> > {    
30+    typedef CYapfNodeT<Tkey_, CYapfShipNodeT<Tkey_> > base;    
31     
32+    TileIndex m_segment_last_tile;    
33+    Trackdir  m_segment_last_td;    
34+    
35+    void Set(CYapfShipNodeT *parent, TileIndex tile, Trackdir td, bool is_choice)    
36+    {    
37+        base::Set(parent, tile, td, is_choice);    
38+        m_segment_last_tile = tile;    
39+        m_segment_last_td = td;    
40+    }    
41+};    
42+    
43 /* now define two major node types (that differ by key type) */    
44 typedef CYapfShipNodeT<CYapfNodeKeyExitDir>  CYapfShipNodeExitDir;    
45 typedef CYapfShipNodeT<CYapfNodeKeyTrackDir> CYapfShipNodeTrackDir;    
46Index: src/pathfinder/yapf/yapf_ship.cpp  121Index: src/pathfinder/yapf/yapf_ship.cpp  
47===================================================================  122===================================================================  
48--- src/pathfinder/yapf/yapf_ship.cpp    (revision 27829)  48--- src/pathfinder/yapf/yapf_ship.cpp    (revision 27833)
49+++ src/pathfinder/yapf/yapf_ship.cpp    (working copy)  124+++ src/pathfinder/yapf/yapf_ship.cpp    (working copy)  
50@@ -139,6 +139,31 @@  50@@ -139,6 +139,48 @@
51         assert(best_trackdir == td1 || best_trackdir == td2);  126         assert(best_trackdir == td1 || best_trackdir == td2);  
52         return best_trackdir == td2;  127         return best_trackdir == td2;  
53     }  128     }  
  129+  
  130+    static bool stFindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed)  
  131+    {  
  132+        Tpf pf;  
  133+        bool result = pf.FindNearestDepot(v, tile, td1, td2, depot_tile, reversed);  
  134+        return result;  
  135+    }  
54+  136+  
55+    /**  137+    /**  
56+     * Find the best depot for a ship.  138+     * Find the best depot for a ship.  
57+     * @param v Vehicle  139+     * @param v Vehicle  
58+     * @param tile Tile of the vehicle.  140+     * @param tile Tile of the vehicle.  
59+     * @param td Trackdir of the vehicle.  59+     * @param td1 Trackdir of the vehicle.
60+     * @param max_distance max length (penalty) for paths.  60+     * @param td2 reversed Trackdir of the vehicle.
61+     * @todo max_distance not used by YAPF for ships.  61+     * @param depot_tile the tile of the depot.
62+     *       It can be removed or copy the SetMaxCost() strategy  62+     * @param reversed whether the path to depot was found on reversed Trackdir.
63+     *       applied in YAPF for rail. The best depot can be at    
64+     *       a distance greater than max_distance.    
65+     */  145+     */  
66+    static FindDepotData FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td, int max_distance)  66+    inline bool FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed)
67+    {  147+    {  
68+        Tpf pf;  148+        Tpf pf;  
69+        /* Set origin. */  149+        /* Set origin. */  
70+        pf.SetOrigin(tile, TrackdirToTrackdirBits(td));  150+        pf.SetOrigin(tile, TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2));
71+  151+
72+        /* Find the best path and return if no depot is found. */  152+        /* find the best path */
73+        if (!pf.FindPath(v)) return FindDepotData();  153+        bool bFound = pf.FindPath(v);
74+  154+        if (!bFound) return false;
75+        /* Return the cost of the best path and its depot. */  155+
   156+        /* some path found
   157+         * get found depot tile */
76+        Node *n = pf.GetBestNode();  158+        Node *n = pf.GetBestNode();  
77+        return FindDepotData(n->m_segment_last_tile, n->m_cost);  159+        *depot_tile = n->m_key.m_tile;
   160+
   161+        /* walk through the path back to the origin */
   162+        Node *pNode = n;
   163+        while (pNode->m_parent != NULL) {
   164+            pNode = pNode->m_parent;
   165+        }
   166+
   167+        /* if the origin node is the ship's Trackdir then we didn't reverse */
   168+        *reversed = (pNode->m_key.m_td != td1);
   169+        return true;
78+    }  170+    }  
79 };  171 };  
80   172   
81 /** Cost Provider module of YAPF for ships */  173 /** Cost Provider module of YAPF for ships */  
82@@ -188,15 +213,53 @@  82@@ -188,15 +230,54 @@
83     }  175     }  
84 };  176 };  
85   177   
  
101+    /** Called by YAPF to detect if node ends in the desired destination */  193+    /** Called by YAPF to detect if node ends in the desired destination */  
102+    inline bool PfDetectDestination(Node &n)  194+    inline bool PfDetectDestination(Node &n)  
103+    {  195+    {  
104+        bool bDest = IsShipDepotTile(n.m_segment_last_tile);  196+       
   197+        bool bDest = (IsShipDepotTile(n.m_key.m_tile) && GetShipDepotPart(n.m_key.m_tile) == DEPOT_PART_NORTH) && IsTileOwner(n.m_key.m_tile, Yapf().GetVehicle()->owner);
105+        return bDest;  198+        return bDest;  
106+    }  199+    }  
107+  200+  
108+    inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)  201+    inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)  
109+    {  202+    {  
110+        return IsShipDepotTile(tile);  110+        return (IsShipDepotTile(n.m_key.m_tile) && GetShipDepotPart(n.m_key.m_tile) == DEPOT_PART_NORTH) && IsTileOwner(n.m_key.m_tile, Yapf().GetVehicle()->owner);
111+    }  204+    }  
112+  205+  
113+    /**  206+    /**  
  
135   228   
136     /** Tpf - pathfinder type */  229     /** Tpf - pathfinder type */  
137     typedef Tpf_                              Tpf;  230     typedef Tpf_                              Tpf;  
138@@ -215,12 +278,16 @@  138@@ -215,12 +296,16 @@
139 };  232 };  
140   233   
141 /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */  234 /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */  
142-struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater    , CShipNodeListTrackDir> > {};  235-struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater    , CShipNodeListTrackDir> > {};  
143+struct CYapfShip1         : CYapfT<CYapfShip_TypesT<CYapfShip1        , CFollowTrackWater    , CShipNodeListTrackDir, CYapfDestinationTileT > > {};  143+struct CYapfShip1         : CYapfT<CYapfShip_TypesT<CYapfShip1        , CFollowTrackWater    , CShipNodeListTrackDir, CYapfDestinationTileT> > {};
144 /* YAPF type 2 - uses TileIndex/DiagDirection as Node key, allows 90-deg turns */  237 /* YAPF type 2 - uses TileIndex/DiagDirection as Node key, allows 90-deg turns */  
145-struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater    , CShipNodeListExitDir > > {};  238-struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater    , CShipNodeListExitDir > > {};  
146+struct CYapfShip2         : CYapfT<CYapfShip_TypesT<CYapfShip2        , CFollowTrackWater    , CShipNodeListExitDir , CYapfDestinationTileT > > {};  146+struct CYapfShip2         : CYapfT<CYapfShip_TypesT<CYapfShip2        , CFollowTrackWater    , CShipNodeListExitDir , CYapfDestinationTileT> > {};
147 /* YAPF type 3 - uses TileIndex/Trackdir as Node key, forbids 90-deg turns */  240 /* YAPF type 3 - uses TileIndex/Trackdir as Node key, forbids 90-deg turns */  
148-struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {};  241-struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {};  
149+struct CYapfShip3         : CYapfT<CYapfShip_TypesT<CYapfShip3        , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT > > {};  149+struct CYapfShip3         : CYapfT<CYapfShip_TypesT<CYapfShip3        , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT> > {};
150   150 
151+struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater    , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT > > {};  151+struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater    , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {};
152+struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater    , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT > > {};  152+struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater    , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT> > {};
153+struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT > > {};  153+struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {};
154+  247+  
155 /** Ship controller helper - path finder invoker */  248 /** Ship controller helper - path finder invoker */  
156 Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)  249 Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found)  
157 {  250 {  
158@@ -239,6 +306,27 @@  158@@ -239,6 +324,31 @@
159     return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;  252     return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK;  
160 }  253 }  
161   254   
162+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance)  255+FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance)  
163+{  256+{  
  257+    FindDepotData fdd;  
  258+  
  259+    Trackdir td = v->GetVehicleTrackdir();  
  260+    Trackdir td_rev = ReverseTrackdir(td);  
164+    TileIndex tile = v->tile;  261+    TileIndex tile = v->tile;  
165+    Trackdir trackdir = v->GetVehicleTrackdir();  165+
166+    if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & TrackdirToTrackdirBits(trackdir)) == 0) {    
167+        return FindDepotData();    
168+    }    
169+    /* default is YAPF type 2 */  263+    /* default is YAPF type 2 */  
170+    typedef FindDepotData(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, int);  170+    typedef bool(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, Trackdir, TileIndex*, bool*);
171+    PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::FindNearestDepot;  171+    PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::stFindNearestDepot;
172+  266+  
173+    /* check if non-default YAPF type should be used */  267+    /* check if non-default YAPF type should be used */  
174+    if (_settings_game.pf.forbid_90_deg) {  268+    if (_settings_game.pf.forbid_90_deg) {  
175+        pfnFindNearestDepot = &CYapfShipAnyDepot3::FindNearestDepot; // Trackdir, forbid 90-deg  175+        pfnFindNearestDepot = &CYapfShipAnyDepot3::stFindNearestDepot; // Trackdir, forbid 90-deg
176+    } else if (_settings_game.pf.yapf.disable_node_optimization) {  270+    } else if (_settings_game.pf.yapf.disable_node_optimization) {  
177+        pfnFindNearestDepot = &CYapfShipAnyDepot1::FindNearestDepot; // Trackdir, allow 90-deg  271+        pfnFindNearestDepot = &CYapfShipAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg
178+    }  272+    }
179+  273+
180+    return pfnFindNearestDepot(v, tile, trackdir, max_distance);  274+    bool ret = pfnFindNearestDepot(v, tile, td, td_rev, &fdd.tile, &fdd.reverse);
   275+
   276+    fdd.best_length = ret ? DistanceManhattan(tile, fdd.tile) : UINT_MAX; // distance manhattan or NOT_FOUND
   277+    return fdd;
181+}  278+}  
182+  279+  
183 bool YapfShipCheckReverse(const Ship *v)  280 bool YapfShipCheckReverse(const Ship *v)  
  
185     Trackdir td = v->GetVehicleTrackdir();  282     Trackdir td = v->GetVehicleTrackdir();  
186Index: src/ship_cmd.cpp  283Index: src/ship_cmd.cpp  
187===================================================================  284===================================================================  
188--- src/ship_cmd.cpp    (revision 27829)  188--- src/ship_cmd.cpp    (revision 27833)
189+++ src/ship_cmd.cpp    (working copy)  286+++ src/ship_cmd.cpp    (working copy)  
190@@ -138,30 +138,17 @@  190@@ -138,7 +138,7 @@
191     result->Set(_ship_sprites[spritenum] + direction);  288     result->Set(_ship_sprites[spritenum] + direction);  
192 }  289 }  
193   290   
194-static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)  291-static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)  
  292+static FindDepotData FindClosestShipDepot(const Ship *v, uint max_distance)  
  293 {  
  294     /* Find the closest depot */  
  295     const Depot *depot;  
  296@@ -161,9 +161,27 @@  
  297         }  
  298     }  
  299   
  300-    return best_depot;  
  301+    FindDepotData fdd;  
  302+    if (best_depot != NULL) {  
  303+        fdd.best_length = best_dist;  
  304+        fdd.tile = best_depot->xy;  
  305+    }  
  306+    return fdd;  
  307 }  
  308   
195+static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance)  309+static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance)  
196 {  196+{
197-    /* Find the closest depot */  197+    if ((IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) && IsTileOwner(v->tile, v->owner)) return FindDepotData(v->tile, 0);
198-    const Depot *depot;  198+
199-    const Depot *best_depot = NULL;    
200-    /* If we don't have a maximum distance, i.e. distance = 0,    
201-     * we want to find any depot so the best distance of no    
202-     * depot must be more than any correct distance. On the    
203-     * other hand if we have set a maximum distance, any depot    
204-     * further away than max_distance can safely be ignored. */    
205-    uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1;    
206+    if (IsShipDepotTile(v->tile)) return FindDepotData(v->tile, 0);    
207     
208-    FOR_ALL_DEPOTS(depot) {    
209-        TileIndex tile = depot->xy;    
210-        if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) {    
211-            uint dist = DistanceManhattan(tile, v->tile);    
212-            if (dist < best_dist) {    
213-                best_dist = dist;    
214-                best_depot = depot;    
215-            }    
216-        }    
217+    switch (_settings_game.pf.pathfinder_for_ships) {  313+    switch (_settings_game.pf.pathfinder_for_ships) {  
218+//    case VPF_OPF: return OPFShipFindNearestDepot(v, max_distance); //TODO  218+    case VPF_OPF: return OPFShipFindNearestDepot(v, max_distance);
219+//    case VPF_NPF: return NPFShipFindNearestDepot(v, max_distance); //TODO  219+    case VPF_NPF: return NPFShipFindNearestDepot(v, max_distance);
220+    case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance);  316+    case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance);  
221+  317+  
222+    default: NOT_REACHED();  318+    default: NOT_REACHED();  
223     }  223+    }
224-  224+}
225-    return best_depot;  225+
226 }    
227     
228 static void CheckIfShipNeedsService(Vehicle *v)  322 static void CheckIfShipNeedsService(Vehicle *v)  
229@@ -180,9 +167,9 @@  323 {
   324     if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return;
   325@@ -180,9 +198,9 @@
230         default: NOT_REACHED();  326         default: NOT_REACHED();  
231     }  327     }  
232   328   
233-    const Depot *depot = FindClosestShipDepot(v, max_distance);  329-    const Depot *depot = FindClosestShipDepot(v, max_distance);  
234+    const FindDepotData depot = FindClosestReachableShipDepot(Ship::From(v), max_distance);  234+    const FindDepotData sfdd = FindClosestReachableShipDepot(Ship::From(v), max_distance);
235   331   
236-    if (depot == NULL) {  332-    if (depot == NULL) {  
237+    if (depot.best_length == UINT_MAX) {  237+    if (sfdd.best_length == UINT_MAX || sfdd.best_length >= max_distance) {
238         if (v->current_order.IsType(OT_GOTO_DEPOT)) {  334         if (v->current_order.IsType(OT_GOTO_DEPOT)) {  
239             v->current_order.MakeDummy();  335             v->current_order.MakeDummy();  
240             SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);  336             SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);  
241@@ -190,8 +177,8 @@  241@@ -190,8 +208,8 @@
242         return;  338         return;  
243     }  339     }  
244   340   
245-    v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);  341-    v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE);  
246-    v->dest_tile = depot->xy;  342-    v->dest_tile = depot->xy;  
247+    v->current_order.MakeGoToDepot(GetDepotIndex(depot.tile), ODTFB_SERVICE);  247+    v->current_order.MakeGoToDepot(GetDepotIndex(sfdd.tile), ODTFB_SERVICE);
248+    v->dest_tile = depot.tile;  248+    v->dest_tile = sfdd.tile;
249     SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);  345     SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);  
250 }  346 }  
251   347   
252@@ -712,12 +699,11 @@  252@@ -712,12 +730,15 @@
253   349   
254 bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)  350 bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse)  
255 {  351 {  
256-    const Depot *depot = FindClosestShipDepot(this, 0);  352-    const Depot *depot = FindClosestShipDepot(this, 0);  
257+    FindDepotData rfdd = FindClosestReachableShipDepot(this, 0);  353+    FindDepotData sfdd = FindClosestReachableShipDepot(this, 0);
258+    if (rfdd.best_length == UINT_MAX) return false;  354+    if (sfdd.best_length == UINT_MAX) {
   355+        sfdd = FindClosestShipDepot(this, 0);
   356+        if (sfdd.best_length == UINT_MAX) return false;
   357+    }
259   358   
260-    if (depot == NULL) return false;  359-    if (depot == NULL) return false;  
261+    if (location != NULL) *location = rfdd.tile;  360+    if (location    != NULL) *location = sfdd.tile;
262+    if (destination != NULL) *destination = GetDepotIndex(rfdd.tile);  361+    if (destination != NULL) *destination = GetDepotIndex(sfdd.tile);
   362+    if (reverse     != NULL) *reverse = sfdd.reverse;
263   363   
264-    if (location    != NULL) *location    = depot->xy;  364-    if (location    != NULL) *location    = depot->xy;  
265-    if (destination != NULL) *destination = depot->index;  365-    if (destination != NULL) *destination = depot->index;