| 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; |