summaryrefslogtreecommitdiff
path: root/src/roadveh_cmd.cpp
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2007-02-14 16:37:16 +0000
committerrubidium <rubidium@openttd.org>2007-02-14 16:37:16 +0000
commita2999dadc91fd95fae93c3063d9db7c99245c7ad (patch)
tree1a15ba2c92fafbb76de3d76a96583953c41b088b /src/roadveh_cmd.cpp
parentca310e5a2684e8a3f905ba59219fc5c24c089f78 (diff)
downloadopenttd-a2999dadc91fd95fae93c3063d9db7c99245c7ad.tar.xz
(svn r8735) -Feature: drive-through road stops made possible by the hard work of mart3p.
Diffstat (limited to 'src/roadveh_cmd.cpp')
-rw-r--r--src/roadveh_cmd.cpp79
1 files changed, 63 insertions, 16 deletions
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
index 9d76fc4f7..4af0a269b 100644
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -1080,7 +1080,8 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
/* Road depot owned by another player or with the wrong orientation */
trackdirs = TRACKDIR_BIT_NONE;
}
- } else if (IsTileType(tile, MP_STATION) && IsRoadStopTile(tile)) {
+ } else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) {
+ /* Standard road stop (drive-through stops are treated as normal road) */
if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir) {
/* different station owner or wrong orientation */
trackdirs = TRACKDIR_BIT_NONE;
@@ -1093,7 +1094,7 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
trackdirs = TRACKDIR_BIT_NONE;
} else {
/* Proper station type, check if there is free loading bay */
- if (!_patches.roadveh_queue &&
+ if (!_patches.roadveh_queue && IsStandardRoadStopTile(tile) &&
!GetRoadStopByTile(tile, rstype)->HasFreeBay()) {
/* Station is full and RV queuing is off */
trackdirs = TRACKDIR_BIT_NONE;
@@ -1167,7 +1168,8 @@ static Trackdir RoadFindPathToDest(Vehicle* v, TileIndex tile, DiagDirection ent
goto do_it;
}
} else if (IsTileType(desttile, MP_STATION)) {
- if (IsRoadStop(desttile)) {
+ /* For drive-through stops we can head for the actual station tile */
+ if (IsStandardRoadStopTile(desttile)) {
dir = GetRoadStopDir(desttile);
do_it:;
/* When we are heading for a depot or station, we just
@@ -1242,9 +1244,11 @@ enum {
/* Start frames for when a vehicle enters a tile/changes its state.
* The start frame is different for vehicles that turned around or
* are leaving the depot as the do not start at the edge of the tile */
- RVC_DEFAULT_START_FRAME = 0,
- RVC_TURN_AROUND_START_FRAME = 1,
- RVC_DEPOT_START_FRAME = 6
+ RVC_DEFAULT_START_FRAME = 0,
+ RVC_TURN_AROUND_START_FRAME = 1,
+ RVC_DEPOT_START_FRAME = 6,
+ /* Stop frame for a vehicle in a drive-through stop */
+ RVC_DRIVE_THROUGH_STOP_FRAME = 7
};
typedef struct RoadDriveEntry {
@@ -1376,8 +1380,12 @@ static void RoadVehController(Vehicle *v)
return;
}
- /* Get move position data for next frame */
- rd = _road_drive_data[(v->u.road.state + (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
+ /* Get move position data for next frame.
+ * For a drive-through road stop use 'straight road' move data.
+ * In this case v->u.road.state is masked to give the road stop entry direction. */
+ rd = _road_drive_data[(
+ (HASBIT(v->u.road.state, RVS_IN_DT_ROAD_STOP) ? v->u.road.state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->u.road.state) +
+ (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
if (rd.x & RDE_NEXT_TILE) {
TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
@@ -1417,8 +1425,8 @@ again:
goto again;
}
- if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
- if (IsReversingRoadTrackdir(dir)) {
+ if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
+ if (IsReversingRoadTrackdir(dir) && IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
/* New direction is trying to turn vehicle around.
* We can't turn at the exit of a road stop so wait.*/
v->cur_speed = 0;
@@ -1427,9 +1435,13 @@ again:
if (IsRoadStop(v->tile)) {
RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
- /* Vehicle is leaving a road stop tile, mark bay as free */
- rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY));
- rs->SetEntranceBusy(false);
+ /* Vehicle is leaving a road stop tile, mark bay as free
+ * For drive-through stops, only do it if the vehicle stopped here */
+ if (IsStandardRoadStopTile(v->tile) || HASBIT(v->u.road.state, RVS_IS_STOPPING)) {
+ rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY));
+ CLRBIT(v->u.road.state, RVS_IS_STOPPING);
+ }
+ if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(false);
}
}
@@ -1523,8 +1535,18 @@ again:
}
}
- if (v->u.road.state >= RVSB_IN_ROAD_STOP &&
- _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) {
+ /* If the vehicle is in a normal road stop and the frame equals the stop frame OR
+ * if the vehicle is in a drive-through road stop and this is the destination station
+ * and it's the correct type of stop (bus or truck) and the frame equals the stop frame...
+ * (the station test and stop type test ensure that other vehicles, using the road stop as
+ * a through route, do not stop) */
+ if ((IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) &&
+ _road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) ||
+ (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) &&
+ v->current_order.dest == GetStationIndex(v->tile) &&
+ GetRoadStopType(v->tile) == ((v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK) &&
+ v->u.road.frame == RVC_DRIVE_THROUGH_STOP_FRAME)) {
+
RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
Station* st = GetStationByTile(v->tile);
@@ -1536,6 +1558,31 @@ again:
/* Vehicle has arrived at a bay in a road stop */
Order old_order;
+ if (IsDriveThroughStopTile(v->tile)) {
+ TileIndex next_tile = TILE_ADD(v->tile, TileOffsByDir(v->direction));
+ RoadStop::Type type = (v->cargo_type == CT_PASSENGERS) ? RoadStop::BUS : RoadStop::TRUCK;
+
+ assert(HASBIT(v->u.road.state, RVS_IS_STOPPING));
+
+ /* Check if next inline bay is free */
+ if (IsDriveThroughStopTile(next_tile) && (GetRoadStopType(next_tile) == type)) {
+ RoadStop *rs_n = GetRoadStopByTile(next_tile, type);
+
+ if (rs_n->IsFreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY))) {
+ /* Bay in next stop along is free - use it */
+ ClearSlot(v);
+ rs_n->num_vehicles++;
+ v->u.road.slot = rs_n;
+ v->dest_tile = rs_n->xy;
+ v->u.road.slot_age = 14;
+
+ v->u.road.frame++;
+ RoadZPosAffectSpeed(v, SetRoadVehPosition(v, x, y));
+ return;
+ }
+ }
+ }
+
rs->SetEntranceBusy(false);
v->last_station_visited = GetStationIndex(v->tile);
@@ -1573,7 +1620,7 @@ again:
ClearSlot(v);
}
- rs->SetEntranceBusy(true);
+ if (IsStandardRoadStopTile(v->tile)) rs->SetEntranceBusy(true);
if (rs == v->u.road.slot) {
/* We are leaving the correct station */