summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2008-02-20 14:07:45 +0000
committerfrosch <frosch@openttd.org>2008-02-20 14:07:45 +0000
commit0e9e94a94b2b6a1790cab91af3413928e920c982 (patch)
tree24e6b56841bd60fc943e78a45a47790c79d4f43a /src
parent2b8d1bcb51b40f6c095ea5addf07cd66e34ef924 (diff)
downloadopenttd-0e9e94a94b2b6a1790cab91af3413928e920c982.tar.xz
(svn r12191) -Fix: Do not start overtaking if the RV reaches wrong-way one-way-road in the next tiles.
Diffstat (limited to 'src')
-rw-r--r--src/roadveh_cmd.cpp50
1 files 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;
}