Tracerestrict: Add long reserve (unless stopping) mode

Requires realistic braking
This commit is contained in:
Jonathan G Rennison
2023-10-03 20:59:28 +01:00
parent b299c4dce8
commit 0620026d56
6 changed files with 41 additions and 11 deletions

View File

@@ -890,6 +890,7 @@ STR_TRACE_RESTRICT_RESERVE_THROUGH :Reserve through
STR_TRACE_RESTRICT_RESERVE_THROUGH_CANCEL :Cancel reserve through STR_TRACE_RESTRICT_RESERVE_THROUGH_CANCEL :Cancel reserve through
STR_TRACE_RESTRICT_LONG_RESERVE :Long reserve STR_TRACE_RESTRICT_LONG_RESERVE :Long reserve
STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL :Cancel long reserve STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL :Cancel long reserve
STR_TRACE_RESTRICT_LONG_RESERVE_UNLESS_STOPPING :Long reserve (unless stopping)
STR_TRACE_RESTRICT_WAIT_AT_PBS :Wait at PBS signal STR_TRACE_RESTRICT_WAIT_AT_PBS :Wait at PBS signal
STR_TRACE_RESTRICT_WAIT_AT_PBS_CANCEL :Cancel wait at PBS signal STR_TRACE_RESTRICT_WAIT_AT_PBS_CANCEL :Cancel wait at PBS signal
STR_TRACE_RESTRICT_PBS_RES_END_WAIT :Wait at start PBS signal for reservation ending here STR_TRACE_RESTRICT_PBS_RES_END_WAIT :Wait at start PBS signal for reservation ending here

View File

@@ -76,7 +76,7 @@ static uint32 saveSTC(const SlxiSubChunkInfo *info, bool dry_run);
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_VERSION_LABEL, XSCF_IGNORABLE_ALL, 1, 1, "version_label", saveVL, loadVL, nullptr }, { XSLFI_VERSION_LABEL, XSCF_IGNORABLE_ALL, 1, 1, "version_label", saveVL, loadVL, nullptr },
{ XSLFI_UPSTREAM_VERSION, XSCF_NULL, 1, 1, "upstream_version", saveUV, loadUV, nullptr }, { XSLFI_UPSTREAM_VERSION, XSCF_NULL, 1, 1, "upstream_version", saveUV, loadUV, nullptr },
{ XSLFI_TRACE_RESTRICT, XSCF_NULL, 15, 15, "tracerestrict", nullptr, nullptr, "TRRM,TRRP,TRRS" }, { XSLFI_TRACE_RESTRICT, XSCF_NULL, 16, 16, "tracerestrict", nullptr, nullptr, "TRRM,TRRP,TRRS" },
{ XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 4, 4, "tracerestrict_order_cond", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 4, 4, "tracerestrict_order_cond", nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_STATUSCND, XSCF_NULL, 2, 2, "tracerestrict_status_cond", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_STATUSCND, XSCF_NULL, 2, 2, "tracerestrict_status_cond", nullptr, nullptr, nullptr },

View File

@@ -687,6 +687,12 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
out.flags &= ~TRPRF_LONG_RESERVE; out.flags &= ~TRPRF_LONG_RESERVE;
break; break;
case TRLRVF_LONG_RESERVE_UNLESS_STOPPING:
if (!(input.input_flags & TRPIF_PASSED_STOP)) {
out.flags |= TRPRF_LONG_RESERVE;
}
break;
default: default:
NOT_REACHED(); NOT_REACHED();
break; break;

View File

@@ -275,6 +275,7 @@ enum TraceRestrictTargetDirectionCondAuxField {
enum TraceRestrictLongReserveValueField { enum TraceRestrictLongReserveValueField {
TRLRVF_LONG_RESERVE = 0, ///< Long reserve TRLRVF_LONG_RESERVE = 0, ///< Long reserve
TRLRVF_CANCEL_LONG_RESERVE = 1, ///< Cancel long reserve TRLRVF_CANCEL_LONG_RESERVE = 1, ///< Cancel long reserve
TRLRVF_LONG_RESERVE_UNLESS_STOPPING = 2, ///< Long reserve (unless passed stop)
}; };
/** /**
@@ -474,6 +475,14 @@ enum TraceRestrictProgramInputSlotPermissions : uint8 {
}; };
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputSlotPermissions) DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputSlotPermissions)
/**
* Enumeration for TraceRestrictProgramInput::input_flags
*/
enum TraceRestrictProgramInputFlags : uint8 {
TRPIF_PASSED_STOP = 1 << 0, ///< Train has passed stop
};
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputFlags)
/** /**
* Execution input of a TraceRestrictProgram * Execution input of a TraceRestrictProgram
*/ */
@@ -485,10 +494,12 @@ struct TraceRestrictProgramInput {
PreviousSignalProc *previous_signal_callback; ///< Callback to retrieve tile and direction of previous signal, may be nullptr PreviousSignalProc *previous_signal_callback; ///< Callback to retrieve tile and direction of previous signal, may be nullptr
const void *previous_signal_ptr; ///< Opaque pointer suitable to be passed to previous_signal_callback const void *previous_signal_ptr; ///< Opaque pointer suitable to be passed to previous_signal_callback
TraceRestrictProgramInputSlotPermissions permitted_slot_operations; ///< Permitted slot operations TraceRestrictProgramInputSlotPermissions permitted_slot_operations; ///< Permitted slot operations
TraceRestrictProgramInputFlags input_flags; ///< Input flags
TraceRestrictProgramInput(TileIndex tile_, Trackdir trackdir_, PreviousSignalProc *previous_signal_callback_, const void *previous_signal_ptr_) TraceRestrictProgramInput(TileIndex tile_, Trackdir trackdir_, PreviousSignalProc *previous_signal_callback_, const void *previous_signal_ptr_)
: tile(tile_), trackdir(trackdir_), previous_signal_callback(previous_signal_callback_), previous_signal_ptr(previous_signal_ptr_), : tile(tile_), trackdir(trackdir_), previous_signal_callback(previous_signal_callback_), previous_signal_ptr(previous_signal_ptr_),
permitted_slot_operations(static_cast<TraceRestrictProgramInputSlotPermissions>(0)) { } permitted_slot_operations(static_cast<TraceRestrictProgramInputSlotPermissions>(0)),
input_flags(static_cast<TraceRestrictProgramInputFlags>(0)) { }
}; };
/** /**

View File

@@ -242,11 +242,13 @@ static const TraceRestrictDropDownListSet _reserve_through_value = {
static const StringID _long_reserve_value_str[] = { static const StringID _long_reserve_value_str[] = {
STR_TRACE_RESTRICT_LONG_RESERVE, STR_TRACE_RESTRICT_LONG_RESERVE,
STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL, STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL,
STR_TRACE_RESTRICT_LONG_RESERVE_UNLESS_STOPPING,
INVALID_STRING_ID INVALID_STRING_ID
}; };
static const uint _long_reserve_value_val[] = { static const uint _long_reserve_value_val[] = {
0, 0,
1, 1,
2,
}; };
/** value drop down list for long reserve types strings and values */ /** value drop down list for long reserve types strings and values */
@@ -1554,6 +1556,10 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
instruction_string = STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL; instruction_string = STR_TRACE_RESTRICT_LONG_RESERVE_CANCEL;
break; break;
case TRLRVF_LONG_RESERVE_UNLESS_STOPPING:
instruction_string = STR_TRACE_RESTRICT_LONG_RESERVE_UNLESS_STOPPING;
break;
default: default:
NOT_REACHED(); NOT_REACHED();
break; break;
@@ -2061,9 +2067,12 @@ public:
this->ShowDropDownListWithValue(&_reserve_through_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0); this->ShowDropDownListWithValue(&_reserve_through_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0);
break; break;
case TRVT_LONG_RESERVE: case TRVT_LONG_RESERVE: {
this->ShowDropDownListWithValue(&_long_reserve_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0); uint hidden = 0;
if (_settings_game.vehicle.train_braking_model != TBM_REALISTIC) hidden |= 4;
this->ShowDropDownListWithValue(&_long_reserve_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, hidden);
break; break;
}
case TRVT_WAIT_AT_PBS: case TRVT_WAIT_AT_PBS:
this->ShowDropDownListWithValue(&_wait_at_pbs_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0); this->ShowDropDownListWithValue(&_wait_at_pbs_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0);

View File

@@ -4179,7 +4179,7 @@ static bool LookaheadWithinCurrentTunnelBridge(const Train *t)
return t->lookahead->current_position >= t->lookahead->reservation_end_position - ((int)TILE_SIZE * t->lookahead->tunnel_bridge_reserved_tiles) && !HasBit(t->lookahead->flags, TRLF_TB_EXIT_FREE); return t->lookahead->current_position >= t->lookahead->reservation_end_position - ((int)TILE_SIZE * t->lookahead->tunnel_bridge_reserved_tiles) && !HasBit(t->lookahead->flags, TRLF_TB_EXIT_FREE);
} }
static bool HasLongReservePbsSignalOnTrackdir(Train* v, TileIndex tile, Trackdir trackdir, bool default_value) static bool HasLongReservePbsSignalOnTrackdir(Train* v, TileIndex tile, Trackdir trackdir, bool default_value, uint16 lookahead_state_flags)
{ {
if (HasPbsSignalOnTrackdir(tile, trackdir)) { if (HasPbsSignalOnTrackdir(tile, trackdir)) {
if (IsNoEntrySignal(tile, TrackdirToTrack(trackdir))) return false; if (IsNoEntrySignal(tile, TrackdirToTrack(trackdir))) return false;
@@ -4188,7 +4188,9 @@ static bool HasLongReservePbsSignalOnTrackdir(Train* v, TileIndex tile, Trackdir
if (prog && prog->actions_used_flags & TRPAUF_LONG_RESERVE) { if (prog && prog->actions_used_flags & TRPAUF_LONG_RESERVE) {
TraceRestrictProgramResult out; TraceRestrictProgramResult out;
if (default_value) out.flags |= TRPRF_LONG_RESERVE; if (default_value) out.flags |= TRPRF_LONG_RESERVE;
prog->Execute(v, TraceRestrictProgramInput(tile, trackdir, &VehiclePosTraceRestrictPreviousSignalCallback, nullptr), out); TraceRestrictProgramInput input(tile, trackdir, &VehiclePosTraceRestrictPreviousSignalCallback, nullptr);
if (HasBit(lookahead_state_flags, CTTLASF_STOP_FOUND)) input.input_flags |= TRPIF_PASSED_STOP;
prog->Execute(v, input, out);
return (out.flags & TRPRF_LONG_RESERVE); return (out.flags & TRPRF_LONG_RESERVE);
} }
} }
@@ -4249,6 +4251,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
TraceRestrictProgramResult out; TraceRestrictProgramResult out;
if (long_reserve) out.flags |= TRPRF_LONG_RESERVE; if (long_reserve) out.flags |= TRPRF_LONG_RESERVE;
TraceRestrictProgramInput input(exit_tile, exit_td, nullptr, nullptr); TraceRestrictProgramInput input(exit_tile, exit_td, nullptr, nullptr);
if (HasBit(lookahead_state.flags, CTTLASF_STOP_FOUND)) input.input_flags |= TRPIF_PASSED_STOP;
input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_ACQUIRE_ON_RES; input.permitted_slot_operations = TRPISP_ACQUIRE | TRPISP_ACQUIRE_ON_RES;
prog->Execute(v, input, out); prog->Execute(v, input, out);
if (out.flags & TRPRF_WAIT_AT_PBS) { if (out.flags & TRPRF_WAIT_AT_PBS) {
@@ -4292,7 +4295,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
} }
CFollowTrackRail ft(v); CFollowTrackRail ft(v);
if (ft.Follow(tile, td) && HasLongReservePbsSignalOnTrackdir(v, ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits), !long_enough)) { if (ft.Follow(tile, td) && HasLongReservePbsSignalOnTrackdir(v, ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits), !long_enough, lookahead_state.flags)) {
// We reserved up to a LR signal, reserve past it as well. recursion // We reserved up to a LR signal, reserve past it as well. recursion
ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), nullptr, lookahead_state); ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, TrackdirBitsToTrackBits(ft.m_new_td_bits), CTTF_NO_LOOKAHEAD_VALIDATE | (force_res ? CTTF_FORCE_RES : CTTF_NONE), nullptr, lookahead_state);
} }
@@ -4412,7 +4415,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
CFollowTrackRail ft(v); CFollowTrackRail ft(v);
if (ft.Follow(res_dest.tile, res_dest.trackdir)) { if (ft.Follow(res_dest.tile, res_dest.trackdir)) {
Trackdir new_td = FindFirstTrackdir(ft.m_new_td_bits); Trackdir new_td = FindFirstTrackdir(ft.m_new_td_bits);
long_reserve = HasLongReservePbsSignalOnTrackdir(v, ft.m_new_tile, new_td, _settings_game.vehicle.train_braking_model == TBM_REALISTIC); long_reserve = HasLongReservePbsSignalOnTrackdir(v, ft.m_new_tile, new_td, _settings_game.vehicle.train_braking_model == TBM_REALISTIC, lookahead_state.flags);
} }
} }
@@ -4898,7 +4901,7 @@ static TrainMovedChangeSignalEnum TrainMovedChangeSignal(Train* v, TileIndex til
/* A PBS block with a non-PBS signal facing us? */ /* A PBS block with a non-PBS signal facing us? */
if (!IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return CHANGED_NORMAL_TO_PBS_BLOCK; if (!IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) return CHANGED_NORMAL_TO_PBS_BLOCK;
if (front && HasLongReservePbsSignalOnTrackdir(v, tile, trackdir, _settings_game.vehicle.train_braking_model == TBM_REALISTIC)) return CHANGED_LR_PBS; if (front && HasLongReservePbsSignalOnTrackdir(v, tile, trackdir, _settings_game.vehicle.train_braking_model == TBM_REALISTIC, 0)) return CHANGED_LR_PBS;
} }
} }
if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) { if (IsTileType(tile, MP_TUNNELBRIDGE) && IsTunnelBridgeSignalSimulationExit(tile) && GetTunnelBridgeDirection(tile) == ReverseDiagDir(dir)) {