From dbf0d34823d0ad4cb8ba42cf9b71c66830afc091 Mon Sep 17 00:00:00 2001 From: Samu Date: Sun, 3 Nov 2019 11:02:54 +0000 Subject: [PATCH] Fix #7670: Cache the origin tile to prevent recurring calls to the road pathfinder when a vehicle is blocked by another --- src/pathfinder/yapf/yapf_road.cpp | 2 ++ src/roadveh.h | 4 ++++ src/roadveh_cmd.cpp | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 1b85c8d4ec671..8df9f114e3fa9 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -402,6 +402,8 @@ class CYapfFollowRoadT Node &best_next_node = *pNode; assert(best_next_node.GetTile() == tile); next_trackdir = best_next_node.GetTrackdir(); + path_cache.origin_td = next_trackdir; + path_cache.origin_tile = tile; /* remove last element for the special case when tile == dest_tile */ if (path_found && !path_cache.empty() && tile == v->dest_tile) { path_cache.td.pop_back(); diff --git a/src/roadveh.h b/src/roadveh.h index 028af9decb71a..f5d5390336554 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -83,6 +83,8 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length = false); void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); struct RoadVehPathCache { + Trackdir origin_td = INVALID_TRACKDIR; + TileIndex origin_tile = INVALID_TILE; std::deque td; std::deque tile; @@ -96,6 +98,8 @@ struct RoadVehPathCache { inline void clear() { + this->origin_td = INVALID_TRACKDIR; + this->origin_tile = INVALID_TILE; this->td.clear(); this->tile.clear(); } diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 261af7042bceb..3e1c190a53b51 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -968,6 +968,9 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection /* Attempt to follow cached path. */ if (!v->path.empty()) { if (v->path.tile.front() != tile) { + if (IsValidTile(v->path.origin_tile) && v->path.origin_tile == tile && HasBit(trackdirs, v->path.origin_td)) { + return_track(v->path.origin_td); + } /* Vehicle didn't expect a choice here, invalidate its path. */ v->path.clear(); } else { @@ -977,6 +980,8 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection v->path.td.pop_front(); v->path.tile.pop_front(); return_track(trackdir); + } else if (IsValidTile(v->path.origin_tile) && v->path.origin_tile == tile && HasBit(trackdirs, v->path.origin_td)) { + return_track(v->path.origin_td); } /* Vehicle expected a choice which is no longer available. */