From 0e9e94a94b2b6a1790cab91af3413928e920c982 Mon Sep 17 00:00:00 2001 From: frosch Date: Wed, 20 Feb 2008 14:07:45 +0000 Subject: (svn r12191) -Fix: Do not start overtaking if the RV reaches wrong-way one-way-road in the next tiles. --- src/roadveh_cmd.cpp | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 57208e7e1..ede841d23 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -1008,10 +1008,10 @@ struct OvertakeData { const Vehicle* u; const Vehicle* v; TileIndex tile; - uint16 tilebits; + Trackdir trackdir; }; -static void* EnumFindVehToOvertake(Vehicle* v, void* data) +static void* EnumFindVehBlockingOvertake(Vehicle* v, void* data) { const OvertakeData* od = (OvertakeData*)data; @@ -1020,22 +1020,29 @@ static void* EnumFindVehToOvertake(Vehicle* v, void* data) v : NULL; } -static bool FindRoadVehToOvertake(OvertakeData *od) +/** + * Check if overtaking is possible on a piece of track + * + * @param od Information about the tile and the involved vehicles + * @return true if we have to abort overtaking + */ +static bool CheckRoadBlockedForOvertaking(OvertakeData *od) { - uint32 bits; + uint32 ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes); + TrackdirBits trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK); + TrackdirBits red_signals = (TrackdirBits)((ts >> 16) & TRACKDIR_BIT_MASK); // barred level crossing + TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits); - bits = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->u.road.compatible_roadtypes); - bits |= bits >> 8; + /* Track does not continue along overtaking direction || track has junction || levelcrossing is barred */ + if (!HasBit(trackdirbits, od->trackdir) || (trackbits & ~TRACK_BIT_CROSS) || (red_signals != TRACKDIR_BIT_NONE)) return true; - if (!(od->tilebits & bits) || (bits & 0x3C3C) || (bits & 0x3F3F0000)) - return true; - return VehicleFromPos(od->tile, od, EnumFindVehToOvertake) != NULL; + /* Are there more vehicles on the tile except the two vehicles involved in overtaking */ + return VehicleFromPos(od->tile, od, EnumFindVehBlockingOvertake) != NULL; } static void RoadVehCheckOvertake(Vehicle *v, Vehicle *u) { OvertakeData od; - uint16 tt; od.v = v; od.u = u; @@ -1055,32 +1062,31 @@ static void RoadVehCheckOvertake(Vehicle *v, Vehicle *u) /* For now, articulated road vehicles can't overtake anything. */ if (RoadVehHasArticPart(v)) return; + /* Vehicles are not driving in same direction || direction is not a diagonal direction */ if (v->direction != u->direction || !(v->direction & 1)) return; /* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */ if (v->u.road.state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return; - tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes); - tt |= tt >> 8; - tt &= 0x3F; - - if ((tt & 3) == 0) return; - if ((tt & 0x3C) != 0) return; - - if (tt == 3) tt = (v->direction & 2) ? 2 : 1; - od.tilebits = tt; + od.trackdir = DiagdirToDiagTrackdir(DirToDiagDir(v->direction)); + /* Are the current and the next tile suitable for overtaking? + * - Does the track continue along od.trackdir + * - No junctions + * - No barred levelcrossing + * - No other vehicles in the way + */ od.tile = v->tile; - if (FindRoadVehToOvertake(&od)) return; + if (CheckRoadBlockedForOvertaking(&od)) return; od.tile = v->tile + TileOffsByDiagDir(DirToDiagDir(v->direction)); - if (FindRoadVehToOvertake(&od)) return; + if (CheckRoadBlockedForOvertaking(&od)) return; if (od.u->cur_speed == 0 || od.u->vehstatus& VS_STOPPED) { v->u.road.overtaking_ctr = 0x11; v->u.road.overtaking = 0x10; } else { -// if (FindRoadVehToOvertake(&od)) return; +// if (CheckRoadBlockedForOvertaking(&od)) return; v->u.road.overtaking_ctr = 0; v->u.road.overtaking = 0x10; } -- cgit v1.2.3-70-g09d2