Tracerestrict: Do not acquire slots a second time when front passes signal

If slot acquire was already handled during reservation
This commit is contained in:
Jonathan G Rennison
2024-01-20 15:41:24 +00:00
parent 5e2a8861f9
commit 5a731c04f3

View File

@@ -5287,12 +5287,14 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
t->UpdatePosition(); t->UpdatePosition();
} }
bool ok = try_exit_reservation(); bool ok;
if (!ok && (t->lookahead->reservation_end_position >= t->lookahead->current_position && t->lookahead->reservation_end_position > t->lookahead->current_position + tile_margin)) { if (t->lookahead->reservation_end_position >= t->lookahead->current_position && t->lookahead->reservation_end_position > t->lookahead->current_position + tile_margin) {
/* Reservation was made previously and was valid then. /* Reservation was made previously and was valid then.
* To avoid unexpected braking due to stopping short of the lookahead end, * To avoid unexpected braking due to stopping short of the lookahead end,
* just carry on even if the end is not a safe waiting point now. */ * just carry on even if the end is not a safe waiting point now. */
ok = true; ok = true;
} else {
ok = try_exit_reservation();
} }
if (ok) { if (ok) {
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
@@ -5466,6 +5468,30 @@ void HandleTraceRestrictSpeedRestrictionAction(const TraceRestrictProgramResult
} }
} }
template <typename AllowSlotAcquireT, typename PostProcessResultT>
void TrainControllerTraceRestrictFrontEvaluation(TileIndex tile, Trackdir dir, Train *v, TraceRestrictProgramActionsUsedFlags extra_action_used_flags, AllowSlotAcquireT allow_slot_acquire, PostProcessResultT post_process_result)
{
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(dir));
if (prog == nullptr) return;
TraceRestrictProgramActionsUsedFlags actions_used_flags = extra_action_used_flags | TRPAUF_SLOT_RELEASE_FRONT | TRPAUF_SPEED_RESTRICTION | TRPAUF_SPEED_ADAPTATION | TRPAUF_CHANGE_COUNTER;
const bool slot_acquire_allowed = allow_slot_acquire();
if (slot_acquire_allowed) actions_used_flags |= TRPAUF_SLOT_ACQUIRE;
if ((prog->actions_used_flags & actions_used_flags) == 0) return;
TraceRestrictProgramResult out;
TraceRestrictProgramInput input(tile, dir, nullptr, nullptr);
input.permitted_slot_operations = TRPISP_RELEASE_FRONT | TRPISP_CHANGE_COUNTER;
if (slot_acquire_allowed) input.permitted_slot_operations |= TRPISP_ACQUIRE;
prog->Execute(v, input, out);
HandleTraceRestrictSpeedRestrictionAction(out, v, dir);
post_process_result(out);
}
/** /**
* Move a vehicle chain one movement stop forwards. * Move a vehicle chain one movement stop forwards.
* @param v First vehicle to move. * @param v First vehicle to move.
@@ -5652,19 +5678,15 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
if (IsPlainRailTile(gp.new_tile) && HasSignals(gp.new_tile) && IsRestrictedSignal(gp.new_tile)) { if (IsPlainRailTile(gp.new_tile) && HasSignals(gp.new_tile) && IsRestrictedSignal(gp.new_tile)) {
const Trackdir dir = FindFirstTrackdir(trackdirbits); const Trackdir dir = FindFirstTrackdir(trackdirbits);
if (HasSignalOnTrack(gp.new_tile, TrackdirToTrack(dir))) { if (HasSignalOnTrack(gp.new_tile, TrackdirToTrack(dir))) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.new_tile, TrackdirToTrack(dir)); TrainControllerTraceRestrictFrontEvaluation(gp.new_tile, dir, v, TRPAUF_REVERSE, [&]() -> bool {
if (prog && prog->actions_used_flags & (TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_RELEASE_FRONT | TRPAUF_REVERSE | TRPAUF_SPEED_RESTRICTION | TRPAUF_SPEED_ADAPTATION | TRPAUF_CHANGE_COUNTER)) { return !IsPbsSignal(GetSignalType(gp.new_tile, TrackdirToTrack(dir)));
TraceRestrictProgramResult out; }, [&](const TraceRestrictProgramResult &out) {
TraceRestrictProgramInput input(gp.new_tile, dir, nullptr, nullptr);
input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_RELEASE_FRONT | TRPISP_CHANGE_COUNTER;
prog->Execute(v, input, out);
if (out.flags & TRPRF_REVERSE && GetSignalType(gp.new_tile, TrackdirToTrack(dir)) == SIGTYPE_PBS && if (out.flags & TRPRF_REVERSE && GetSignalType(gp.new_tile, TrackdirToTrack(dir)) == SIGTYPE_PBS &&
!HasSignalOnTrackdir(gp.new_tile, dir)) { !HasSignalOnTrackdir(gp.new_tile, dir)) {
v->reverse_distance = v->gcache.cached_total_length + (IsDiagonalTrack(TrackdirToTrack(dir)) ? 16 : 8); v->reverse_distance = v->gcache.cached_total_length + (IsDiagonalTrack(TrackdirToTrack(dir)) ? 16 : 8);
SetWindowDirty(WC_VEHICLE_VIEW, v->index); SetWindowDirty(WC_VEHICLE_VIEW, v->index);
} }
HandleTraceRestrictSpeedRestrictionAction(out, v, dir); });
}
} }
} }
} }
@@ -5810,14 +5832,10 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
if (v->IsFrontEngine() && IsTunnelBridgeSignalSimulationEntrance(old_tile) && (IsTunnelBridgeRestrictedSignal(old_tile) || _settings_game.vehicle.train_speed_adaptation)) { if (v->IsFrontEngine() && IsTunnelBridgeSignalSimulationEntrance(old_tile) && (IsTunnelBridgeRestrictedSignal(old_tile) || _settings_game.vehicle.train_speed_adaptation)) {
const Trackdir trackdir = GetTunnelBridgeEntranceTrackdir(old_tile); const Trackdir trackdir = GetTunnelBridgeEntranceTrackdir(old_tile);
if (IsTunnelBridgeRestrictedSignal(old_tile)) { if (IsTunnelBridgeRestrictedSignal(old_tile)) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(old_tile, TrackdirToTrack(trackdir)); TrainControllerTraceRestrictFrontEvaluation(old_tile, trackdir, v, TRPAUF_NONE, [&]() -> bool {
if (prog && prog->actions_used_flags & (TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_RELEASE_FRONT | TRPAUF_SPEED_RESTRICTION | TRPAUF_SPEED_ADAPTATION | TRPAUF_CHANGE_COUNTER)) { /* Only acquire slot when not using realistic braking, as the tunnel/bridge entrance otherwise acts as a block signal */
TraceRestrictProgramResult out; return _settings_game.vehicle.train_braking_model != TBM_REALISTIC;
TraceRestrictProgramInput input(old_tile, trackdir, nullptr, nullptr); }, [&](const TraceRestrictProgramResult &out) {});
input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_RELEASE_FRONT | TRPISP_CHANGE_COUNTER;
prog->Execute(v, input, out);
HandleTraceRestrictSpeedRestrictionAction(out, v, trackdir);
}
} }
if (_settings_game.vehicle.train_speed_adaptation) { if (_settings_game.vehicle.train_speed_adaptation) {
SetSignalTrainAdaptationSpeed(v, old_tile, TrackdirToTrack(trackdir)); SetSignalTrainAdaptationSpeed(v, old_tile, TrackdirToTrack(trackdir));
@@ -5858,14 +5876,9 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse)
leaving = true; leaving = true;
if (IsTunnelBridgeRestrictedSignal(gp.new_tile) && IsTunnelBridgeSignalSimulationExit(gp.new_tile)) { if (IsTunnelBridgeRestrictedSignal(gp.new_tile) && IsTunnelBridgeSignalSimulationExit(gp.new_tile)) {
const Trackdir trackdir = GetTunnelBridgeExitTrackdir(gp.new_tile); const Trackdir trackdir = GetTunnelBridgeExitTrackdir(gp.new_tile);
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(gp.new_tile, TrackdirToTrack(trackdir)); TrainControllerTraceRestrictFrontEvaluation(gp.new_tile, trackdir, v, TRPAUF_NONE, [&]() -> bool {
if (prog && prog->actions_used_flags & (TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_RELEASE_FRONT | TRPAUF_SPEED_RESTRICTION | TRPAUF_SPEED_ADAPTATION | TRPAUF_CHANGE_COUNTER)) { return !IsTunnelBridgeEffectivelyPBS(gp.new_tile);
TraceRestrictProgramResult out; }, [&](const TraceRestrictProgramResult &out) {});
TraceRestrictProgramInput input(gp.new_tile, trackdir, nullptr, nullptr);
input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_RELEASE_FRONT | TRPISP_CHANGE_COUNTER;
prog->Execute(v, input, out);
HandleTraceRestrictSpeedRestrictionAction(out, v, trackdir);
}
} }
} else { } else {
if (IsTooCloseBehindTrain(v, gp.new_tile, v->wait_counter, distance == 0)) { if (IsTooCloseBehindTrain(v, gp.new_tile, v->wait_counter, distance == 0)) {