Old revision #pxmwekzc2 | 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, | 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 | + | 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 +2 | 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 | 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 +2 | 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 +3 | 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 | 170 | + typedef bool(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, Trackdir, TileIndex*, bool*); |
171 | + PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2:: | 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:: | 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(); |
186 | Index: src/ship_cmd.cpp | 283 | Index: src/ship_cmd.cpp |
187 | =================================================================== | 284 | =================================================================== |
188 | --- src/ship_cmd.cpp (revision 278 | 188 | --- src/ship_cmd.cpp (revision 27833) |
189 | +++ src/ship_cmd.cpp (working copy) | 286 | +++ src/ship_cmd.cpp (working copy) |
190 | @@ -138, | 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 | + | 218 | + case VPF_OPF: return OPFShipFindNearestDepot(v, max_distance); |
219 | + | 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 | 234 | + const FindDepotData sfdd = FindClosestReachableShipDepot(Ship::From(v), max_distance); |
235 | 331 | ||
236 | - if (depot == NULL) { | 332 | - if (depot == NULL) { |
237 | + if ( | 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 + | 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( | 247 | + v->current_order.MakeGoToDepot(GetDepotIndex(sfdd.tile), ODTFB_SERVICE); |
248 | + v->dest_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 + | 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; |