Old revision #phoeeb6pa | New revision #pubn57tm0 | ||
---|---|---|---|
1 | |||
2 | |||
3 | |||
4 | |||
5 | |||
6 | |||
7 | |||
8 | |||
9 | |||
10 | |||
11 | |||
12 | |||
13 | |||
14 | |||
15 | |||
16 | |||
17 | |||
18 | |||
19 | |||
20 | |||
21 | |||
22 | |||
23 | |||
24 | |||
25 | |||
26 | |||
27 | Index: src/pathfinder/yapf/yapf.h | 1 | Index: src/pathfinder/yapf/yapf.h |
28 | =================================================================== | 2 | =================================================================== |
29 | --- src/pathfinder/yapf/yapf.h (revision 27829) | 3 | --- src/pathfinder/yapf/yapf.h (revision 27829) | … | … |
73 | =================================================================== | 47 | =================================================================== |
74 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 27829) | 48 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 27829) |
75 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) | 49 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) |
76 | @@ -139,6 +139, | 76 | @@ -139,6 +139,43 @@ |
77 | assert(best_trackdir == td1 || best_trackdir == td2); | 51 | assert(best_trackdir == td1 || best_trackdir == td2); |
78 | return best_trackdir == td2; | 52 | return best_trackdir == td2; |
79 | } | 53 | } |
54 | + | ||
55 | + static bool stFindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed) | ||
56 | + { | ||
57 | + Tpf pf; | ||
58 | + bool result = pf.FindNearestDepot(v, tile, td1, td2, depot_tile, reversed); | ||
59 | + return result; | ||
60 | + } | ||
80 | + | 61 | + |
81 | + /** | 62 | + /** |
82 | + * Find the best depot for a ship. | 63 | + * Find the best depot for a ship. |
83 | + * @param v Vehicle | 64 | + * @param v Vehicle |
84 | + * @param tile Tile of the vehicle. | 65 | + * @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 | + */ | 70 | + */ |
92 | + static FindDepotData FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td, int max_distance) | 71 | + inline bool FindNearestDepot(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, TileIndex *depot_tile, bool *reversed) |
93 | + { | 72 | + { |
94 | + Tpf pf; | 73 | + Tpf pf1; |
74 | + Tpf pf2; | ||
95 | + /* Set origin. */ | 75 | + /* Set origin. */ |
96 | + pf.SetOrigin(tile, TrackdirToTrackdirBits(td)); | 76 | + pf1.SetOrigin(tile, TrackdirToTrackdirBits(td1)); |
97 | + | 77 | + pf2.SetOrigin(tile, TrackdirToTrackdirBits(td2)); |
98 | + /* Find the best path and return if no depot is found. */ | 78 | + |
99 | + if (!pf.FindPath(v)) return FindDepotData(); | 79 | + bool path_found1 = pf1.FindPath(v); |
100 | + | 80 | + bool path_found2 = pf2.FindPath(v); |
101 | + /* Return the cost of the best path and its depot. */ | 81 | + if (!path_found1 && !path_found2) return false; |
102 | + Node *n = pf.GetBestNode(); | 82 | + |
103 | + return FindDepotData(n->m_segment_last_tile, n->m_cost); | 83 | + Node *n; |
84 | + if (path_found1 || path_found2) { | ||
85 | + n = path_found1 ? pf1.GetBestNode() : pf2.GetBestNode(); | ||
86 | + *depot_tile = n->m_segment_last_tile; | ||
87 | + *reversed = !path_found1 && path_found2; | ||
88 | + } | ||
89 | + return true; | ||
104 | + } | 90 | + } |
105 | }; | 91 | }; |
106 | 92 | ||
107 | /** Cost Provider module of YAPF for ships */ | 93 | /** Cost Provider module of YAPF for ships */ |
108 | @@ -188,15 +2 | 108 | @@ -188,15 +225,53 @@ |
109 | } | 95 | } |
110 | }; | 96 | }; |
111 | 97 | … | … |
161 | 147 | ||
162 | /** Tpf - pathfinder type */ | 148 | /** Tpf - pathfinder type */ |
163 | typedef Tpf_ Tpf; | 149 | typedef Tpf_ Tpf; |
164 | @@ -215,12 +2 | 164 | @@ -215,12 +290,16 @@ |
165 | }; | 151 | }; |
166 | 152 | ||
167 | /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */ | 153 | /* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */ | … | … |
181 | /** Ship controller helper - path finder invoker */ | 167 | /** Ship controller helper - path finder invoker */ |
182 | Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found) | 168 | Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found) |
183 | { | 169 | { |
184 | @@ -239,6 +3 | 184 | @@ -239,6 +318,30 @@ |
185 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; | 171 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; |
186 | } | 172 | } |
187 | 173 | ||
188 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_ | 188 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty) |
189 | +{ | 175 | +{ |
176 | + FindDepotData fdd; | ||
177 | + | ||
178 | + Trackdir td = v->GetVehicleTrackdir(); | ||
179 | + Trackdir td_rev = ReverseTrackdir(td); | ||
190 | + TileIndex tile = v->tile; | 180 | + 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 */ | 182 | + /* 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 | + | 185 | + |
199 | + /* check if non-default YAPF type should be used */ | 186 | + /* check if non-default YAPF type should be used */ |
200 | + if (_settings_game.pf.forbid_90_deg) { | 187 | + 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) { | 189 | + } else if (_settings_game.pf.yapf.disable_node_optimization) { |
203 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::FindNearestDepot; // Trackdir, allow 90-deg | 190 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg |
204 | + } | 191 | + } |
205 | + | 192 | + |
206 | + return pfnFindNearestDepot(v, tile, trackdir, max_distance); | 193 | + 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 | ||
195 | + return fdd; | ||
207 | +} | 196 | +} |
208 | + | 197 | + |
209 | bool YapfShipCheckReverse(const Ship *v) | 198 | bool YapfShipCheckReverse(const Ship *v) | … | … |
280 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) | 269 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) |
281 | { | 270 | { |
282 | - const Depot *depot = FindClosestShipDepot(this, 0); | 271 | - const Depot *depot = FindClosestShipDepot(this, 0); |
283 | + FindDepotData | 283 | + FindDepotData sfdd = FindClosestReachableShipDepot(this, 0); |
284 | + if ( | 284 | + if (sfdd.best_length == UINT_MAX) return false; |
285 | 274 | ||
286 | - if (depot == NULL) return false; | 275 | - if (depot == NULL) return false; |
287 | + if (location != NULL) *location = | 287 | + if (location != NULL) *location = sfdd.tile; |
288 | + if (destination != NULL) *destination = GetDepotIndex( | 288 | + if (destination != NULL) *destination = GetDepotIndex(sfdd.tile); |
289 | 278 | ||
290 | - if (location != NULL) *location = depot->xy; | 279 | - if (location != NULL) *location = depot->xy; |
291 | - if (destination != NULL) *destination = depot->index; | 280 | - if (destination != NULL) *destination = depot->index; |