|
|
|
@ -835,6 +835,8 @@ struct OvertakeData {
|
|
|
|
|
const RoadVehicle *v;
|
|
|
|
|
TileIndex tile;
|
|
|
|
|
Trackdir trackdir;
|
|
|
|
|
int tunnelbridge_min;
|
|
|
|
|
int tunnelbridge_max;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data)
|
|
|
|
@ -864,6 +866,32 @@ static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data)
|
|
|
|
|
return v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Vehicle *EnumFindVehBlockingOvertakeTunnelBridge(Vehicle *v, void *data)
|
|
|
|
|
{
|
|
|
|
|
const OvertakeData *od = (OvertakeData*)data;
|
|
|
|
|
|
|
|
|
|
switch (DiagDirToAxis(DirToDiagDir(v->direction))) {
|
|
|
|
|
case AXIS_X:
|
|
|
|
|
if (v->x_pos < od->tunnelbridge_min || v->x_pos > od->tunnelbridge_max) return nullptr;
|
|
|
|
|
break;
|
|
|
|
|
case AXIS_Y:
|
|
|
|
|
if (v->y_pos < od->tunnelbridge_min || v->y_pos > od->tunnelbridge_max) return nullptr;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
return EnumFindVehBlockingOvertake(v, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Vehicle *EnumFindVehBlockingOvertakeBehind(Vehicle *v, void *data)
|
|
|
|
|
{
|
|
|
|
|
const OvertakeData *od = (OvertakeData*)data;
|
|
|
|
|
|
|
|
|
|
if (v->First() == od->u || v->First() == od->v) return nullptr;
|
|
|
|
|
if (RoadVehicle::From(v)->overtaking != 0 && TileVirtXY(v->x_pos, v->y_pos) == od->tile) return v;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CheckRoadInfraUnsuitableForOvertaking(OvertakeData *od)
|
|
|
|
|
{
|
|
|
|
|
if (!HasTileAnyRoadType(od->tile, od->v->compatible_roadtypes)) return true;
|
|
|
|
@ -884,7 +912,7 @@ static bool CheckRoadInfraUnsuitableForOvertaking(OvertakeData *od)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return rcows != RCOWS_SIDE_JUNCTION_NO_EXIT;
|
|
|
|
|
return rcows == RCOWS_NORMAL || rcows == RCOWS_NO_ACCESS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -924,6 +952,34 @@ inline bool IsValidRoadVehStateForOvertake(const RoadVehicle *v)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool CheckTunnelBridgeBlockedForOvertaking(OvertakeData *od, TileIndex behind_end, TileIndex ahead_end, TileIndex pos, int ahead_extent, int behind_extent)
|
|
|
|
|
{
|
|
|
|
|
switch (DirToDiagDir(od->v->direction)) {
|
|
|
|
|
case DIAGDIR_NE:
|
|
|
|
|
od->tunnelbridge_min = (TileX(pos) - ahead_extent) * TILE_SIZE;
|
|
|
|
|
od->tunnelbridge_max = ((TileX(pos) + behind_extent) * TILE_SIZE) + TILE_UNIT_MASK;
|
|
|
|
|
break;
|
|
|
|
|
case DIAGDIR_SE:
|
|
|
|
|
od->tunnelbridge_min = (TileY(pos) - behind_extent) * TILE_SIZE;
|
|
|
|
|
od->tunnelbridge_max = ((TileY(pos) + ahead_extent) * TILE_SIZE) + TILE_UNIT_MASK;
|
|
|
|
|
break;
|
|
|
|
|
case DIAGDIR_SW:
|
|
|
|
|
od->tunnelbridge_min = (TileX(pos) - behind_extent) * TILE_SIZE;
|
|
|
|
|
od->tunnelbridge_max = ((TileX(pos) + ahead_extent) * TILE_SIZE) + TILE_UNIT_MASK;
|
|
|
|
|
break;
|
|
|
|
|
case DIAGDIR_NW:
|
|
|
|
|
od->tunnelbridge_min = (TileY(pos) - ahead_extent) * TILE_SIZE;
|
|
|
|
|
od->tunnelbridge_max = ((TileY(pos) + behind_extent) * TILE_SIZE) + TILE_UNIT_MASK;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HasVehicleOnPos(behind_end, VEH_ROAD, od, EnumFindVehBlockingOvertakeTunnelBridge)) return true;
|
|
|
|
|
if (HasVehicleOnPos(ahead_end, VEH_ROAD, od, EnumFindVehBlockingOvertakeTunnelBridge)) return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
|
|
|
|
|
{
|
|
|
|
|
/* Trams can't overtake other trams */
|
|
|
|
@ -955,9 +1011,9 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
|
|
|
|
|
/* Don't overtake if vehicle parts not all in same direction */
|
|
|
|
|
if (w->direction != v->direction) return;
|
|
|
|
|
|
|
|
|
|
/* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
|
|
|
|
|
/* Check if vehicle is in a road stop, depot, or not on a straight road */
|
|
|
|
|
if ((w->state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(w->state & RVSB_TRACKDIR_MASK))) &&
|
|
|
|
|
!IsInsideMM(w->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
|
|
|
|
|
!IsInsideMM(w->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && w->state != RVSB_WORMHOLE) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -983,12 +1039,40 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
|
|
|
|
|
* - No barred levelcrossing
|
|
|
|
|
* - No other vehicles in the way
|
|
|
|
|
*/
|
|
|
|
|
uint tile_count = 1 + CeilDiv(v->gcache.cached_total_length, TILE_SIZE);
|
|
|
|
|
int tile_count = 1 + CeilDiv(v->gcache.cached_total_length, TILE_SIZE);
|
|
|
|
|
TileIndex check_tile = v->tile;
|
|
|
|
|
DiagDirection dir = DirToDiagDir(v->direction);
|
|
|
|
|
TileIndexDiff check_tile_diff = TileOffsByDiagDir(DirToDiagDir(v->direction));
|
|
|
|
|
for (; tile_count != 0; tile_count--, check_tile += check_tile_diff) {
|
|
|
|
|
TileIndex behind_check_tile = v->tile - check_tile_diff;
|
|
|
|
|
|
|
|
|
|
int tile_offset = ((DiagDirToAxis(DirToDiagDir(v->direction)) == AXIS_X) ? v->x_pos : v->y_pos) & 0xF;
|
|
|
|
|
int tile_ahead_margin = ((dir == DIAGDIR_SE || dir == DIAGDIR_SW) ? TILE_SIZE - 1 - tile_offset : tile_offset);;
|
|
|
|
|
int behind_tile_count = (v->gcache.cached_total_length + tile_ahead_margin) / TILE_SIZE;
|
|
|
|
|
|
|
|
|
|
if (IsTileType(check_tile, MP_TUNNELBRIDGE)) {
|
|
|
|
|
TileIndex behind_end = GetOtherTunnelBridgeEnd(check_tile);
|
|
|
|
|
if (IsBridgeTile(check_tile) && (IsRoadCustomBridgeHeadTile(check_tile) || IsRoadCustomBridgeHeadTile(behind_end))) return;
|
|
|
|
|
if (GetTunnelBridgeDirection(check_tile) == dir) std::swap(check_tile, behind_end);
|
|
|
|
|
TileIndex veh_tile = TileVirtXY(v->x_pos, v->y_pos);
|
|
|
|
|
bool one_way = GetRoadCachedOneWayState(check_tile) != RCOWS_NORMAL;
|
|
|
|
|
if (CheckTunnelBridgeBlockedForOvertaking(&od, behind_end, check_tile, veh_tile, one_way ? 0 : (tile_count - 1), behind_tile_count)) return;
|
|
|
|
|
|
|
|
|
|
tile_count -= DistanceManhattan(check_tile, veh_tile);
|
|
|
|
|
behind_tile_count -= DistanceManhattan(behind_end, veh_tile);
|
|
|
|
|
check_tile += check_tile_diff;
|
|
|
|
|
behind_check_tile = behind_end - check_tile_diff;
|
|
|
|
|
}
|
|
|
|
|
for (; tile_count > 0; tile_count--, check_tile += check_tile_diff) {
|
|
|
|
|
od.tile = check_tile;
|
|
|
|
|
if (CheckRoadInfraUnsuitableForOvertaking(&od)) return;
|
|
|
|
|
if (IsTileType(check_tile, MP_TUNNELBRIDGE)) {
|
|
|
|
|
TileIndex ahead_end = GetOtherTunnelBridgeEnd(check_tile);
|
|
|
|
|
if (IsBridgeTile(check_tile) && (IsRoadCustomBridgeHeadTile(check_tile) || IsRoadCustomBridgeHeadTile(ahead_end))) return;
|
|
|
|
|
if (GetRoadCachedOneWayState(check_tile) == RCOWS_NORMAL && CheckTunnelBridgeBlockedForOvertaking(&od, check_tile, ahead_end, check_tile, tile_count - 1, 0)) return;
|
|
|
|
|
tile_count -= DistanceManhattan(check_tile, ahead_end);
|
|
|
|
|
check_tile = ahead_end;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (IsDriveThroughStopTile(check_tile) && GetDriveThroughStopDisallowedRoadDirections(check_tile) != DRD_NONE) {
|
|
|
|
|
const RoadStop *rs = RoadStop::GetByTile(check_tile, GetRoadStopType(check_tile));
|
|
|
|
|
DiagDirection dir = DirToDiagDir(v->direction);
|
|
|
|
@ -1003,18 +1087,22 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
|
|
|
|
|
}
|
|
|
|
|
if (CheckRoadBlockedForOvertaking(&od)) return;
|
|
|
|
|
}
|
|
|
|
|
DiagDirection dir = DirToDiagDir(v->direction);
|
|
|
|
|
int tile_offset = ((DiagDirToAxis(DirToDiagDir(v->direction)) == AXIS_X) ? v->x_pos : v->y_pos) & 0xF;
|
|
|
|
|
int tile_ahead_margin = ((dir == DIAGDIR_SE || dir == DIAGDIR_SW) ? TILE_SIZE - 1 - tile_offset : tile_offset);;
|
|
|
|
|
tile_count = (v->gcache.cached_total_length + tile_ahead_margin) / TILE_SIZE;
|
|
|
|
|
check_tile = v->tile - check_tile_diff;
|
|
|
|
|
for (; tile_count != 0; tile_count--, check_tile -= check_tile_diff) {
|
|
|
|
|
od.tile = check_tile;
|
|
|
|
|
if (tile_count == 1) {
|
|
|
|
|
RoadBits rb = GetAnyRoadBits(check_tile, RTT_ROAD);
|
|
|
|
|
if ((rb & DiagDirToRoadBits(dir)) && HasVehicleOnPos(check_tile, VEH_ROAD, &od, EnumFindVehBlockingOvertakeBehind)) return;
|
|
|
|
|
|
|
|
|
|
for (; behind_tile_count > 0; behind_tile_count--, behind_check_tile -= check_tile_diff) {
|
|
|
|
|
od.tile = behind_check_tile;
|
|
|
|
|
if (behind_tile_count == 1) {
|
|
|
|
|
RoadBits rb = GetAnyRoadBits(behind_check_tile, RTT_ROAD);
|
|
|
|
|
if ((rb & DiagDirToRoadBits(dir)) && HasVehicleOnPos(behind_check_tile, VEH_ROAD, &od, EnumFindVehBlockingOvertakeBehind)) return;
|
|
|
|
|
} else {
|
|
|
|
|
if (CheckRoadInfraUnsuitableForOvertaking(&od)) return;
|
|
|
|
|
if (IsTileType(behind_check_tile, MP_TUNNELBRIDGE)) {
|
|
|
|
|
TileIndex behind_end = GetOtherTunnelBridgeEnd(behind_check_tile);
|
|
|
|
|
if (IsBridgeTile(behind_check_tile) && (IsRoadCustomBridgeHeadTile(behind_check_tile) || IsRoadCustomBridgeHeadTile(behind_end))) return;
|
|
|
|
|
if (CheckTunnelBridgeBlockedForOvertaking(&od, behind_check_tile, behind_end, behind_check_tile, 0, behind_tile_count - 1)) return;
|
|
|
|
|
behind_tile_count -= DistanceManhattan(behind_check_tile, behind_end);
|
|
|
|
|
check_tile = behind_end;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (CheckRoadBlockedForOvertaking(&od)) return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1390,7 +1478,8 @@ static void RoadVehCheckFinishOvertake(RoadVehicle *v)
|
|
|
|
|
const RoadVehicle *last = v->Last();
|
|
|
|
|
const int front_margin = 10;
|
|
|
|
|
const int back_margin = 10;
|
|
|
|
|
switch (DirToDiagDir(v->direction)) {
|
|
|
|
|
DiagDirection dir = DirToDiagDir(v->direction);
|
|
|
|
|
switch (dir) {
|
|
|
|
|
case DIAGDIR_NE:
|
|
|
|
|
od.min_coord = v->x_pos - front_margin;
|
|
|
|
|
od.max_coord = last->x_pos + back_margin;
|
|
|
|
@ -1416,13 +1505,43 @@ static void RoadVehCheckFinishOvertake(RoadVehicle *v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TileIndexDiffC ti = TileIndexDiffCByDiagDir(DirToDiagDir(v->direction));
|
|
|
|
|
TileIndex ahead_tile = TileAddWrap(v->tile, ti.x, ti.y);
|
|
|
|
|
if (ahead_tile != INVALID_TILE && HasVehicleOnPos(ahead_tile, VEH_ROAD, &od, EnumFindVehBlockingFinishOvertake)) return;
|
|
|
|
|
bool check_ahead = true;
|
|
|
|
|
int tiles_behind = 1 + CeilDiv(v->gcache.cached_total_length, TILE_SIZE);
|
|
|
|
|
|
|
|
|
|
uint tile_count = 1 + CeilDiv(v->gcache.cached_total_length, TILE_SIZE);
|
|
|
|
|
TileIndex check_tile = v->tile;
|
|
|
|
|
for (; check_tile != INVALID_TILE && tile_count != 0; tile_count--, check_tile = TileAddWrap(check_tile, -ti.x, -ti.y)) {
|
|
|
|
|
if (IsTileType(check_tile, MP_TUNNELBRIDGE)) {
|
|
|
|
|
TileIndex ahead = GetOtherTunnelBridgeEnd(check_tile);
|
|
|
|
|
if (v->state == RVSB_WORMHOLE) {
|
|
|
|
|
check_ahead = false;
|
|
|
|
|
}
|
|
|
|
|
if (GetTunnelBridgeDirection(check_tile) == dir) {
|
|
|
|
|
check_ahead = false;
|
|
|
|
|
} else if (GetTunnelBridgeDirection(check_tile) == ReverseDiagDir(dir)) {
|
|
|
|
|
std::swap(ahead, check_tile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HasVehicleOnPos(ahead, VEH_ROAD, &od, EnumFindVehBlockingFinishOvertake)) return;
|
|
|
|
|
if (HasVehicleOnPos(check_tile, VEH_ROAD, &od, EnumFindVehBlockingFinishOvertake)) return;
|
|
|
|
|
tiles_behind -= 1 + DistanceManhattan(check_tile, TileVirtXY(v->x_pos, v->y_pos));
|
|
|
|
|
check_tile = TileAddWrap(check_tile, -ti.x, -ti.y);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (check_ahead > 0) {
|
|
|
|
|
TileIndex ahead_tile = TileAddWrap(check_tile, ti.x, ti.y);
|
|
|
|
|
if (ahead_tile != INVALID_TILE) {
|
|
|
|
|
if (HasVehicleOnPos(ahead_tile, VEH_ROAD, &od, EnumFindVehBlockingFinishOvertake)) return;
|
|
|
|
|
if (IsTileType(ahead_tile, MP_TUNNELBRIDGE) && HasVehicleOnPos(GetOtherTunnelBridgeEnd(ahead_tile), VEH_ROAD, &od, EnumFindVehBlockingFinishOvertake)) return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (; check_tile != INVALID_TILE && tiles_behind > 0; tiles_behind--, check_tile = TileAddWrap(check_tile, -ti.x, -ti.y)) {
|
|
|
|
|
if (HasVehicleOnPos(check_tile, VEH_ROAD, &od, EnumFindVehBlockingFinishOvertake)) return;
|
|
|
|
|
if (IsTileType(check_tile, MP_TUNNELBRIDGE)) {
|
|
|
|
|
TileIndex other_end = GetOtherTunnelBridgeEnd(check_tile);
|
|
|
|
|
tiles_behind -= DistanceManhattan(other_end, check_tile);
|
|
|
|
|
if (HasVehicleOnPos(other_end, VEH_ROAD, &od, EnumFindVehBlockingFinishOvertake)) return;
|
|
|
|
|
check_tile = other_end;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* road on the normal side is clear, finish overtake */
|
|
|
|
@ -1438,11 +1557,11 @@ inline byte IncreaseOvertakingCounter(RoadVehicle *v)
|
|
|
|
|
bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
|
|
|
|
|
{
|
|
|
|
|
SCOPE_INFO_FMT([&], "IndividualRoadVehicleController: %s, %s", scope_dumper().VehicleInfo(v), scope_dumper().VehicleInfo(prev));
|
|
|
|
|
if (v->overtaking != 0 && v->IsFrontEngine()) {
|
|
|
|
|
if (v->overtaking & RVSB_DRIVE_SIDE && v->IsFrontEngine()) {
|
|
|
|
|
if (IsNonOvertakingStationTile(v->tile, DirToDiagDir(v->direction))) {
|
|
|
|
|
/* Force us to be not overtaking! */
|
|
|
|
|
v->SetRoadVehicleOvertaking(0);
|
|
|
|
|
} else if (v->HasArticulatedPart() && (v->state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)v->state)) && !IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) {
|
|
|
|
|
} else if (v->HasArticulatedPart() && (v->state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)v->state)) && !IsInsideMM(v->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END) && v->state != RVSB_WORMHOLE) {
|
|
|
|
|
/* Articulated RVs may not overtake on corners */
|
|
|
|
|
v->SetRoadVehicleOvertaking(0);
|
|
|
|
|
} else if (v->HasArticulatedPart() && IsBridgeTile(v->tile) && (IsRoadCustomBridgeHeadTile(v->tile) || IsRoadCustomBridgeHeadTile(GetOtherBridgeEnd(v->tile)))) {
|
|
|
|
@ -1455,7 +1574,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
|
|
|
|
|
/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
|
|
|
|
|
* if the vehicle started a corner. To protect that, only allow an abort of
|
|
|
|
|
* overtake if we are on straight roads */
|
|
|
|
|
if (v->overtaking_ctr >= v->GetOvertakingCounterThreshold() && v->state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->state)) {
|
|
|
|
|
if (v->overtaking_ctr >= v->GetOvertakingCounterThreshold() && (v->state == RVSB_WORMHOLE || (v->state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->state)))) {
|
|
|
|
|
if (IsOneWayRoadTile(v->tile)) {
|
|
|
|
|
RoadVehCheckFinishOvertake(v);
|
|
|
|
|
} else {
|
|
|
|
@ -1475,14 +1594,35 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
|
|
|
|
|
if (v->state == RVSB_WORMHOLE) {
|
|
|
|
|
/* Vehicle is entering a depot or is on a bridge or in a tunnel */
|
|
|
|
|
GetNewVehiclePosResult gp = GetNewVehiclePos(v);
|
|
|
|
|
|
|
|
|
|
if (v->overtaking & 1) {
|
|
|
|
|
DiagDirection dir = DirToDiagDir(v->direction);
|
|
|
|
|
switch (dir) {
|
|
|
|
|
case DIAGDIR_NE:
|
|
|
|
|
case DIAGDIR_SW:
|
|
|
|
|
SB(gp.y, 0, 4, (_settings_game.vehicle.road_side ^ (dir >> 1) ^ (v->overtaking >> RVS_DRIVE_SIDE)) ? 9 : 5);
|
|
|
|
|
break;
|
|
|
|
|
case DIAGDIR_SE:
|
|
|
|
|
case DIAGDIR_NW:
|
|
|
|
|
SB(gp.x, 0, 4, (_settings_game.vehicle.road_side ^ (dir >> 1) ^ (v->overtaking >> RVS_DRIVE_SIDE)) ? 9 : 5);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
NOT_REACHED();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (v->IsFrontEngine()) {
|
|
|
|
|
const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
|
|
|
|
|
RoadVehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
|
|
|
|
|
if (u != nullptr) {
|
|
|
|
|
v->cur_speed = u->First()->cur_speed;
|
|
|
|
|
u = u->First();
|
|
|
|
|
/* There is a vehicle in front overtake it if possible */
|
|
|
|
|
byte old_overtaking = v->overtaking;
|
|
|
|
|
if (v->overtaking == 0) RoadVehCheckOvertake(v, u);
|
|
|
|
|
if (v->overtaking == old_overtaking) {
|
|
|
|
|
v->cur_speed = u->cur_speed;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
v->overtaking &= ~1;
|
|
|
|
|
|
|
|
|
|
if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) && HasBit(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y), VETS_ENTERED_WORMHOLE)) {
|
|
|
|
|
if (IsRoadCustomBridgeHeadTile(gp.new_tile)) {
|
|
|
|
@ -1999,6 +2139,7 @@ void RoadVehicle::SetRoadVehicleOvertaking(byte overtaking)
|
|
|
|
|
|
|
|
|
|
for (RoadVehicle *u = this; u != nullptr; u = u->Next()) {
|
|
|
|
|
u->overtaking = overtaking;
|
|
|
|
|
if (u->state == RVSB_WORMHOLE) u->overtaking |= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (IsInsideMM(this->state, RVSB_IN_DT_ROAD_STOP, RVSB_IN_DT_ROAD_STOP_END)) RoadStop::GetByTile(this->tile, GetRoadStopType(this->tile))->Enter(this);
|
|
|
|
|