Tracerestrict: Add long reserve (unless stopping) mode
Requires realistic braking
This commit is contained in:
@@ -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
|
||||||
|
@@ -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 },
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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);
|
||||||
|
@@ -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)) {
|
||||||
|
Reference in New Issue
Block a user