diff --git a/src/lang/english.txt b/src/lang/english.txt index 51de0ab88b..fddcc955a7 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1269,6 +1269,7 @@ STR_CONFIG_SETTING_ORIGINAL :Original STR_CONFIG_SETTING_REALISTIC :Realistic STR_CONFIG_SETTING_TRAIN_BRAKING_REALISTIC :Realistic {PUSH_COLOUR}{RED}(Expert){POP_COLOUR} +STR_CONFIG_SETTING_TRAIN_BRAKING_ASPECT_LIMITED_ON :On {PUSH_COLOUR}{RED}(Expert, Difficult){POP_COLOUR} STR_CONFIG_SETTING_REALISTIC_BRAKING_SIGNALS_NOT_ALLOWED :{WHITE}Realistic braking can't be enabled. At least one pre-signal or two-way signal is present. @@ -1369,6 +1370,8 @@ STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL :Train accelerat STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL_HELPTEXT :Select the physics model for train acceleration. The "original" model penalises slopes equally for all vehicles. The "realistic" model penalises slopes and curves depending on various properties of the consist, like length and tractive effort STR_CONFIG_SETTING_TRAIN_BRAKING_MODEL :Train braking model: {STRING2} STR_CONFIG_SETTING_TRAIN_BRAKING_MODEL_HELPTEXT :Select the physics model for train braking. The "original" model allows trains to stop instantly. In the "realistic" model, trains have a stopping distance and will reserve ahead accordingly, trains cannot stop instantly.{}{}The "realistic" model has many implications for signalling and track layout design, and is therefore an advanced feature which may not be suitable for beginners. In particular pre-signals and two-way signals are not permitted, and PBS is used for all signalling. +STR_CONFIG_SETTING_REALISTIC_BRAKING_ASPECT_LIMITED :Realistic train braking is aspect limited: {STRING2} +STR_CONFIG_SETTING_REALISTIC_BRAKING_ASPECT_LIMITED_HELPTEXT :In the realistic train braking model, limit the look-ahead of trains to the aspect of signals (i.e. do not allow reserving and looking ahead an unlimited number of signals).{}This requires a NewGRF which provides multi-aspect signals.{}{}This is an expert setting which will likely increase gameplay difficulty and will require additional thought about signal types and placement. STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL :Road vehicle acceleration model: {STRING2} STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL_HELPTEXT :Select the physics model for road vehicle acceleration. The "original" model penalises slopes equally for all vehicles. The "realistic" model penalises slopes depending on various properties of the engine, for example 'tractive effort' diff --git a/src/pbs.cpp b/src/pbs.cpp index 29e87d1b8b..0441fe1f61 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -585,7 +585,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra if (signal_speed == 0 || (bridge_speed != 0 && bridge_speed < signal_speed)) signal_speed = bridge_speed; /* Entrance signal */ - lookahead->AddSignal(signal_speed, 0, z); + lookahead->AddSignal(signal_speed, 0, z, 0); update_z(tile, trackdir, false); @@ -599,7 +599,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra int offset = start_offset - TILE_SIZE; for (int i = 0; i < signals; i++) { offset += TILE_SIZE * spacing; - lookahead->AddSignal(signal_speed, offset, chunnel ? LookaheadTileHeightForChunnel(length, i * spacing) : z); + lookahead->AddSignal(signal_speed, offset, chunnel ? LookaheadTileHeightForChunnel(length, i * spacing) : z, 0); } /* Exit signal */ @@ -613,7 +613,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra if (signal_speed == 0 || (bridge_speed != 0 && bridge_speed < signal_speed)) signal_speed = bridge_speed; } - lookahead->AddSignal(signal_speed, end_offset, z); + lookahead->AddSignal(signal_speed, end_offset, z, 0); lookahead->SetNextExtendPositionIfUnset(); } else { @@ -656,7 +656,11 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra /* Passing through a signal from the front side */ uint16 signal_speed = GetRailTypeInfo(rt)->max_speed; if (signal_speed == 0 || (speed_restriction != 0 && speed_restriction < signal_speed)) signal_speed = speed_restriction; - lookahead->AddSignal(signal_speed, 0, z); + uint16 signal_flags = 0; + if (_non_aspect_inc_style_mask != 0 && HasBit(_non_aspect_inc_style_mask, GetSignalStyle(tile, TrackdirToTrack(trackdir)))) { + SetBit(signal_flags, TRSLAI_NO_ASPECT_INC); + } + lookahead->AddSignal(signal_speed, 0, z, signal_flags); lookahead->SetNextExtendPositionIfUnset(); } } @@ -953,7 +957,7 @@ void TryCreateLookAheadForTrainInTunnelBridge(Train *t) int offset = -(int)TILE_SIZE; for (int i = 0; i < signals; i++) { offset += TILE_SIZE * spacing; - t->lookahead->AddSignal(signal_speed, offset, HasBit(t->lookahead->flags, TRLF_CHUNNEL) ? LookaheadTileHeightForChunnel(length, i * spacing) : z); + t->lookahead->AddSignal(signal_speed, offset, HasBit(t->lookahead->flags, TRLF_CHUNNEL) ? LookaheadTileHeightForChunnel(length, i * spacing) : z, 0); } /* Exit signal */ @@ -966,7 +970,7 @@ void TryCreateLookAheadForTrainInTunnelBridge(Train *t) if (signal_speed == 0 || (bridge_speed != 0 && bridge_speed < signal_speed)) signal_speed = bridge_speed; } - t->lookahead->AddSignal(signal_speed, end_offset, z); + t->lookahead->AddSignal(signal_speed, end_offset, z, 0); t->lookahead->SetNextExtendPositionIfUnset(); } @@ -979,6 +983,37 @@ void TryCreateLookAheadForTrainInTunnelBridge(Train *t) } } +void SetTrainReservationLookaheadEnd(Train *v) +{ + if (_settings_game.vehicle.realistic_braking_aspect_limited != TRBALM_ON || _extra_aspects == 0) { + v->lookahead->lookahead_end_position = v->lookahead->reservation_end_position + 1; + return; + } + + int32 threshold = v->lookahead->current_position + 24; + uint8 known_signals_ahead = 1; + for (const TrainReservationLookAheadItem &item : v->lookahead->items) { + if (item.type == TRLIT_SIGNAL) { + if (item.start <= threshold) { + /* Signal is within visual range */ + uint8 max_aspect = _extra_aspects + (HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC) ? 1 : 2); + if (max_aspect > known_signals_ahead) known_signals_ahead = max_aspect; + } + if (!HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC)) { + known_signals_ahead--; + if (known_signals_ahead == 0) { + if (item.start > v->lookahead->lookahead_end_position) v->lookahead->lookahead_end_position = item.start; + return; + } + } + } + } + + /* Didn't need to stop at a signal along the reservation */ + v->lookahead->lookahead_end_position = v->lookahead->reservation_end_position; + if (known_signals_ahead > 1) v->lookahead->lookahead_end_position++; +} + void FillTrainReservationLookAhead(Train *v) { TileIndex tile; @@ -1033,12 +1068,16 @@ void FillTrainReservationLookAhead(Train *v) } if (!(HasAcrossTunnelBridgeReservation(end) && GetTunnelBridgeExitSignalState(end) == SIGNAL_STATE_GREEN && raw_free_tiles == INT_MAX)) { /* do not attempt to follow through a signalled tunnel/bridge if it is not empty or the far end is not reserved */ + SetTrainReservationLookaheadEnd(v); return; } } } - if (IsRailDepotTile(tile) && !GetDepotReservationTrackBits(tile)) return; + if (IsRailDepotTile(tile) && !GetDepotReservationTrackBits(tile)) { + SetTrainReservationLookaheadEnd(v); + return; + } FollowReservationFlags flags = FRF_NONE; if (HasBit(v->lookahead->flags, TRLF_TB_EXIT_FREE)) flags |= FRF_TB_EXIT_FREE; @@ -1069,6 +1108,8 @@ void FillTrainReservationLookAhead(Train *v) v->lookahead->reservation_end_tile = res.tile; v->lookahead->reservation_end_trackdir = res.trackdir; + + SetTrainReservationLookaheadEnd(v); } /** diff --git a/src/pbs.h b/src/pbs.h index 283a99587e..b81a7a142b 100644 --- a/src/pbs.h +++ b/src/pbs.h @@ -58,11 +58,16 @@ enum TrainReservationLookAheadItemType : byte { TRLIT_CURVE_SPEED = 5, ///< Curve speed limit }; +enum TrainReservationSignalLookAheadItemFlags { + TRSLAI_NO_ASPECT_INC = 0, ///< This signal does not increase the signal aspect (e.g. banner repeater) +}; + struct TrainReservationLookAheadItem { int32 start; int32 end; int16 z_pos; uint16 data_id; + uint16 data_aux; TrainReservationLookAheadItemType type; }; @@ -83,6 +88,7 @@ struct TrainReservationLookAhead { Trackdir reservation_end_trackdir; ///< The reserved trackdir on the end tile. int32 current_position; ///< Current position of the train on the reservation int32 reservation_end_position; ///< Position of the end of the reservation + int32 lookahead_end_position; ///< Position of the end of the reservation within the lookahead distance int32 next_extend_position; ///< Next position to try extending the reservation at the sighting distance of the next mid-reservation signal int16 reservation_end_z; ///< The z coordinate of the reservation end int16 tunnel_bridge_reserved_tiles; ///< How many tiles a reservation into the tunnel/bridge currently extends into the wormhole @@ -101,38 +107,38 @@ struct TrainReservationLookAhead { void AddStation(int tiles, StationID id, int16 z_pos) { int end = this->RealEndPosition(); - this->items.push_back({ end, end + (((int)TILE_SIZE) * tiles), z_pos, id, TRLIT_STATION }); + this->items.push_back({ end, end + (((int)TILE_SIZE) * tiles), z_pos, id, 0, TRLIT_STATION }); } void AddReverse(int16 z_pos) { int end = this->RealEndPosition(); - this->items.push_back({ end, end, z_pos, 0, TRLIT_REVERSE }); + this->items.push_back({ end, end, z_pos, 0, 0, TRLIT_REVERSE }); } void AddTrackSpeedLimit(uint16 speed, int offset, int duration, int16 z_pos) { int end = this->RealEndPosition(); - this->items.push_back({ end + offset, end + offset + duration, z_pos, speed, TRLIT_TRACK_SPEED }); + this->items.push_back({ end + offset, end + offset + duration, z_pos, speed, 0, TRLIT_TRACK_SPEED }); } void AddSpeedRestriction(uint16 speed, int offset, int duration, int16 z_pos) { int end = this->RealEndPosition(); - this->items.push_back({ end + offset, end + offset + duration, z_pos, speed, TRLIT_SPEED_RESTRICTION }); + this->items.push_back({ end + offset, end + offset + duration, z_pos, speed, 0, TRLIT_SPEED_RESTRICTION }); this->speed_restriction = speed; } - void AddSignal(uint16 target_speed, int offset, int16 z_pos) + void AddSignal(uint16 target_speed, int offset, int16 z_pos, uint16 flags) { int end = this->RealEndPosition(); - this->items.push_back({ end + offset, end + offset, z_pos, target_speed, TRLIT_SIGNAL }); + this->items.push_back({ end + offset, end + offset, z_pos, target_speed, flags, TRLIT_SIGNAL }); } void AddCurveSpeedLimit(uint16 target_speed, int offset, int16 z_pos) { int end = this->RealEndPosition(); - this->items.push_back({ end + offset, end + offset, z_pos, target_speed, TRLIT_CURVE_SPEED }); + this->items.push_back({ end + offset, end + offset, z_pos, target_speed, 0, TRLIT_CURVE_SPEED }); } void SetNextExtendPosition(); @@ -155,6 +161,7 @@ bool ValidateLookAhead(const Train *v); PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res = nullptr, FollowTrainReservationFlags flags = FTRF_NONE); void ApplyAvailableFreeTunnelBridgeTiles(TrainReservationLookAhead *lookahead, int free_tiles, TileIndex tile, TileIndex end); void TryCreateLookAheadForTrainInTunnelBridge(Train *t); +void SetTrainReservationLookaheadEnd(Train *v); void FillTrainReservationLookAhead(Train *v); void SetLookAheadNextExtendPosition(Train *v); void SetLookAheadNextExtendPositionIfUnset(Train *v); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 20d6dba6a6..a98bec1cbd 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -4082,6 +4082,14 @@ bool AfterLoadGame() _aspect_cfg_hash = 0; } + if (!SlXvIsFeaturePresent(XSLFI_REALISTIC_TRAIN_BRAKING, 9) && _settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + for (Train *t : Train::Iterate()) { + if (t->lookahead != nullptr) { + t->lookahead->lookahead_end_position = t->lookahead->reservation_end_position + 1; + } + } + } + InitializeRoadGUI(); /* This needs to be done after conversion. */ diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index b08fe809a8..5961ba8be6 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -151,7 +151,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_ANIMATED_TILE_EXTRA, XSCF_NULL, 1, 1, "animated_tile_extra", nullptr, nullptr, nullptr }, { XSLFI_NEWGRF_INFO_EXTRA, XSCF_NULL, 1, 1, "newgrf_info_extra", nullptr, nullptr, nullptr }, { XSLFI_INDUSTRY_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 1, 1, "industry_cargo_adj", nullptr, nullptr, nullptr }, - { XSLFI_REALISTIC_TRAIN_BRAKING,XSCF_NULL, 8, 8, "realistic_train_braking", nullptr, nullptr, "VLKA" }, + { XSLFI_REALISTIC_TRAIN_BRAKING,XSCF_NULL, 9, 9, "realistic_train_braking", nullptr, nullptr, "VLKA" }, { XSLFI_INFLATION_FIXED_DATES, XSCF_IGNORABLE_ALL, 1, 1, "inflation_fixed_dates", nullptr, nullptr, nullptr }, { XSLFI_WATER_FLOODING, XSCF_NULL, 2, 2, "water_flooding", nullptr, nullptr, nullptr }, { XSLFI_MORE_HOUSES, XSCF_NULL, 2, 2, "more_houses", nullptr, nullptr, nullptr }, diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 6f70e39de7..d61158266a 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -1387,6 +1387,7 @@ const SaveLoadTable GetVehicleLookAheadDescription() SLE_VAR(TrainReservationLookAhead, reservation_end_trackdir, SLE_UINT8), SLE_VAR(TrainReservationLookAhead, current_position, SLE_INT32), SLE_VAR(TrainReservationLookAhead, reservation_end_position, SLE_INT32), + SLE_CONDVAR_X(TrainReservationLookAhead, lookahead_end_position, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 9)), SLE_VAR(TrainReservationLookAhead, reservation_end_z, SLE_INT16), SLE_VAR(TrainReservationLookAhead, tunnel_bridge_reserved_tiles, SLE_INT16), SLE_VAR(TrainReservationLookAhead, flags, SLE_UINT16), @@ -1406,6 +1407,7 @@ const SaveLoadTable GetVehicleLookAheadItemDescription() SLE_VAR(TrainReservationLookAheadItem, end, SLE_INT32), SLE_VAR(TrainReservationLookAheadItem, z_pos, SLE_INT16), SLE_VAR(TrainReservationLookAheadItem, data_id, SLE_UINT16), + SLE_CONDVAR_X(TrainReservationLookAheadItem, data_aux, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 9)), SLE_VAR(TrainReservationLookAheadItem, type, SLE_UINT8), }; diff --git a/src/settings.cpp b/src/settings.cpp index a6e8904d65..15f5b10c11 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1138,6 +1138,7 @@ static void TrainBrakingModelChanged(int32 new_value) UpdateAllBlockSignals(); InvalidateWindowData(WC_BUILD_SIGNAL, 0); + InvalidateWindowClassesData(WC_GAME_OPTIONS); } /** diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 15b3edc237..a837105a1e 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2018,6 +2018,7 @@ static SettingsContainer &GetSettingsTree() { physics->Add(new SettingEntry("vehicle.train_acceleration_model")); physics->Add(new SettingEntry("vehicle.train_braking_model")); + physics->Add(new ConditionallyHiddenSettingEntry("vehicle.realistic_braking_aspect_limited", []() -> bool { return GetGameSettings().vehicle.train_braking_model != TBM_REALISTIC; })); physics->Add(new SettingEntry("vehicle.train_slope_steepness")); physics->Add(new SettingEntry("vehicle.wagon_speed_limits")); physics->Add(new SettingEntry("vehicle.train_speed_adaptation")); diff --git a/src/settings_type.h b/src/settings_type.h index b0f44b1496..0c6d26c495 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -603,6 +603,7 @@ struct VehicleSettings { uint8 smoke_amount; ///< amount of smoke/sparks locomotives produce uint8 train_acceleration_model; ///< realistic acceleration for trains uint8 train_braking_model; ///< braking model for trains + uint8 realistic_braking_aspect_limited; ///< realistic braking lookahead is aspect limited uint8 roadveh_acceleration_model; ///< realistic acceleration for road vehicles uint8 train_slope_steepness; ///< Steepness of hills for trains when using realistic acceleration uint8 roadveh_slope_steepness; ///< Steepness of hills for road vehicles when using realistic acceleration diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index 780c33f40f..7b21cb3d07 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -225,6 +225,9 @@ class NIHVehicle : public NIHelper { }; b = buffer + seprintf(buffer, lastof(buffer), " Position: current: %d, z: %d, end: %d, remaining: %d", l.current_position, stats.z_pos, l.reservation_end_position, l.reservation_end_position - l.current_position); + if (l.lookahead_end_position <= l.reservation_end_position) { + b += seprintf(b, lastof(buffer), ", (lookahead: end: %d, remaining: %d)", l.lookahead_end_position, l.lookahead_end_position - l.current_position); + } if (l.next_extend_position > l.current_position) { b += seprintf(b, lastof(buffer), ", next extend position: %d (dist: %d)", l.next_extend_position, l.next_extend_position - l.current_position); } @@ -273,7 +276,12 @@ class NIHVehicle : public NIHelper { if (item.data_id > 0) print_braking_speed(item.start, item.data_id, item.z_pos); break; case TRLIT_SIGNAL: - b += seprintf(b, lastof(buffer), "signal: target speed: %u", item.data_id); + b += seprintf(b, lastof(buffer), "signal: target speed: %u, flags:", item.data_id); + if (HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC)) b += seprintf(b, lastof(buffer), "n"); + if (_settings_game.vehicle.realistic_braking_aspect_limited == TRBALM_ON && l.lookahead_end_position == item.start) { + b += seprintf(b, lastof(buffer), ", lookahead end"); + print_braking_speed(item.start, 0, item.z_pos); + } break; case TRLIT_CURVE_SPEED: b += seprintf(b, lastof(buffer), "curve speed: %u", item.data_id); diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index d49694e006..43ca0d1a0b 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -125,6 +125,12 @@ static const SettingDescEnumEntry _train_braking_model[] = { { 0, STR_NULL } }; +static const SettingDescEnumEntry _realistic_braking_aspect_limited[] = { +{ TRBALM_OFF, STR_CONFIG_SETTING_OFF }, +{ TRBALM_ON, STR_CONFIG_SETTING_TRAIN_BRAKING_ASPECT_LIMITED_ON }, +{ 0, STR_NULL } +}; + static const SettingDescEnumEntry _station_delivery_mode[] = { { SD_NEAREST_FIRST, STR_CONFIG_SETTING_ORIGINAL}, { SD_BALANCED, STR_CONFIG_SETTING_DELIVERY_BALANCED}, @@ -1327,6 +1333,16 @@ post_cb = TrainBrakingModelChanged cat = SC_EXPERT patxname = ""realistic_braking.vehicle.train_braking_model"" +[SDT_ENUM] +var = vehicle.realistic_braking_aspect_limited +type = SLE_UINT8 +def = TRBALM_OFF +enumlist = _realistic_braking_aspect_limited +str = STR_CONFIG_SETTING_REALISTIC_BRAKING_ASPECT_LIMITED +strhelp = STR_CONFIG_SETTING_REALISTIC_BRAKING_ASPECT_LIMITED_HELPTEXT +cat = SC_EXPERT +patxname = ""realistic_braking.vehicle.realistic_braking_aspect_limited"" + [SDT_VAR] var = vehicle.roadveh_acceleration_model type = SLE_UINT8 diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 0722d14ca6..ff0b4aa57a 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -958,6 +958,9 @@ static void ApplyLookAheadItem(const Train *v, const TrainReservationLookAheadIt break; case TRLIT_SIGNAL: + if (_settings_game.vehicle.realistic_braking_aspect_limited == TRBALM_ON && v->lookahead->lookahead_end_position == item.start) { + limit_advisory_speed(item.start, 0, item.z_pos); + } break; case TRLIT_CURVE_SPEED: @@ -982,6 +985,7 @@ static void AdvanceLookAheadPosition(Train *v) const int32 old_position = v->lookahead->current_position; v->lookahead->current_position = 0; v->lookahead->reservation_end_position -= old_position; + v->lookahead->lookahead_end_position -= old_position; v->lookahead->next_extend_position -= old_position; for (TrainReservationLookAheadItem &item : v->lookahead->items) { item.start -= old_position; @@ -1008,6 +1012,7 @@ static void AdvanceLookAheadPosition(Train *v) } if (v->lookahead->current_position == v->lookahead->next_extend_position) { + SetTrainReservationLookaheadEnd(v); TryLongReserveChooseTrainTrackFromReservationEnd(v, true); v->lookahead->SetNextExtendPositionIfUnset(); } @@ -3990,6 +3995,8 @@ static bool IsReservationLookAheadLongEnough(const Train *v, const ChooseTrainTr if (v->lookahead->reservation_end_position >= v->lookahead->current_position + v->reverse_distance - 1) return true; } + if (v->lookahead->lookahead_end_position <= v->lookahead->reservation_end_position && _settings_game.vehicle.realistic_braking_aspect_limited == TRBALM_ON) return true; + TrainDecelerationStats stats(v, v->lookahead->cached_zpos); bool found_signal = false; @@ -4985,6 +4992,7 @@ static bool IsTooCloseBehindTrain(Train *t, TileIndex tile, uint16 distance, boo TileIndex end = GetOtherTunnelBridgeEnd(t->tile); const int raw_free_tiles = GetAvailableFreeTilesInSignalledTunnelBridge(t->tile, end, tile); ApplyAvailableFreeTunnelBridgeTiles(t->lookahead.get(), raw_free_tiles + ((raw_free_tiles != INT_MAX) ? DistanceManhattan(t->tile, tile) : 0), t->tile, end); + SetTrainReservationLookaheadEnd(t); if (!LookaheadWithinCurrentTunnelBridge(t)) { /* Try to extend the reservation beyond the tunnel/bridge exit */ diff --git a/src/vehicle_type.h b/src/vehicle_type.h index 2e1a8141fd..602661bfb9 100644 --- a/src/vehicle_type.h +++ b/src/vehicle_type.h @@ -108,6 +108,12 @@ enum TrainBrakingModel { TBM_REALISTIC, }; +/** Train realistic braking aspect limited mode. */ +enum TrainRealisticBrakingAspectLimitedMode { + TRBALM_OFF, + TRBALM_ON, +}; + /** Visualisation contexts of vehicles and engines. */ enum EngineImageType { EIT_ON_MAP = 0x00, ///< Vehicle drawn in viewport.