mirror of https://github.com/OpenTTD/OpenTTD
Fix #12228: Don't restrict path when checking ship reverse on first attempt
Try to mimic the same path results as ChooseShipTrack to maintain behaviour consistency.pull/12232/head
parent
d7c5e9e8ab
commit
d6584c11b6
|
@ -292,31 +292,43 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool CheckShipReverse(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, Trackdir *trackdir)
|
static bool CheckShipReverse(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2, Trackdir *trackdir)
|
||||||
{
|
{
|
||||||
|
bool reverse = false;
|
||||||
|
|
||||||
const std::vector<WaterRegionPatchDesc> high_level_path = YapfShipFindWaterRegionPath(v, tile, NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1);
|
const std::vector<WaterRegionPatchDesc> high_level_path = YapfShipFindWaterRegionPath(v, tile, NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1);
|
||||||
if (high_level_path.empty()) {
|
if (high_level_path.empty()) return reverse;
|
||||||
if (trackdir) *trackdir = INVALID_TRACKDIR;
|
|
||||||
return false;
|
TrackdirBits trackdirs;
|
||||||
|
if (trackdir == nullptr) {
|
||||||
|
/* Leaving station or depot. */
|
||||||
|
trackdirs = TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2);
|
||||||
|
} else {
|
||||||
|
/* At the end of path, no path ahead, reversing. */
|
||||||
|
DiagDirection entry = ReverseDiagDir(VehicleExitDir(v->direction, v->state));
|
||||||
|
trackdirs = DiagdirReachesTrackdirs(entry) & TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0, entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int attempt = 0; attempt < 2; ++attempt) {
|
||||||
/* Create pathfinder instance. */
|
/* Create pathfinder instance. */
|
||||||
Tpf pf(MAX_SHIP_PF_NODES);
|
Tpf pf(MAX_SHIP_PF_NODES);
|
||||||
|
|
||||||
/* Set origin and destination nodes. */
|
/* Set origin and destination nodes. */
|
||||||
if (trackdir == nullptr) {
|
pf.SetOrigin(tile, trackdirs);
|
||||||
pf.SetOrigin(tile, TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2));
|
|
||||||
} else {
|
|
||||||
DiagDirection entry = ReverseDiagDir(VehicleExitDir(v->direction, v->state));
|
|
||||||
TrackdirBits rtds = DiagdirReachesTrackdirs(entry) & TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0, entry));
|
|
||||||
pf.SetOrigin(tile, rtds);
|
|
||||||
}
|
|
||||||
pf.SetDestination(v);
|
pf.SetDestination(v);
|
||||||
if (high_level_path.size() > 1) pf.SetIntermediateDestination(high_level_path.back());
|
const bool is_intermediate_destination = static_cast<int>(high_level_path.size()) >= NUMBER_OR_WATER_REGIONS_LOOKAHEAD + 1;
|
||||||
pf.RestrictSearch(high_level_path);
|
if (is_intermediate_destination) pf.SetIntermediateDestination(high_level_path.back());
|
||||||
|
|
||||||
|
/* Restrict the search area to prevent the low level pathfinder from expanding too many nodes. This can happen
|
||||||
|
* when the terrain is very "maze-like" or when the high level path "teleports" via a very long aqueduct. */
|
||||||
|
if (attempt > 0) pf.RestrictSearch(high_level_path);
|
||||||
|
|
||||||
/* Find best path. */
|
/* Find best path. */
|
||||||
if (!pf.FindPath(v)) return false;
|
if (!pf.FindPath(v)) {
|
||||||
|
if (attempt == 0) continue; // Try again with restricted search area.
|
||||||
|
break; // Returns false.
|
||||||
|
}
|
||||||
|
|
||||||
Node *pNode = pf.GetBestNode();
|
Node *pNode = pf.GetBestNode();
|
||||||
if (pNode == nullptr) return false;
|
if (pNode == nullptr) break; // Returns false.
|
||||||
|
|
||||||
/* Path was found, walk through the path back to the origin. */
|
/* Path was found, walk through the path back to the origin. */
|
||||||
while (pNode->m_parent != nullptr) {
|
while (pNode->m_parent != nullptr) {
|
||||||
|
@ -329,7 +341,12 @@ public:
|
||||||
} else {
|
} else {
|
||||||
assert(best_trackdir == td1 || best_trackdir == td2);
|
assert(best_trackdir == td1 || best_trackdir == td2);
|
||||||
}
|
}
|
||||||
return best_trackdir != td1;
|
reverse = best_trackdir != td1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reverse;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue