From 1e75f87780ee34ab6445f39db32e5f7742241bfe Mon Sep 17 00:00:00 2001 From: TrevorShelton Date: Thu, 6 Apr 2023 18:24:02 -0700 Subject: [PATCH] Fix #10028: Did Some Overtaking Routine Fixes --- src/roadveh.h | 2 +- src/roadveh_cmd.cpp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/roadveh.h b/src/roadveh.h index 79ff9dbe0c..e6bb13f54f 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -77,7 +77,7 @@ static const uint RVC_DRIVE_THROUGH_STOP_FRAME = 11; static const uint RVC_DEPOT_STOP_FRAME = 11; /** The number of ticks a vehicle has for overtaking. */ -static const byte RV_OVERTAKE_TIMEOUT = 35; +static const byte RV_OVERTAKE_TIMEOUT = 25; void RoadVehUpdateCache(RoadVehicle *v, bool same_length = false); void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 9b68df99a3..a954814cde 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -768,8 +768,16 @@ struct OvertakeData { static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data) { const OvertakeData *od = (OvertakeData*)data; + TileIndexDiff front = TileOffsByDiagDir(DirToDiagDir(od->v->direction)); - return (v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v) ? v : nullptr; + /* Distinct road engine is blocking if it's within the tile or the next few of the passer as well as either it being + * directionally opposed to passer, the passed pending movement, or the blocker being stopped while overtaking. */ + return (v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v + && + ( v->tile == od->v->tile || v->tile == od->v->tile + front || v->tile == od->v->tile + front + front || v->tile == od->u->tile + front + front ) + && + ( v->direction == ReverseDir(od->v->direction) || !(od->u->vehstatus & VS_STOPPED) || (v->vehstatus & VS_STOPPED && ( (RoadVehicle*)v )->overtaking ) ) ) + ? v : nullptr; } /** @@ -833,10 +841,10 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u) * - No barred levelcrossing * - No other vehicles in the way */ + od.tile = v->tile; if (CheckRoadBlockedForOvertaking(&od)) return; - - od.tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction)); + od.tile += TileOffsByDiagDir(DirToDiagDir(v->direction)); if (CheckRoadBlockedForOvertaking(&od)) return; /* When the vehicle in front of us is stopped we may only take