From d2594ece79e8bdc0c9b30ac01b2e7c9ce1a6f5c8 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 29 Aug 2020 13:32:53 +0100 Subject: [PATCH] Add routing restrictions action to control news reports about stuck trains --- src/lang/english.txt | 5 ++++ src/saveload/extended_ver_sl.cpp | 1 + src/saveload/extended_ver_sl.h | 1 + src/tracerestrict.cpp | 21 ++++++++++++++ src/tracerestrict.h | 14 ++++++++++ src/tracerestrict_gui.cpp | 48 +++++++++++++++++++++++++++++++- src/train_cmd.cpp | 5 +++- 7 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 0baff9a6dd..d7f6637b82 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2798,6 +2798,7 @@ STR_TRACE_RESTRICT_UNDEFINED_COMPANY :Undefined compa STR_TRACE_RESTRICT_SLOT_OP :Slot operation STR_TRACE_RESTRICT_REVERSE :Reverse STR_TRACE_RESTRICT_SPEED_RESTRICTION :Speed restriction +STR_TRACE_RESTRICT_NEWS_CONTROL :News control STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT :Acquire or wait STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE :Try to acquire STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT :Release (front) @@ -2830,6 +2831,10 @@ STR_TRACE_RESTRICT_REVERSE_SIG :Reverse behind STR_TRACE_RESTRICT_REVERSE_SIG_CANCEL :Cancel reverse behind signal STR_TRACE_RESTRICT_SET_SPEED_RESTRICTION :Restrict train speed to: {VELOCITY} STR_TRACE_RESTRICT_REMOVE_SPEED_RESTRICTION :Remove train speed restriction +STR_TRACE_RESTRICT_TRAIN_NOT_STUCK :Train is not stuck, do not show news reports about waiting at this PBS signal +STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_CANCEL :Cancel train is not stuck, do not show news reports about waiting at this PBS signal +STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_SHORT :Train is not stuck... +STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_CANCEL_SHORT :Cancel train is not stuck... STR_TRACE_RESTRICT_VALUE_CAPTION :{WHITE}Value STR_TRACE_RESTRICT_CAPTION :{WHITE}Routefinding restriction STR_TRACE_RESTRICT_CAPTION_SHARED :{WHITE}Routefinding restriction - shared by {COMMA} signals diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index a174bd7abe..60e2709a77 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -70,6 +70,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 3, 3, "tracerestrict_order_cond", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_STATUSCND,XSCF_NULL, 1, 1, "tracerestrict_status_cond", nullptr, nullptr, nullptr }, { XSLFI_TRACE_RESTRICT_REVERSE, XSCF_NULL, 1, 1, "tracerestrict_reverse", nullptr, nullptr, nullptr }, + { XSLFI_TRACE_RESTRICT_NEWSCTRL,XSCF_NULL, 1, 1, "tracerestrict_newsctrl", nullptr, nullptr, nullptr }, { XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", nullptr, nullptr, "SPRG" }, { XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", nullptr, nullptr, nullptr }, { XSLFI_SAFER_CROSSINGS, XSCF_NULL, 1, 1, "safer_crossings", nullptr, nullptr, nullptr }, diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index fcfd047db4..5b732ac05e 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -27,6 +27,7 @@ enum SlXvFeatureIndex { XSLFI_TRACE_RESTRICT_ORDRCND, ///< Trace restrict: slot conditional order XSLFI_TRACE_RESTRICT_STATUSCND, ///< Trace restrict: train status condition XSLFI_TRACE_RESTRICT_REVERSE, ///< Trace restrict: reverse + XSLFI_TRACE_RESTRICT_NEWSCTRL, ///< Trace restrict: news control XSLFI_PROG_SIGS, ///< programmable pre-signals patch XSLFI_ADJACENT_CROSSINGS, ///< Adjacent level crossings closure patch XSLFI_SAFER_CROSSINGS, ///< Safer level crossings diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index f7786e21cc..41729e0a1c 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -641,6 +641,22 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp break; } + case TRIT_NEWS_CONTROL: + switch (static_cast(GetTraceRestrictValue(item))) { + case TRRVF_TRAIN_NOT_STUCK: + out.flags |= TRPRF_TRAIN_NOT_STUCK; + break; + + case TRRVF_CANCEL_TRAIN_NOT_STUCK: + out.flags &= ~TRPRF_TRAIN_NOT_STUCK; + break; + + default: + NOT_REACHED(); + break; + } + break; + default: NOT_REACHED(); } @@ -814,6 +830,10 @@ CommandCost TraceRestrictProgram::Validate(const std::vector actions_used_flags |= TRPAUF_SPEED_RESTRICTION; break; + case TRIT_NEWS_CONTROL: + actions_used_flags |= TRPAUF_TRAIN_NOT_STUCK; + break; + default: return_cmd_error(STR_TRACE_RESTRICT_ERROR_VALIDATE_UNKNOWN_INSTRUCTION); } @@ -876,6 +896,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp case TRVT_TRAIN_STATUS: case TRVT_REVERSE: case TRVT_PERCENT: + case TRVT_NEWS_CONTROL: SetTraceRestrictValue(item, 0); if (!IsTraceRestrictTypeAuxSubtype(GetTraceRestrictType(item))) { SetTraceRestrictAuxField(item, 0); diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 8a0e02e2bf..68835ccfe4 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -140,6 +140,7 @@ enum TraceRestrictItemType { TRIT_COND_END = 48, ///< End (exclusive) of conditional item types, note that this has the same value as TRIT_REVERSE TRIT_REVERSE = 48, ///< Reverse behind signal TRIT_SPEED_RESTRICTION = 49, ///< Speed restriction + TRIT_NEWS_CONTROL = 50, ///< News control /* space up to 63 */ }; @@ -245,6 +246,14 @@ enum TraceRestrictReverseValueField { TRRVF_CANCEL_REVERSE = 1, ///< Cancel reverse }; +/** + * TraceRestrictItem value field, for TRIT_NEWS_CONTROL + */ +enum TraceRestrictNewsControlField { + TRRVF_TRAIN_NOT_STUCK = 0, ///< Train is not stuck + TRRVF_CANCEL_TRAIN_NOT_STUCK = 1, ///< Cancel train is not stuck +}; + /** * TraceRestrictItem value field, for TRIT_COND_TRAIN_STATUS */ @@ -307,6 +316,7 @@ enum TraceRestrictProgramResultFlags { TRPRF_PBS_RES_END_WAIT = 1 << 4, ///< PBS reservations ending at this signal wait is set TRPRF_REVERSE = 1 << 5, ///< Reverse behind signal TRPRF_SPEED_RETRICTION_SET = 1 << 6, ///< Speed restriction field set + TRPRF_TRAIN_NOT_STUCK = 1 << 7, ///< Train is not stuck }; DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags) @@ -325,6 +335,7 @@ enum TraceRestrictProgramActionsUsedFlags { TRPAUF_PBS_RES_END_SLOT = 1 << 8, ///< PBS reservations ending at this signal slot action is present TRPAUF_REVERSE = 1 << 9, ///< Reverse behind signal TRPAUF_SPEED_RESTRICTION = 1 << 10, ///< Speed restriction + TRPAUF_TRAIN_NOT_STUCK = 1 << 11, ///< Train is not stuck }; DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags) @@ -559,6 +570,7 @@ enum TraceRestrictValueType { TRVT_OWNER = 40,///< takes a CompanyID TRVT_TRAIN_STATUS = 41,///< takes a TraceRestrictTrainStatusValueField TRVT_REVERSE = 42,///< takes a TraceRestrictReverseValueField + TRVT_NEWS_CONTROL = 43,///< takes a TraceRestrictNewsControlField }; /** @@ -706,6 +718,8 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR out.value_type = TRVT_REVERSE; } else if (GetTraceRestrictType(item) == TRIT_SPEED_RESTRICTION) { out.value_type = TRVT_SPEED; + } else if (GetTraceRestrictType(item) == TRIT_NEWS_CONTROL) { + out.value_type = TRVT_NEWS_CONTROL; } else { out.value_type = TRVT_NONE; } diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index 993ec967ab..9d9105f2b3 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -152,6 +152,7 @@ static const StringID _program_insert_str[] = { STR_TRACE_RESTRICT_SLOT_OP, STR_TRACE_RESTRICT_REVERSE, STR_TRACE_RESTRICT_SPEED_RESTRICTION, + STR_TRACE_RESTRICT_NEWS_CONTROL, INVALID_STRING_ID }; static const uint32 _program_insert_else_hide_mask = 8; ///< disable bitmask for else @@ -174,6 +175,7 @@ static const uint _program_insert_val[] = { TRIT_SLOT, // slot operation TRIT_REVERSE, // reverse TRIT_SPEED_RESTRICTION, // speed restriction + TRIT_NEWS_CONTROL, // news control }; /** insert drop down list strings and values */ @@ -311,11 +313,26 @@ static const uint _reverse_value_val[] = { TRRVF_CANCEL_REVERSE, }; -/** value drop down list for wait at PBS types strings and values */ +/** value drop down list for reverse types strings and values */ static const TraceRestrictDropDownListSet _reverse_value = { _reverse_value_str, _reverse_value_val, }; +static const StringID _news_control_value_str[] = { + STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_SHORT, + STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_CANCEL_SHORT, + INVALID_STRING_ID +}; +static const uint _news_control_value_val[] = { + TRRVF_REVERSE, + TRRVF_CANCEL_REVERSE, +}; + +/** value drop down list for news control types strings and values */ +static const TraceRestrictDropDownListSet _news_control_value = { + _news_control_value_str, _news_control_value_val, +}; + /** * Get index of @p value in @p list_set * if @p value is not present, assert if @p missing_ok is false, otherwise return -1 @@ -374,6 +391,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG STR_TRACE_RESTRICT_SLOT_OP, STR_TRACE_RESTRICT_REVERSE, STR_TRACE_RESTRICT_SPEED_RESTRICTION, + STR_TRACE_RESTRICT_NEWS_CONTROL, INVALID_STRING_ID, }; static const uint val_action[] = { @@ -385,6 +403,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG TRIT_SLOT, TRIT_REVERSE, TRIT_SPEED_RESTRICTION, + TRIT_NEWS_CONTROL, }; static const TraceRestrictDropDownListSet set_action = { str_action, val_action, @@ -1242,6 +1261,22 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric } break; + case TRIT_NEWS_CONTROL: + switch (static_cast(GetTraceRestrictValue(item))) { + case TRRVF_TRAIN_NOT_STUCK: + instruction_string = STR_TRACE_RESTRICT_TRAIN_NOT_STUCK; + break; + + case TRRVF_CANCEL_TRAIN_NOT_STUCK: + instruction_string = STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_CANCEL; + break; + + default: + NOT_REACHED(); + break; + } + break; + default: NOT_REACHED(); break; @@ -1540,6 +1575,10 @@ public: this->ShowDropDownListWithValue(&_reverse_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0, 0); break; + case TRVT_NEWS_CONTROL: + this->ShowDropDownListWithValue(&_news_control_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0, 0); + break; + default: break; } @@ -2530,6 +2569,13 @@ private: GetDropDownStringByValue(&_reverse_value, GetTraceRestrictValue(item)); break; + case TRVT_NEWS_CONTROL: + right_sel->SetDisplayedPlane(DPR_VALUE_DROPDOWN); + this->EnableWidget(TR_WIDGET_VALUE_DROPDOWN); + this->GetWidget(TR_WIDGET_VALUE_DROPDOWN)->widget_data = + GetDropDownStringByValue(&_news_control_value, GetTraceRestrictValue(item)); + break; + default: break; } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 5ee850fd7d..1a51a16e84 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3126,11 +3126,14 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, if (track != INVALID_TRACK && HasPbsSignalOnTrackdir(tile, TrackEnterdirToTrackdir(track, enterdir))) { if (IsRestrictedSignal(tile) && v->force_proceed != TFP_SIGNAL) { const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, track); - if (prog && prog->actions_used_flags & (TRPAUF_WAIT_AT_PBS | TRPAUF_SLOT_ACQUIRE)) { + if (prog && prog->actions_used_flags & (TRPAUF_WAIT_AT_PBS | TRPAUF_SLOT_ACQUIRE | TRPAUF_TRAIN_NOT_STUCK)) { TraceRestrictProgramResult out; TraceRestrictProgramInput input(tile, TrackEnterdirToTrackdir(track, enterdir), nullptr, nullptr); input.permitted_slot_operations = TRPISP_ACQUIRE; prog->Execute(v, input, out); + if (out.flags & TRPRF_TRAIN_NOT_STUCK) { + v->wait_counter = 0; + } if (out.flags & TRPRF_WAIT_AT_PBS) { if (mark_stuck) MarkTrainAsStuck(v, true); return track;