Old revision #pubn57tm0 | New revision #pbcgoaplf | ||
---|---|---|---|
1 | Index: 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; | ||
46 | Index: 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) | ||
65 | Index: 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 | +} | ||
86 | Index: 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 */ | ||
1 | Index: src/pathfinder/yapf/yapf.h | 104 | Index: src/pathfinder/yapf/yapf.h |
2 | =================================================================== | 105 | =================================================================== |
3 | --- src/pathfinder/yapf/yapf.h (revision 278 | 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,1 | 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 */ |
20 | |||
21 | |||
22 | |||
23 | |||
24 | |||
25 | |||
26 | |||
27 | |||
28 | |||
29 | |||
30 | |||
31 | |||
32 | |||
33 | |||
34 | |||
35 | |||
36 | |||
37 | |||
38 | |||
39 | |||
40 | |||
41 | |||
42 | |||
43 | |||
44 | |||
45 | |||
46 | Index: src/pathfinder/yapf/yapf_ship.cpp | 121 | Index: src/pathfinder/yapf/yapf_ship.cpp |
47 | =================================================================== | 122 | =================================================================== |
48 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 278 | 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,4 | 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 | } | … | … |
70 | + */ | 145 | + */ |
71 | + inline bool FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed) | 146 | + inline bool FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed) |
72 | + { | 147 | + { |
73 | + Tpf pf1; | 73 | + Tpf pf; |
74 | + Tpf pf2; | ||
75 | + /* Set origin. */ | 149 | + /* Set origin. */ |
76 | + pf1.SetOrigin(tile, TrackdirToTrackdirBits(td1)); | 150 | + pf.SetOrigin(tile, TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2)); |
77 | + pf2.SetOrigin(tile, TrackdirToTrackdirBits(td2)); | 151 | + |
78 | + | 152 | + /* find the best path */ |
79 | + bool path_found1 = pf1.FindPath(v); | 153 | + bool bFound = pf.FindPath(v); |
80 | + bool path_found2 = pf2.FindPath(v); | 154 | + if (!bFound) return false; |
81 | + if (!path_found1 && !path_found2) return false; | 155 | + |
82 | + | 156 | + /* some path found |
83 | + Node *n; | 157 | + * get found depot tile */ |
84 | + if (path_found1 || path_found2) { | 158 | + Node *n = pf.GetBestNode(); |
85 | + n = path_found1 ? pf1.GetBestNode() : pf2.GetBestNode(); | 159 | + *depot_tile = n->m_key.m_tile; |
86 | + *depot_tile = n->m_segment_last_tile; | 160 | + |
87 | + *reversed = !path_found1 && path_found2; | 161 | + /* walk through the path back to the origin */ |
162 | + Node *pNode = n; | ||
163 | + while (pNode->m_parent != NULL) { | ||
164 | + pNode = pNode->m_parent; | ||
88 | + } | 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); | ||
89 | + return true; | 169 | + return true; |
90 | + } | 170 | + } |
91 | }; | 171 | }; |
92 | 172 | ||
93 | /** Cost Provider module of YAPF for ships */ | 173 | /** Cost Provider module of YAPF for ships */ |
94 | @@ -188,15 +2 | 94 | @@ -188,15 +230,54 @@ |
95 | } | 175 | } |
96 | }; | 176 | }; |
97 | 177 | … | … |
113 | + /** 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 */ |
114 | + inline bool PfDetectDestination(Node &n) | 194 | + inline bool PfDetectDestination(Node &n) |
115 | + { | 195 | + { |
116 | + bool bDest = IsShipDepotTile(n.m_segment_last_tile) && GetShipDepotPart(n.m_segment_last_tile) == DEPOT_PART_NORTH; | 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); | ||
117 | + return bDest; | 198 | + return bDest; |
118 | + } | 199 | + } |
119 | + | 200 | + |
120 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) | 201 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) |
121 | + { | 202 | + { |
122 | + return | 122 | + 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); |
123 | + } | 204 | + } |
124 | + | 205 | + |
125 | + /** | 206 | + /** | … | … |
147 | 228 | ||
148 | /** Tpf - pathfinder type */ | 229 | /** Tpf - pathfinder type */ |
149 | typedef Tpf_ Tpf; | 230 | typedef Tpf_ Tpf; |
150 | @@ -215,12 +29 | 150 | @@ -215,12 +296,16 @@ |
151 | }; | 232 | }; |
152 | 233 | ||
153 | /* 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 */ |
154 | -struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , CShipNodeListTrackDir> > {}; | 235 | -struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , CShipNodeListTrackDir> > {}; |
155 | +struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1 , CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationTileT | 155 | +struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1 , CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationTileT> > {}; |
156 | /* 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 */ |
157 | -struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {}; | 238 | -struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {}; |
158 | +struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2 , CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationTileT | 158 | +struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2 , CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationTileT> > {}; |
159 | /* 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 */ |
160 | -struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {}; | 241 | -struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {}; |
161 | +struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3 , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT | 161 | +struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3 , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT> > {}; |
162 |
| 162 | |
163 | +struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT | 163 | +struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {}; |
164 | +struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT | 164 | +struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT> > {}; |
165 | +struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT | 165 | +struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {}; |
166 | + | 247 | + |
167 | /** Ship controller helper - path finder invoker */ | 248 | /** Ship controller helper - path finder invoker */ |
168 | 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) |
169 | { | 250 | { |
170 | @@ -239,6 +3 | 170 | @@ -239,6 +324,31 @@ |
171 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; | 252 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; |
172 | } | 253 | } |
173 | 254 | ||
174 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_ | 174 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance) |
175 | +{ | 256 | +{ |
176 | + FindDepotData fdd; | 257 | + FindDepotData fdd; |
177 | + | 258 | + | … | … |
191 | + } | 272 | + } |
192 | + | 273 | + |
193 | + bool ret = pfnFindNearestDepot(v, tile, td, td_rev, &fdd.tile, &fdd.reverse); | 274 | + bool ret = pfnFindNearestDepot(v, tile, td, td_rev, &fdd.tile, &fdd.reverse); |
194 | + fdd.best_length = ret ? max_penalty / 2 : UINT_MAX; // some fake distance or NOT_FOUND | 275 | + |
276 | + fdd.best_length = ret ? DistanceManhattan(tile, fdd.tile) : UINT_MAX; // distance manhattan or NOT_FOUND | ||
195 | + return fdd; | 277 | + return fdd; |
196 | +} | 278 | +} |
197 | + | 279 | + | … | … |
200 | Trackdir td = v->GetVehicleTrackdir(); | 282 | Trackdir td = v->GetVehicleTrackdir(); |
201 | Index: src/ship_cmd.cpp | 283 | Index: src/ship_cmd.cpp |
202 | =================================================================== | 284 | =================================================================== |
203 | --- src/ship_cmd.cpp (revision 278 | 203 | --- src/ship_cmd.cpp (revision 27833) |
204 | +++ src/ship_cmd.cpp (working copy) | 286 | +++ src/ship_cmd.cpp (working copy) |
205 | @@ -138, | 205 | @@ -138,7 +138,7 @@ |
206 | result->Set(_ship_sprites[spritenum] + direction); | 288 | result->Set(_ship_sprites[spritenum] + direction); |
207 | } | 289 | } |
208 | 290 | ||
209 | -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 | |||
210 | +static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance) | 309 | +static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance) |
211 | { | 211 | +{ |
212 | - /* Find the closest depot */ | 212 | + if ((IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) && IsTileOwner(v->tile, v->owner)) return FindDepotData(v->tile, 0); |
213 | - const Depot *depot; | 213 | + |
214 | - const Depot *best_depot = NULL; | ||
215 | - /* If we don't have a maximum distance, i.e. distance = 0, | ||
216 | - * we want to find any depot so the best distance of no | ||
217 | - * depot must be more than any correct distance. On the | ||
218 | - * other hand if we have set a maximum distance, any depot | ||
219 | - * further away than max_distance can safely be ignored. */ | ||
220 | - uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1; | ||
221 | + if (IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) return FindDepotData(v->tile, 0); | ||
222 | |||
223 | - FOR_ALL_DEPOTS(depot) { | ||
224 | - TileIndex tile = depot->xy; | ||
225 | - if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) { | ||
226 | - uint dist = DistanceManhattan(tile, v->tile); | ||
227 | - if (dist < best_dist) { | ||
228 | - best_dist = dist; | ||
229 | - best_depot = depot; | ||
230 | - } | ||
231 | - } | ||
232 | + switch (_settings_game.pf.pathfinder_for_ships) { | 313 | + switch (_settings_game.pf.pathfinder_for_ships) { |
233 | + | 233 | + case VPF_OPF: return OPFShipFindNearestDepot(v, max_distance); |
234 | + | 234 | + case VPF_NPF: return NPFShipFindNearestDepot(v, max_distance); |
235 | + case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance); | 316 | + case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance); |
236 | + | 317 | + |
237 | + default: NOT_REACHED(); | 318 | + default: NOT_REACHED(); |
238 | } | 238 | + } |
239 | - | 239 | +} |
240 | - return best_depot; | 240 | + |
241 | } | ||
242 | |||
243 | static void CheckIfShipNeedsService(Vehicle *v) | 322 | static void CheckIfShipNeedsService(Vehicle *v) |
244 | @@ -180,9 +167,9 @@ | 323 | { |
324 | if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return; | ||
325 | @@ -180,9 +198,9 @@ | ||
245 | default: NOT_REACHED(); | 326 | default: NOT_REACHED(); |
246 | } | 327 | } |
247 | 328 | ||
248 | - const Depot *depot = FindClosestShipDepot(v, max_distance); | 329 | - const Depot *depot = FindClosestShipDepot(v, max_distance); |
249 | + const FindDepotData | 249 | + const FindDepotData sfdd = FindClosestReachableShipDepot(Ship::From(v), max_distance); |
250 | 331 | ||
251 | - if (depot == NULL) { | 332 | - if (depot == NULL) { |
252 | + if ( | 252 | + if (sfdd.best_length == UINT_MAX || sfdd.best_length >= max_distance) { |
253 | if (v->current_order.IsType(OT_GOTO_DEPOT)) { | 334 | if (v->current_order.IsType(OT_GOTO_DEPOT)) { |
254 | v->current_order.MakeDummy(); | 335 | v->current_order.MakeDummy(); |
255 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); | 336 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); |
256 | @@ -190,8 + | 256 | @@ -190,8 +208,8 @@ |
257 | return; | 338 | return; |
258 | } | 339 | } |
259 | 340 | ||
260 | - v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); | 341 | - v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); |
261 | - v->dest_tile = depot->xy; | 342 | - v->dest_tile = depot->xy; |
262 | + v->current_order.MakeGoToDepot(GetDepotIndex( | 262 | + v->current_order.MakeGoToDepot(GetDepotIndex(sfdd.tile), ODTFB_SERVICE); |
263 | + v->dest_tile = | 263 | + v->dest_tile = sfdd.tile; |
264 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); | 345 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); |
265 | } | 346 | } |
266 | 347 | ||
267 | @@ -712,12 + | 267 | @@ -712,12 +730,15 @@ |
268 | 349 | ||
269 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) | 350 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) |
270 | { | 351 | { |
271 | - const Depot *depot = FindClosestShipDepot(this, 0); | 352 | - const Depot *depot = FindClosestShipDepot(this, 0); |
272 | + FindDepotData sfdd = FindClosestReachableShipDepot(this, 0); | 353 | + FindDepotData sfdd = FindClosestReachableShipDepot(this, 0); |
273 | + if (sfdd.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 | + } | ||
274 | 358 | ||
275 | - if (depot == NULL) return false; | 359 | - if (depot == NULL) return false; |
276 | + if (location | 276 | + if (location != NULL) *location = sfdd.tile; |
277 | + if (destination != NULL) *destination = GetDepotIndex(sfdd.tile); | 361 | + if (destination != NULL) *destination = GetDepotIndex(sfdd.tile); |
362 | + if (reverse != NULL) *reverse = sfdd.reverse; | ||
278 | 363 | ||
279 | - if (location != NULL) *location = depot->xy; | 364 | - if (location != NULL) *location = depot->xy; |
280 | - if (destination != NULL) *destination = depot->index; | 365 | - if (destination != NULL) *destination = depot->index; |