diff --git a/src/pbs.cpp b/src/pbs.cpp index 2e937d926a..c73503cb03 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -1099,14 +1099,13 @@ void TryCreateLookAheadForTrainInTunnelBridge(Train *t) } } -void SetTrainReservationLookaheadEnd(Train *v) +int AdvanceTrainReservationLookaheadEnd(const Train *v, int lookahead_end_position) { 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; + return v->lookahead->reservation_end_position + 1; } - if (v->lookahead->lookahead_end_position > v->lookahead->reservation_end_position) return; + if (lookahead_end_position > v->lookahead->reservation_end_position) return lookahead_end_position; int32 threshold = v->lookahead->current_position + 24; uint8 known_signals_ahead = 1; @@ -1125,8 +1124,8 @@ void SetTrainReservationLookaheadEnd(Train *v) known_signals_ahead = 1; continue; } else { - if (item.start > v->lookahead->lookahead_end_position) v->lookahead->lookahead_end_position = item.start; - return; + if (item.start > lookahead_end_position) lookahead_end_position = item.start; + return lookahead_end_position; } } @@ -1141,18 +1140,24 @@ void SetTrainReservationLookaheadEnd(Train *v) if (!HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC) || !allow_skip_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; + if (item.start > lookahead_end_position) lookahead_end_position = item.start; + return lookahead_end_position; } } } } /* Didn't need to stop at a signal along the reservation */ - if (v->lookahead->reservation_end_position >= v->lookahead->lookahead_end_position) { - v->lookahead->lookahead_end_position = v->lookahead->reservation_end_position; - if (known_signals_ahead > 1) v->lookahead->lookahead_end_position++; + if (v->lookahead->reservation_end_position >= lookahead_end_position) { + lookahead_end_position = v->lookahead->reservation_end_position; + if (known_signals_ahead > 1) lookahead_end_position++; } + return lookahead_end_position; +} + +void SetTrainReservationLookaheadEnd(Train *v) +{ + v->lookahead->lookahead_end_position = AdvanceTrainReservationLookaheadEnd(v, v->lookahead->lookahead_end_position); } void FillTrainReservationLookAhead(Train *v) diff --git a/src/pbs.h b/src/pbs.h index 0f6726bc27..e62b343e74 100644 --- a/src/pbs.h +++ b/src/pbs.h @@ -164,6 +164,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); +int AdvanceTrainReservationLookaheadEnd(const Train *v, int lookahead_end_position); void SetTrainReservationLookaheadEnd(Train *v); void FillTrainReservationLookAhead(Train *v); bool TrainReservationPassesThroughTile(const Train *v, TileIndex search_tile); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 28f06d1098..7a846f620f 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4120,6 +4120,7 @@ static bool IsReservationLookAheadLongEnough(const Train *v, const ChooseTrainTr int signal_speed = 0; int signal_position = 0; int signal_z = 0; + bool signal_limited_lookahead_check = false; for (const TrainReservationLookAheadItem &item : v->lookahead->items) { if (item.type == TRLIT_REVERSE) { @@ -4139,6 +4140,21 @@ static bool IsReservationLookAheadLongEnough(const Train *v, const ChooseTrainTr signal_z = item.z_pos; found_signal = true; } + + if (item.type == TRLIT_SIGNAL && _settings_game.vehicle.realistic_braking_aspect_limited == TRBALM_ON && item.start <= v->lookahead->current_position + 24) { + if (HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC) || HasBit(item.data_aux, TRSLAI_NEXT_ONLY) || HasBit(item.data_aux, TRSLAI_COMBINED_SHUNT)) { + signal_limited_lookahead_check = true; + } + } + } + + if (signal_limited_lookahead_check) { + /* Do not unnecessarily extend the reservation when passing a signal within the reservation which could not display an aspect + * beyond the current end of the reservation, e.g. banner repeaters and shunt signals */ + if (AdvanceTrainReservationLookaheadEnd(v, v->lookahead->current_position + 24) <= v->lookahead->reservation_end_position && + v->lookahead->reservation_end_position > v->lookahead->current_position + 24) { + return true; + } } if (found_signal) {