diff --git a/src/pathfinder/yapf/yapf.h b/src/pathfinder/yapf/yapf.h --- a/src/pathfinder/yapf/yapf.h +++ b/src/pathfinder/yapf/yapf.h @@ -56,9 +56,10 @@ Trackdir YapfRoadVehicleChooseTrack(cons * @param path_found [out] Whether a path has been found (true) or has been guessed (false) * @param reserve_track indicates whether YAPF should try to reserve the found path * @param target [out] the target tile of the reservation, free is set to true if path was reserved + * @param dest [out] the final tile of the best path found * @return the best track for next turn */ -Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, struct PBSTileInfo *target); +Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, struct PBSTileInfo *target, TileIndex *dest); /** * Used when user sends road vehicle to the nearest depot or if road vehicle needs servicing using YAPF. diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -395,19 +395,19 @@ public: return 't'; } - static Trackdir stChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target) + static Trackdir stChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest) { /* create pathfinder instance */ Tpf pf1; Trackdir result1; if (_debug_desync_level < 2) { - result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); + result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest); } else { - result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, false, nullptr); + result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, false, nullptr, nullptr); Tpf pf2; pf2.DisableCache(true); - Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); + Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest); if (result1 != result2) { Debug(desync, 2, "CACHE ERROR: ChooseRailTrack() = [{}, {}]", result1, result2); DumpState(pf1, pf2); @@ -417,9 +417,10 @@ public: return result1; } - inline Trackdir ChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target) + inline Trackdir ChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest) { if (target != nullptr) target->tile = INVALID_TILE; + if (dest != nullptr) *dest = INVALID_TILE; /* set origin and destination nodes */ PBSTileInfo origin = FollowTrainReservation(v); @@ -449,7 +450,10 @@ public: Node &best_next_node = *pPrev; next_trackdir = best_next_node.GetTrackdir(); - if (reserve_track && path_found) this->TryReservePath(target, pNode->GetLastTile()); + if (reserve_track && path_found) { + if (dest != nullptr) *dest = Yapf().GetBestNode()->GetLastTile(); + this->TryReservePath(target, pNode->GetLastTile()); + } } /* Treat the path as found if stopped on the first two way signal(s). */ @@ -528,10 +532,10 @@ struct CYapfAnySafeTileRail1 : CYapfT > {}; -Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target) +Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target, TileIndex *dest) { /* default is YAPF type 2 */ - typedef Trackdir (*PfnChooseRailTrack)(const Train*, TileIndex, DiagDirection, TrackBits, bool&, bool, PBSTileInfo*); + typedef Trackdir (*PfnChooseRailTrack)(const Train*, TileIndex, DiagDirection, TrackBits, bool&, bool, PBSTileInfo*, TileIndex*); PfnChooseRailTrack pfnChooseRailTrack = &CYapfRail1::stChooseRailTrack; /* check if non-default YAPF type needed */ @@ -539,7 +543,7 @@ Track YapfTrainChooseTrack(const Train * pfnChooseRailTrack = &CYapfRail2::stChooseRailTrack; // Trackdir, forbid 90-deg } - Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); + Trackdir td_ret = pfnChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest); return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : FindFirstTrack(tracks); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -2318,13 +2318,16 @@ static const byte _initial_tile_subcoord * @param[out] path_found Whether a path has been found or not. * @param do_track_reservation Path reservation is requested * @param[out] dest State and destination of the requested path + * @param[out] final_dest Final tile of the best path found * @return The best track the train should follow */ -static Track DoTrainPathfind(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool do_track_reservation, PBSTileInfo *dest) +static Track DoTrainPathfind(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool do_track_reservation, PBSTileInfo *dest, TileIndex *final_dest) { + if (final_dest != nullptr) *final_dest = INVALID_TILE; + switch (_settings_game.pf.pathfinder_for_trains) { case VPF_NPF: return NPFTrainChooseTrack(v, path_found, do_track_reservation, dest); - case VPF_YAPF: return YapfTrainChooseTrack(v, tile, enterdir, tracks, path_found, do_track_reservation, dest); + case VPF_YAPF: return YapfTrainChooseTrack(v, tile, enterdir, tracks, path_found, do_track_reservation, dest, final_dest); default: NOT_REACHED(); } @@ -2596,7 +2599,7 @@ static Track ChooseTrainTrack(Train *v, bool path_found = true; TileIndex new_tile = res_dest.tile; - Track next_track = DoTrainPathfind(v, new_tile, dest_enterdir, tracks, path_found, do_track_reservation, &res_dest); + Track next_track = DoTrainPathfind(v, new_tile, dest_enterdir, tracks, path_found, do_track_reservation, &res_dest, nullptr); if (new_tile == tile) best_track = next_track; v->HandlePathfindingResult(path_found); } @@ -2644,7 +2647,7 @@ static Track ChooseTrainTrack(Train *v, if (orders.SwitchToNextOrder(true)) { PBSTileInfo cur_dest; bool path_found; - DoTrainPathfind(v, next_tile, exitdir, reachable, path_found, true, &cur_dest); + DoTrainPathfind(v, next_tile, exitdir, reachable, path_found, true, &cur_dest, nullptr); if (cur_dest.tile != INVALID_TILE) { res_dest = cur_dest; if (res_dest.okay) continue;