Old revision #phoeeb6pa | New revision #pbcgoaplf | ||
---|---|---|---|
1 | Index: src/pathfinder/follow_track.hpp | 1 | Index: src/pathfinder/npf/npf.cpp |
2 | =================================================================== | 2 | =================================================================== |
3 | --- src/pathfinder/follow_track.hpp (revision 27829) | 3 | --- src/pathfinder/npf/npf.cpp (revision 27833) |
4 | +++ src/pathfinder/follow_track.hpp (working copy) | 4 | +++ src/pathfinder/npf/npf.cpp (working copy) |
5 | @@ -438,6 +438,21 @@ | 5 | @@ -536,8 +536,13 @@ |
6 | return true; | 6 | AyStarUserData *user = (AyStarUserData *)as->user_data; |
7 | } | 7 | /* It's not worth caching the result with NPF_FLAG_IS_TARGET here as below, |
8 | } | 8 | * since checking the cache not that much faster than the actual check */ |
9 | + | 9 | - return IsDepotTypeTile(current->path.node.tile, user->type) ? |
10 | + if (IsWaterTT()) { | 10 | - AYSTAR_FOUND_END_NODE : AYSTAR_DONE; |
11 | + /* if we reached a dead end, we can reverse the ship and continue moving */ | 11 | + if (user->type != TRANSPORT_WATER) { |
12 | + m_exitdir = ReverseDiagDir(m_exitdir); | 12 | + return IsDepotTypeTile(current->path.node.tile, user->type) ? |
13 | + /* new tile will be the same as old one */ | 13 | + AYSTAR_FOUND_END_NODE : AYSTAR_DONE; |
14 | + m_new_tile = m_old_tile; | 14 | + } else { |
15 | + /* set new trackdir bits to all reachable trackdirs */ | 15 | + return IsShipDepotTile(current->path.node.tile) && GetShipDepotPart(current->path.node.tile) == DEPOT_PART_NORTH && IsTileOwner(current->path.node.tile, user->owner) ? |
16 | + QueryNewTileTrackStatus(); | 16 | + AYSTAR_FOUND_END_NODE : AYSTAR_DONE; |
17 | + m_new_td_bits &= DiagdirReachesTrackdirs(m_exitdir); | 17 | + } |
18 | + if (m_new_td_bits != TRACKDIR_BIT_NONE) { | 18 | } |
19 | + /* we have some trackdirs reachable after reversal */ | 19 | |
20 | + return true; | 20 | /** Find any safe and free tile. */ |
21 | + } | 21 | @@ -1161,6 +1166,24 @@ |
22 | + } | 22 | |
23 | + | 23 | /*** Ships ***/ |
24 | m_err = EC_NO_WAY; | 24 | |
25 | return false; | 25 | +FindDepotData NPFShipFindNearestDepot(const Ship *v, int max_distance) |
26 | } | 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 */ | ||
27 | Index: src/pathfinder/yapf/yapf.h | 104 | Index: src/pathfinder/yapf/yapf.h |
28 | =================================================================== | 105 | =================================================================== |
29 | --- src/pathfinder/yapf/yapf.h (revision 278 | 29 | --- src/pathfinder/yapf/yapf.h (revision 27833) |
30 | +++ src/pathfinder/yapf/yapf.h (working copy) | 107 | +++ src/pathfinder/yapf/yapf.h (working copy) |
31 | @@ -97,4 +97,1 | 31 | @@ -97,4 +97,12 @@ |
32 | */ | 109 | */ |
33 | 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); |
34 | 111 | ||
35 | +/** | 112 | +/** |
36 | + * 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. |
37 | + * @param v vehicle that needs to go to some depot | 114 | + * @param v vehicle that needs to go to some depot |
38 | + * @param max_distance max distance (in pathfinder penalty) from the current vehicle position | 38 | + * @param max_distance not used |
39 | + * (used also as optimization - the pathfinder can stop path finding if max_penalty | ||
40 | + * was reached and no depot was seen) | ||
41 | + * @return the data about the depot | 116 | + * @return the data about the depot |
42 | + */ | 117 | + */ |
43 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance); | 118 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance); |
44 | + | 119 | + |
45 | #endif /* YAPF_H */ | 120 | #endif /* YAPF_H */ |
46 | |||
47 | |||
48 | |||
49 | |||
50 | |||
51 | |||
52 | |||
53 | |||
54 | |||
55 | |||
56 | |||
57 | |||
58 | |||
59 | |||
60 | |||
61 | |||
62 | |||
63 | |||
64 | |||
65 | |||
66 | |||
67 | |||
68 | |||
69 | |||
70 | |||
71 | |||
72 | Index: src/pathfinder/yapf/yapf_ship.cpp | 121 | Index: src/pathfinder/yapf/yapf_ship.cpp |
73 | =================================================================== | 122 | =================================================================== |
74 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 278 | 74 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 27833) |
75 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) | 124 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) |
76 | @@ -139,6 +139, | 76 | @@ -139,6 +139,48 @@ |
77 | assert(best_trackdir == td1 || best_trackdir == td2); | 126 | assert(best_trackdir == td1 || best_trackdir == td2); |
78 | return best_trackdir == td2; | 127 | return best_trackdir == td2; |
79 | } | 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 | + } | ||
80 | + | 136 | + |
81 | + /** | 137 | + /** |
82 | + * Find the best depot for a ship. | 138 | + * Find the best depot for a ship. |
83 | + * @param v Vehicle | 139 | + * @param v Vehicle |
84 | + * @param tile Tile of the vehicle. | 140 | + * @param tile Tile of the vehicle. |
85 | + * @param td Trackdir of the vehicle. | 85 | + * @param td1 Trackdir of the vehicle. |
86 | + * @param max_distance max length (penalty) for paths. | 86 | + * @param td2 reversed Trackdir of the vehicle. |
87 | + * @todo max_distance not used by YAPF for ships. | 87 | + * @param depot_tile the tile of the depot. |
88 | + * It can be removed or copy the SetMaxCost() strategy | 88 | + * @param reversed whether the path to depot was found on reversed Trackdir. |
89 | + * applied in YAPF for rail. The best depot can be at | ||
90 | + * a distance greater than max_distance. | ||
91 | + */ | 145 | + */ |
92 | + | 92 | + inline bool FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed) |
93 | + { | 147 | + { |
94 | + Tpf pf; | 148 | + Tpf pf; |
95 | + /* Set origin. */ | 149 | + /* Set origin. */ |
96 | + pf.SetOrigin(tile, TrackdirToTrackdirBits(td)); | 150 | + pf.SetOrigin(tile, TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2)); |
97 | + | 151 | + |
98 | + /* Find the best path and return if no depot is found. */ | 152 | + /* find the best path */ |
99 | + if (!pf.FindPath(v)) return FindDepotData(); | 153 | + bool bFound = pf.FindPath(v); |
100 | + | 154 | + if (!bFound) return false; |
101 | + /* Return the cost of the best path and its depot. */ | 155 | + |
156 | + /* some path found | ||
157 | + * get found depot tile */ | ||
102 | + Node *n = pf.GetBestNode(); | 158 | + Node *n = pf.GetBestNode(); |
103 | + 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; | ||
104 | + } | 170 | + } |
105 | }; | 171 | }; |
106 | 172 | ||
107 | /** Cost Provider module of YAPF for ships */ | 173 | /** Cost Provider module of YAPF for ships */ |
108 | @@ -188,15 +2 | 108 | @@ -188,15 +230,54 @@ |
109 | } | 175 | } |
110 | }; | 176 | }; |
111 | 177 | … | … |
127 | + /** 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 */ |
128 | + inline bool PfDetectDestination(Node &n) | 194 | + inline bool PfDetectDestination(Node &n) |
129 | + { | 195 | + { |
130 | + 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); | ||
131 | + return bDest; | 198 | + return bDest; |
132 | + } | 199 | + } |
133 | + | 200 | + |
134 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) | 201 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) |
135 | + { | 202 | + { |
136 | + return | 136 | + 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); |
137 | + } | 204 | + } |
138 | + | 205 | + |
139 | + /** | 206 | + /** | … | … |
161 | 228 | ||
162 | /** Tpf - pathfinder type */ | 229 | /** Tpf - pathfinder type */ |
163 | typedef Tpf_ Tpf; | 230 | typedef Tpf_ Tpf; |
164 | @@ -215,12 +2 | 164 | @@ -215,12 +296,16 @@ |
165 | }; | 232 | }; |
166 | 233 | ||
167 | /* 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 */ |
168 | -struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , CShipNodeListTrackDir> > {}; | 235 | -struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , CShipNodeListTrackDir> > {}; |
169 | +struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1 , CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationTileT | 169 | +struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1 , CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationTileT> > {}; |
170 | /* 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 */ |
171 | -struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {}; | 238 | -struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {}; |
172 | +struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2 , CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationTileT | 172 | +struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2 , CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationTileT> > {}; |
173 | /* 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 */ |
174 | -struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {}; | 241 | -struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3, CFollowTrackWaterNo90, CShipNodeListTrackDir> > {}; |
175 | +struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3 , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT | 175 | +struct CYapfShip3 : CYapfT<CYapfShip_TypesT<CYapfShip3 , CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationTileT> > {}; |
176 |
| 176 | |
177 | +struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT | 177 | +struct CYapfShipAnyDepot1 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot1, CFollowTrackWater , CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {}; |
178 | +struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT | 178 | +struct CYapfShipAnyDepot2 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot2, CFollowTrackWater , CShipNodeListExitDir , CYapfDestinationAnyDepotShipT> > {}; |
179 | +struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT | 179 | +struct CYapfShipAnyDepot3 : CYapfT<CYapfShip_TypesT<CYapfShipAnyDepot3, CFollowTrackWaterNo90, CShipNodeListTrackDir, CYapfDestinationAnyDepotShipT> > {}; |
180 | + | 247 | + |
181 | /** Ship controller helper - path finder invoker */ | 248 | /** Ship controller helper - path finder invoker */ |
182 | 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) |
183 | { | 250 | { |
184 | @@ -239,6 +3 | 184 | @@ -239,6 +324,31 @@ |
185 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; | 252 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; |
186 | } | 253 | } |
187 | 254 | ||
188 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance) | 255 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_distance) |
189 | +{ | 256 | +{ |
257 | + FindDepotData fdd; | ||
258 | + | ||
259 | + Trackdir td = v->GetVehicleTrackdir(); | ||
260 | + Trackdir td_rev = ReverseTrackdir(td); | ||
190 | + TileIndex tile = v->tile; | 261 | + TileIndex tile = v->tile; |
191 | + Trackdir trackdir = v->GetVehicleTrackdir(); | 191 | + |
192 | + if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & TrackdirToTrackdirBits(trackdir)) == 0) { | ||
193 | + return FindDepotData(); | ||
194 | + } | ||
195 | + /* default is YAPF type 2 */ | 263 | + /* default is YAPF type 2 */ |
196 | + typedef | 196 | + typedef bool(*PfnFindNearestDepot)(const Ship*, TileIndex, Trackdir, Trackdir, TileIndex*, bool*); |
197 | + PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2:: | 197 | + PfnFindNearestDepot pfnFindNearestDepot = &CYapfShipAnyDepot2::stFindNearestDepot; |
198 | + | 266 | + |
199 | + /* check if non-default YAPF type should be used */ | 267 | + /* check if non-default YAPF type should be used */ |
200 | + if (_settings_game.pf.forbid_90_deg) { | 268 | + if (_settings_game.pf.forbid_90_deg) { |
201 | + pfnFindNearestDepot = &CYapfShipAnyDepot3:: | 201 | + pfnFindNearestDepot = &CYapfShipAnyDepot3::stFindNearestDepot; // Trackdir, forbid 90-deg |
202 | + } else if (_settings_game.pf.yapf.disable_node_optimization) { | 270 | + } else if (_settings_game.pf.yapf.disable_node_optimization) { |
203 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::FindNearestDepot; // Trackdir, allow 90-deg | 271 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg |
204 | + } | 272 | + } |
205 | + | 273 | + |
206 | + 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; | ||
207 | +} | 278 | +} |
208 | + | 279 | + |
209 | bool YapfShipCheckReverse(const Ship *v) | 280 | bool YapfShipCheckReverse(const Ship *v) | … | … |
211 | Trackdir td = v->GetVehicleTrackdir(); | 282 | Trackdir td = v->GetVehicleTrackdir(); |
212 | Index: src/ship_cmd.cpp | 283 | Index: src/ship_cmd.cpp |
213 | =================================================================== | 284 | =================================================================== |
214 | --- src/ship_cmd.cpp (revision 278 | 214 | --- src/ship_cmd.cpp (revision 27833) |
215 | +++ src/ship_cmd.cpp (working copy) | 286 | +++ src/ship_cmd.cpp (working copy) |
216 | @@ -138, | 216 | @@ -138,7 +138,7 @@ |
217 | result->Set(_ship_sprites[spritenum] + direction); | 288 | result->Set(_ship_sprites[spritenum] + direction); |
218 | } | 289 | } |
219 | 290 | ||
220 | -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 | |||
221 | +static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance) | 309 | +static FindDepotData FindClosestReachableShipDepot(const Ship *v, int max_distance) |
222 | { | 222 | +{ |
223 | - /* Find the closest depot */ | 223 | + if ((IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) && IsTileOwner(v->tile, v->owner)) return FindDepotData(v->tile, 0); |
224 | - const Depot *depot; | 224 | + |
225 | - const Depot *best_depot = NULL; | ||
226 | - /* If we don't have a maximum distance, i.e. distance = 0, | ||
227 | - * we want to find any depot so the best distance of no | ||
228 | - * depot must be more than any correct distance. On the | ||
229 | - * other hand if we have set a maximum distance, any depot | ||
230 | - * further away than max_distance can safely be ignored. */ | ||
231 | - uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1; | ||
232 | + if (IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) return FindDepotData(v->tile, 0); | ||
233 | |||
234 | - FOR_ALL_DEPOTS(depot) { | ||
235 | - TileIndex tile = depot->xy; | ||
236 | - if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) { | ||
237 | - uint dist = DistanceManhattan(tile, v->tile); | ||
238 | - if (dist < best_dist) { | ||
239 | - best_dist = dist; | ||
240 | - best_depot = depot; | ||
241 | - } | ||
242 | - } | ||
243 | + switch (_settings_game.pf.pathfinder_for_ships) { | 313 | + switch (_settings_game.pf.pathfinder_for_ships) { |
244 | + | 244 | + case VPF_OPF: return OPFShipFindNearestDepot(v, max_distance); |
245 | + | 245 | + case VPF_NPF: return NPFShipFindNearestDepot(v, max_distance); |
246 | + case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance); | 316 | + case VPF_YAPF: return YapfShipFindNearestDepot(v, max_distance); |
247 | + | 317 | + |
248 | + default: NOT_REACHED(); | 318 | + default: NOT_REACHED(); |
249 | } | 249 | + } |
250 | - | 250 | +} |
251 | - return best_depot; | 251 | + |
252 | } | ||
253 | |||
254 | static void CheckIfShipNeedsService(Vehicle *v) | 322 | static void CheckIfShipNeedsService(Vehicle *v) |
255 | @@ -180,9 +167,9 @@ | 323 | { |
324 | if (Company::Get(v->owner)->settings.vehicle.servint_ships == 0 || !v->NeedsAutomaticServicing()) return; | ||
325 | @@ -180,9 +198,9 @@ | ||
256 | default: NOT_REACHED(); | 326 | default: NOT_REACHED(); |
257 | } | 327 | } |
258 | 328 | ||
259 | - const Depot *depot = FindClosestShipDepot(v, max_distance); | 329 | - const Depot *depot = FindClosestShipDepot(v, max_distance); |
260 | + const FindDepotData | 260 | + const FindDepotData sfdd = FindClosestReachableShipDepot(Ship::From(v), max_distance); |
261 | 331 | ||
262 | - if (depot == NULL) { | 332 | - if (depot == NULL) { |
263 | + if ( | 263 | + if (sfdd.best_length == UINT_MAX || sfdd.best_length >= max_distance) { |
264 | if (v->current_order.IsType(OT_GOTO_DEPOT)) { | 334 | if (v->current_order.IsType(OT_GOTO_DEPOT)) { |
265 | v->current_order.MakeDummy(); | 335 | v->current_order.MakeDummy(); |
266 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); | 336 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); |
267 | @@ -190,8 + | 267 | @@ -190,8 +208,8 @@ |
268 | return; | 338 | return; |
269 | } | 339 | } |
270 | 340 | ||
271 | - v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); | 341 | - v->current_order.MakeGoToDepot(depot->index, ODTFB_SERVICE); |
272 | - v->dest_tile = depot->xy; | 342 | - v->dest_tile = depot->xy; |
273 | + v->current_order.MakeGoToDepot(GetDepotIndex( | 273 | + v->current_order.MakeGoToDepot(GetDepotIndex(sfdd.tile), ODTFB_SERVICE); |
274 | + v->dest_tile = | 274 | + v->dest_tile = sfdd.tile; |
275 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); | 345 | SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); |
276 | } | 346 | } |
277 | 347 | ||
278 | @@ -712,12 + | 278 | @@ -712,12 +730,15 @@ |
279 | 349 | ||
280 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) | 350 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) |
281 | { | 351 | { |
282 | - const Depot *depot = FindClosestShipDepot(this, 0); | 352 | - const Depot *depot = FindClosestShipDepot(this, 0); |
283 | + FindDepotData rfdd = FindClosestReachableShipDepot(this, 0); | 353 | + FindDepotData sfdd = FindClosestReachableShipDepot(this, 0); |
284 | + 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 | + } | ||
285 | 358 | ||
286 | - if (depot == NULL) return false; | 359 | - if (depot == NULL) return false; |
287 | + if (location != NULL) *location = rfdd.tile; | 360 | + if (location != NULL) *location = sfdd.tile; |
288 | + if (destination != NULL) *destination = GetDepotIndex(rfdd.tile); | 361 | + if (destination != NULL) *destination = GetDepotIndex(sfdd.tile); |
362 | + if (reverse != NULL) *reverse = sfdd.reverse; | ||
289 | 363 | ||
290 | - if (location != NULL) *location = depot->xy; | 364 | - if (location != NULL) *location = depot->xy; |
291 | - if (destination != NULL) *destination = depot->index; | 365 | - if (destination != NULL) *destination = depot->index; |