summaryrefslogtreecommitdiff
path: root/src/pathfinder
diff options
context:
space:
mode:
authorJonathan G Rennison <j.g.rennison@gmail.com>2020-02-06 21:23:42 +0100
committerNiels Martin Hansen <nielsm@indvikleren.dk>2020-02-07 23:02:10 +0100
commit1a88fb5c910ed8badc9b7535487ff78fbdc7a38b (patch)
treea6089403eab4eb03f5cfdb114f69b43c835a8b18 /src/pathfinder
parent9e632355f14aef4696730267d1682e7f2ba0f3a9 (diff)
downloadopenttd-1a88fb5c910ed8badc9b7535487ff78fbdc7a38b.tar.xz
Fix #7592: Do not cache road vehicle path within 8 tiles of destination with multiple entrances
Ported from jgrpp commit 79d5be7e265df3be8b73d484f0c7261b3c23229d
Diffstat (limited to 'src/pathfinder')
-rw-r--r--src/pathfinder/pathfinder_type.h3
-rw-r--r--src/pathfinder/yapf/yapf_road.cpp21
2 files changed, 24 insertions, 0 deletions
diff --git a/src/pathfinder/pathfinder_type.h b/src/pathfinder/pathfinder_type.h
index f837f4840..eb0381d8a 100644
--- a/src/pathfinder/pathfinder_type.h
+++ b/src/pathfinder/pathfinder_type.h
@@ -44,6 +44,9 @@ static const int YAPF_SHIP_PATH_CACHE_LENGTH = 32;
/** Maximum segments of road vehicle path cache */
static const int YAPF_ROADVEH_PATH_CACHE_SEGMENTS = 8;
+/** Distance from destination road stops to not cache any further */
+static const int YAPF_ROADVEH_PATH_CACHE_DESTINATION_LIMIT = 8;
+
/**
* Helper container to find a depot
*/
diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp
index 248bf1a40..1b85c8d4e 100644
--- a/src/pathfinder/yapf/yapf_road.cpp
+++ b/src/pathfinder/yapf/yapf_road.cpp
@@ -251,6 +251,11 @@ public:
}
}
+ const Station *GetDestinationStation() const
+ {
+ return m_dest_station != INVALID_STATION ? Station::GetIfValid(m_dest_station) : nullptr;
+ }
+
protected:
/** to access inherited path finder */
Tpf& Yapf()
@@ -402,6 +407,22 @@ public:
path_cache.td.pop_back();
path_cache.tile.pop_back();
}
+
+ /* Check if target is a station, and cached path ends within 8 tiles of the dest tile */
+ const Station *st = Yapf().GetDestinationStation();
+ if (st) {
+ const RoadStop *stop = st->GetPrimaryRoadStop(v);
+ if (stop != nullptr && (IsDriveThroughStopTile(stop->xy) || stop->GetNextRoadStop(v) != nullptr)) {
+ /* Destination station has at least 2 usable road stops, or first is a drive-through stop,
+ * trim end of path cache within a number of tiles of road stop tile area */
+ TileArea non_cached_area = v->IsBus() ? st->bus_station : st->truck_station;
+ non_cached_area.Expand(YAPF_ROADVEH_PATH_CACHE_DESTINATION_LIMIT);
+ while (!path_cache.empty() && non_cached_area.Contains(path_cache.tile.back())) {
+ path_cache.td.pop_back();
+ path_cache.tile.pop_back();
+ }
+ }
+ }
}
return next_trackdir;
}