Old revision #ppqwyyw9s | New revision #pubn57tm0 | ||
---|---|---|---|
47 | =================================================================== | 47 | =================================================================== |
48 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 27829) | 48 | --- src/pathfinder/yapf/yapf_ship.cpp (revision 27829) |
49 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) | 49 | +++ src/pathfinder/yapf/yapf_ship.cpp (working copy) |
50 | @@ -139,6 +139, | 50 | @@ -139,6 +139,43 @@ |
51 | assert(best_trackdir == td1 || best_trackdir == td2); | 51 | assert(best_trackdir == td1 || best_trackdir == td2); |
52 | return best_trackdir == td2; | 52 | return best_trackdir == td2; |
53 | } | 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 | + } | ||
54 | + | 61 | + |
55 | + /** | 62 | + /** |
56 | + * Find the best depot for a ship. | 63 | + * Find the best depot for a ship. |
57 | + * @param v Vehicle | 64 | + * @param v Vehicle |
58 | + * @param tile Tile of the vehicle. | 65 | + * @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 | + */ | 70 | + */ |
66 | + 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) |
67 | + { | 72 | + { |
68 | + Tpf pf; | 73 | + Tpf pf1; |
74 | + Tpf pf2; | ||
69 | + /* Set origin. */ | 75 | + /* Set origin. */ |
70 | + pf.SetOrigin(tile, TrackdirToTrackdirBits(td)); | 76 | + pf1.SetOrigin(tile, TrackdirToTrackdirBits(td1)); |
71 | + | 77 | + pf2.SetOrigin(tile, TrackdirToTrackdirBits(td2)); |
72 | + /* Find the best path and return if no depot is found. */ | 78 | + |
73 | + if (!pf.FindPath(v)) return FindDepotData(); | 79 | + bool path_found1 = pf1.FindPath(v); |
74 | + | 80 | + bool path_found2 = pf2.FindPath(v); |
75 | + /* Return the cost of the best path and its depot. */ | 81 | + if (!path_found1 && !path_found2) return false; |
76 | + Node *n = pf.GetBestNode(); | 82 | + |
77 | + 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; | ||
78 | + } | 90 | + } |
79 | }; | 91 | }; |
80 | 92 | ||
81 | /** Cost Provider module of YAPF for ships */ | 93 | /** Cost Provider module of YAPF for ships */ |
82 | @@ -188,15 +2 | 82 | @@ -188,15 +225,53 @@ |
83 | } | 95 | } |
84 | }; | 96 | }; |
85 | 97 | … | … |
101 | + /** Called by YAPF to detect if node ends in the desired destination */ | 113 | + /** Called by YAPF to detect if node ends in the desired destination */ |
102 | + inline bool PfDetectDestination(Node &n) | 114 | + inline bool PfDetectDestination(Node &n) |
103 | + { | 115 | + { |
104 | + bool bDest = IsShipDepotTile(n.m_segment_last_tile) | 104 | + bool bDest = IsShipDepotTile(n.m_segment_last_tile) && GetShipDepotPart(n.m_segment_last_tile) == DEPOT_PART_NORTH; |
105 | + return bDest; | 117 | + return bDest; |
106 | + } | 118 | + } |
107 | + | 119 | + |
108 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) | 120 | + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) |
109 | + { | 121 | + { |
110 | + return IsShipDepotTile( | 110 | + return IsShipDepotTile(n.m_segment_last_tile) && GetShipDepotPart(n.m_segment_last_tile) == DEPOT_PART_NORTH; |
111 | + } | 123 | + } |
112 | + | 124 | + |
113 | + /** | 125 | + /** | … | … |
135 | 147 | ||
136 | /** Tpf - pathfinder type */ | 148 | /** Tpf - pathfinder type */ |
137 | typedef Tpf_ Tpf; | 149 | typedef Tpf_ Tpf; |
138 | @@ -215,12 +2 | 138 | @@ -215,12 +290,16 @@ |
139 | }; | 151 | }; |
140 | 152 | ||
141 | /* 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 */ | … | … |
155 | /** Ship controller helper - path finder invoker */ | 167 | /** Ship controller helper - path finder invoker */ |
156 | 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) |
157 | { | 169 | { |
158 | @@ -239,6 +3 | 158 | @@ -239,6 +318,30 @@ |
159 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; | 171 | return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : INVALID_TRACK; |
160 | } | 172 | } |
161 | 173 | ||
162 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_ | 162 | +FindDepotData YapfShipFindNearestDepot(const Ship *v, int max_penalty) |
163 | +{ | 175 | +{ |
176 | + FindDepotData fdd; | ||
177 | + | ||
178 | + Trackdir td = v->GetVehicleTrackdir(); | ||
179 | + Trackdir td_rev = ReverseTrackdir(td); | ||
164 | + TileIndex tile = v->tile; | 180 | + 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 */ | 182 | + /* 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 | + | 185 | + |
173 | + /* check if non-default YAPF type should be used */ | 186 | + /* check if non-default YAPF type should be used */ |
174 | + if (_settings_game.pf.forbid_90_deg) { | 187 | + 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) { | 189 | + } else if (_settings_game.pf.yapf.disable_node_optimization) { |
177 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::FindNearestDepot; // Trackdir, allow 90-deg | 190 | + pfnFindNearestDepot = &CYapfShipAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg |
178 | + } | 191 | + } |
179 | + | 192 | + |
180 | + 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; | ||
181 | +} | 196 | +} |
182 | + | 197 | + |
183 | bool YapfShipCheckReverse(const Ship *v) | 198 | bool YapfShipCheckReverse(const Ship *v) | … | … |
203 | - * other hand if we have set a maximum distance, any depot | 218 | - * other hand if we have set a maximum distance, any depot |
204 | - * further away than max_distance can safely be ignored. */ | 219 | - * further away than max_distance can safely be ignored. */ |
205 | - uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1; | 220 | - uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1; |
206 | + if (IsShipDepotTile(v->tile) | 206 | + if (IsShipDepotTile(v->tile) && GetShipDepotPart(v->tile) == DEPOT_PART_NORTH) return FindDepotData(v->tile, 0); |
207 | 222 | ||
208 | - FOR_ALL_DEPOTS(depot) { | 223 | - FOR_ALL_DEPOTS(depot) { |
209 | - TileIndex tile = depot->xy; | 224 | - TileIndex tile = depot->xy; | … | … |
254 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) | 269 | bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse) |
255 | { | 270 | { |
256 | - const Depot *depot = FindClosestShipDepot(this, 0); | 271 | - const Depot *depot = FindClosestShipDepot(this, 0); |
257 | + FindDepotData | 257 | + FindDepotData sfdd = FindClosestReachableShipDepot(this, 0); |
258 | + if ( | 258 | + if (sfdd.best_length == UINT_MAX) return false; |
259 | 274 | ||
260 | - if (depot == NULL) return false; | 275 | - if (depot == NULL) return false; |
261 | + if (location != NULL) *location = | 261 | + if (location != NULL) *location = sfdd.tile; |
262 | + if (destination != NULL) *destination = GetDepotIndex( | 262 | + if (destination != NULL) *destination = GetDepotIndex(sfdd.tile); |
263 | 278 | ||
264 | - if (location != NULL) *location = depot->xy; | 279 | - if (location != NULL) *location = depot->xy; |
265 | - if (destination != NULL) *destination = depot->index; | 280 | - if (destination != NULL) *destination = depot->index; |