diff --git a/src/pbs.cpp b/src/pbs.cpp index dea262268e..2e937d926a 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -478,7 +478,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsTunnelBridgeSignalSimulationEntrance(tile)) { TileIndex end = GetOtherTunnelBridgeEnd(tile); if (HasAcrossTunnelBridgeReservation(end) && GetTunnelBridgeExitSignalState(end) == SIGNAL_STATE_GREEN && - ((flags & FRF_TB_EXIT_FREE) || TunnelBridgeIsFree(tile, end, nullptr, true).Succeeded())) { + ((flags & FRF_TB_EXIT_FREE) || TunnelBridgeIsFree(tile, end, nullptr, TBIFM_ACROSS_ONLY).Succeeded())) { /* skip far end */ if (lookahead != nullptr) { lookahead->reservation_end_position += (DistanceManhattan(tile, end) - 1) * TILE_SIZE; @@ -501,7 +501,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra if ((flags & FRF_IGNORE_ONEWAY) && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsTunnelBridgeSignalSimulationExit(tile) && GetTunnelBridgeExitSignalState(tile) == SIGNAL_STATE_GREEN) { TileIndex end = GetOtherTunnelBridgeEnd(tile); - if (HasAcrossTunnelBridgeReservation(end) && TunnelBridgeIsFree(tile, end, nullptr, true).Succeeded()) { + if (HasAcrossTunnelBridgeReservation(end) && TunnelBridgeIsFree(tile, end, nullptr, TBIFM_ACROSS_ONLY).Succeeded()) { /* skip far end */ tile = end; trackdir = GetTunnelBridgeExitTrackdir(tile); @@ -729,7 +729,7 @@ static void FollowReservationEnumerate(Owner o, RailTypes rts, TileIndex tile, T if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsTunnelBridgeSignalSimulationEntrance(tile)) { TileIndex end = GetOtherTunnelBridgeEnd(tile); if (HasAcrossTunnelBridgeReservation(end) && GetTunnelBridgeExitSignalState(end) == SIGNAL_STATE_GREEN && - ((flags & FRF_TB_EXIT_FREE) || TunnelBridgeIsFree(tile, end, nullptr, true).Succeeded())) { + ((flags & FRF_TB_EXIT_FREE) || TunnelBridgeIsFree(tile, end, nullptr, TBIFM_ACROSS_ONLY).Succeeded())) { /* skip far end */ Trackdir end_trackdir = GetTunnelBridgeExitTrackdir(end); tile = end; @@ -741,7 +741,7 @@ static void FollowReservationEnumerate(Owner o, RailTypes rts, TileIndex tile, T if ((flags & FRF_IGNORE_ONEWAY) && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsTunnelBridgeSignalSimulationExit(tile) && GetTunnelBridgeExitSignalState(tile) == SIGNAL_STATE_GREEN) { TileIndex end = GetOtherTunnelBridgeEnd(tile); - if (HasAcrossTunnelBridgeReservation(end) && TunnelBridgeIsFree(tile, end, nullptr, true).Succeeded()) { + if (HasAcrossTunnelBridgeReservation(end) && TunnelBridgeIsFree(tile, end, nullptr, TBIFM_ACROSS_ONLY).Succeeded()) { /* skip far end */ tile = end; trackdir = GetTunnelBridgeExitTrackdir(tile); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index bca6e79893..8d2604914f 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1496,7 +1496,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, if (!ValParamTrackOrientation(track) || !IsTrackAcrossTunnelBridge(tile, track)) { return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); } - CommandCost ret = TunnelBridgeIsFree(tile, GetOtherTunnelBridgeEnd(tile), nullptr, true); + CommandCost ret = TunnelBridgeIsFree(tile, GetOtherTunnelBridgeEnd(tile), nullptr, TBIFM_ACROSS_ONLY); if (ret.Failed()) return ret; } else if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) { return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK); @@ -2185,7 +2185,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 } if (!IsTunnelBridgeWithSignalSimulation(tile)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS); TileIndex end = GetOtherTunnelBridgeEnd(tile); - CommandCost ret = TunnelBridgeIsFree(tile, end, nullptr, true); + CommandCost ret = TunnelBridgeIsFree(tile, end, nullptr, TBIFM_ACROSS_ONLY); if (ret.Failed()) return ret; cost *= GetTunnelBridgeSignalSimulationSignalCount(tile, end); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 5342545da6..06696e0a21 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3593,7 +3593,7 @@ static void ClearPathReservation(const Train *v, TileIndex tile, Trackdir track_ /* Are we just leaving a tunnel/bridge? */ if (TrackdirExitsTunnelBridge(tile, track_dir)) { TileIndex end = GetOtherTunnelBridgeEnd(tile); - bool free = TunnelBridgeIsFree(tile, end, v, true).Succeeded(); + bool free = TunnelBridgeIsFree(tile, end, v, TBIFM_ACROSS_ONLY).Succeeded(); HandleLastTunnelBridgeSignals(tile, end, ReverseDiagDir(GetTunnelBridgeDirection(tile)), free); } } else if (tunbridge_clear_unsignaled_other_end) { @@ -3720,7 +3720,7 @@ void FreeTrainTrackReservation(Train *v, TileIndex origin, Trackdir orig_td) } } else if (IsTunnelBridgeWithSignalSimulation(tile) && TrackdirExitsTunnelBridge(tile, td)) { TileIndex end = GetOtherTunnelBridgeEnd(tile); - bool free = TunnelBridgeIsFree(tile, end, v, true).Succeeded(); + bool free = TunnelBridgeIsFree(tile, end, v, TBIFM_ACROSS_ONLY).Succeeded(); if (!free) break; } @@ -6107,7 +6107,7 @@ static Vehicle *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data) static void SetSignalledBridgeTunnelGreenIfClear(TileIndex tile, TileIndex end) { - if (TunnelBridgeIsFree(tile, end, nullptr, true).Succeeded()) { + if (TunnelBridgeIsFree(tile, end, nullptr, TBIFM_ACROSS_ONLY).Succeeded()) { auto process_tile = [](TileIndex t) { if (IsTunnelBridgeSignalSimulationEntrance(t)) { if (IsBridge(t)) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 02837bb6a8..5410af5918 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -619,7 +619,7 @@ bool IsTrainCollidableRoadVehicleOnGround(TileIndex tile) struct GetVehicleTunnelBridgeProcData { const Vehicle *v; TileIndex t; - bool across_only; + TunnelBridgeIsFreeMode mode; }; /** Procedure called for every vehicle found in tunnel/bridge in the hash map */ @@ -628,9 +628,11 @@ static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data) const GetVehicleTunnelBridgeProcData *info = (GetVehicleTunnelBridgeProcData*) data; if (v == info->v) return nullptr; - if (v->type == VEH_TRAIN && info->across_only && IsBridge(info->t)) { + if (v->type == VEH_TRAIN && info->mode != TBIFM_ALL && IsBridge(info->t)) { TrackBits vehicle_track = Train::From(v)->track; - if (!(vehicle_track & TRACK_BIT_WORMHOLE) && !(GetAcrossBridgePossibleTrackBits(info->t) & vehicle_track)) return nullptr; + if (!(vehicle_track & TRACK_BIT_WORMHOLE)) { + if (info->mode == TBIFM_ACROSS_ONLY && !(GetAcrossBridgePossibleTrackBits(info->t) & vehicle_track)) return nullptr; + } } return v; @@ -641,10 +643,10 @@ static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data) * @param tile first end * @param endtile second end * @param ignore Ignore this vehicle when searching - * @param across_only Only find vehicles which are passing across the bridge/tunnel or on connecting bridge head track pieces + * @param mode Whether to only find vehicles which are passing across the bridge/tunnel or on connecting bridge head track pieces * @return Succeeded command (if tunnel/bridge is free) or failed command (if a vehicle is using the tunnel/bridge). */ -CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore, bool across_only) +CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore, TunnelBridgeIsFreeMode mode) { /* Value v is not safe in MP games, however, it is used to generate a local * error message only (which may be different for different machines). @@ -653,7 +655,7 @@ CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle GetVehicleTunnelBridgeProcData data; data.v = ignore; data.t = tile; - data.across_only = across_only; + data.mode = mode; VehicleType type = static_cast(GetTunnelBridgeTransportType(tile)); Vehicle *v = VehicleFromPos(tile, type, &data, &GetVehicleTunnelBridgeProc, true); if (v == nullptr) { diff --git a/src/vehicle_func.h b/src/vehicle_func.h index 5b8b3f24c8..ce88600116 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.h @@ -132,7 +132,12 @@ void ViewportAddVehicles(DrawPixelInfo *dpi, bool update_vehicles); void ViewportMapDrawVehicles(DrawPixelInfo *dpi, Viewport *vp); void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical); -CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore = nullptr, bool across_only = false); + +enum TunnelBridgeIsFreeMode { + TBIFM_ALL, + TBIFM_ACROSS_ONLY, +}; +CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore = nullptr, TunnelBridgeIsFreeMode mode = TBIFM_ALL); Train *GetTrainClosestToTunnelBridgeEnd(TileIndex tile, TileIndex other_tile); int GetAvailableFreeTilesInSignalledTunnelBridge(TileIndex entrance, TileIndex exit, TileIndex tile); int GetAvailableFreeTilesInSignalledTunnelBridgeWithStartOffset(TileIndex entrance, TileIndex exit, int offset);