From 3e50336079ab7604857ba44052e56e631d315ace Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 21 Aug 2018 19:22:35 +0100 Subject: [PATCH] Add trace restrict train status conditional --- src/lang/english.txt | 15 +++++++ src/saveload/extended_ver_sl.cpp | 1 + src/saveload/extended_ver_sl.h | 1 + src/tracerestrict.cpp | 66 +++++++++++++++++++++++++++++ src/tracerestrict.h | 24 +++++++++++ src/tracerestrict_gui.cpp | 71 +++++++++++++++++++++++++++++++- 6 files changed, 177 insertions(+), 1 deletion(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index 1141b1c196..c8a1df9e74 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2588,6 +2588,8 @@ STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_MORE_THAN :> STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_MORE_EQUALS :>= STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_EQUALS :can carry STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_CARGO_NOT_EQUALS :can't carry +STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_HAS_STATUS :has +STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_DOESNT_HAVE_STATUS :doesn't have STR_TRACE_RESTRICT_CONDITIONAL_IF :If STR_TRACE_RESTRICT_CONDITIONAL_ELIF :Else if STR_TRACE_RESTRICT_CONDITIONAL_ORIF :Or if @@ -2614,6 +2616,7 @@ STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE :max T.E. STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER_WEIGHT_RATIO :power / weight ratio STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE_WEIGHT_RATIO :max T.E. / weight ratio STR_TRACE_RESTRICT_VARIABLE_TRAIN_OWNER :train owner +STR_TRACE_RESTRICT_VARIABLE_TRAIN_STATUS :train status STR_TRACE_RESTRICT_VARIABLE_UNDEFINED :undefined STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED :{RED}undefined STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_INTEGER :{STRING} {STRING} {STRING} {COMMA} then @@ -2637,6 +2640,7 @@ STR_TRACE_RESTRICT_CONDITIONAL_SLOT :{STRING} train STR_TRACE_RESTRICT_CONDITIONAL_SLOT_STR :{STRING} train {STRING} in slot: {STRING} {BLACK}{STRING}then STR_TRACE_RESTRICT_CONDITIONAL_SLOT_OCCUPANCY :{STRING} {STRING} of slot: {TRSLOT} {STRING} {COMMA} then STR_TRACE_RESTRICT_CONDITIONAL_SLOT_OCCUPANCY_STR :{STRING} {STRING} of slot: {STRING} {BLACK}{STRING} {STRING} {COMMA} then +STR_TRACE_RESTRICT_CONDITIONAL_TRAIN_STATUS :{STRING} train {STRING} status: {STRING} then STR_TRACE_RESTRICT_CONDITIONAL_UNDEFINED :{STRING} {STRING} {STRING} {RED}undefined {BLACK}{STRING}then STR_TRACE_RESTRICT_CONDITIONAL_COMPARE_UNDEFINED :{STRING} {RED}undefined {BLACK}{STRING}then STR_TRACE_RESTRICT_PF_PENALTY_ITEM :Add pathfinder penalty: {COMMA} @@ -2688,6 +2692,17 @@ STR_TRACE_RESTRICT_SLOT_PBS_RES_END_RELEASE_ITEM :PBS reservation STR_TRACE_RESTRICT_SLOT_NAME :{TRSLOT} STR_TRACE_RESTRICT_SLOT_LIST_HEADER :{BLACK}Slot{CONSUME_ARG}{P "" s}: {LTBLUE} STR_TRACE_RESTRICT_SLOT_LIST_SEPARATOR :{BLACK}, {LTBLUE} +STR_TRACE_RESTRICT_TRAIN_STATUS_EMPTY :empty +STR_TRACE_RESTRICT_TRAIN_STATUS_FULL :full +STR_TRACE_RESTRICT_TRAIN_STATUS_BROKEN_DOWN :broken down +STR_TRACE_RESTRICT_TRAIN_STATUS_NEEDS_REPAIR :needs repair +STR_TRACE_RESTRICT_TRAIN_STATUS_REVERSING :reversing +STR_TRACE_RESTRICT_TRAIN_STATUS_HEADING_TO_STATION_WAYPOINT :heading to station/waypoint +STR_TRACE_RESTRICT_TRAIN_STATUS_HEADING_TO_DEPOT :heading to depot +STR_TRACE_RESTRICT_TRAIN_STATUS_LOADING :loading +STR_TRACE_RESTRICT_TRAIN_STATUS_WAITING :waiting +STR_TRACE_RESTRICT_TRAIN_STATUS_LOST :lost +STR_TRACE_RESTRICT_TRAIN_STATUS_REQUIRES_SERVICE :requires service 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 49dcd07a9f..d29cc32c2c 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -50,6 +50,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_TRACE_RESTRICT, XSCF_NULL, 9, 9, "tracerestrict", NULL, NULL, "TRRM,TRRP,TRRS" }, { XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", NULL, NULL, NULL }, { XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 1, 1, "tracerestrict_order_cond", NULL, NULL, NULL }, + { XSLFI_TRACE_RESTRICT_STATUSCND,XSCF_NULL, 1, 1, "tracerestrict_status_cond", NULL, NULL, NULL }, { XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", NULL, NULL, "SPRG" }, { XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", NULL, NULL, NULL }, { XSLFI_SAFER_CROSSINGS, XSCF_NULL, 1, 1, "safer_crossings", NULL, NULL, NULL }, diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index dd550ac700..0c10a9859e 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -24,6 +24,7 @@ enum SlXvFeatureIndex { XSLFI_TRACE_RESTRICT, ///< Trace restrict XSLFI_TRACE_RESTRICT_OWNER, ///< Trace restrict: train owner test XSLFI_TRACE_RESTRICT_ORDRCND, ///< Trace restrict: slot conditional order + XSLFI_TRACE_RESTRICT_STATUSCND, ///< Trace restrict: train status condition XSLFI_PROG_SIGS, ///< programmable 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 88672171aa..9f1b895dd5 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -428,6 +428,70 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp break; } + + case TRIT_COND_TRAIN_STATUS: { + bool has_status = false; + switch (static_cast(GetTraceRestrictValue(item))) { + case TRTSVF_EMPTY: + has_status = true; + for (const Vehicle *v_iter = v; v_iter != NULL; v_iter = v_iter->Next()) { + if (v_iter->cargo.StoredCount() > 0) { + has_status = false; + break; + } + } + break; + + case TRTSVF_FULL: + has_status = true; + for (const Vehicle *v_iter = v; v_iter != NULL; v_iter = v_iter->Next()) { + if (v_iter->cargo.StoredCount() < v_iter->cargo_cap) { + has_status = false; + break; + } + } + break; + + case TRTSVF_BROKEN_DOWN: + has_status = v->flags & VRF_IS_BROKEN; + break; + + case TRTSVF_NEEDS_REPAIR: + has_status = v->critical_breakdown_count > 0; + break; + + case TRTSVF_REVERSING: + has_status = v->reverse_distance > 0 || HasBit(v->flags, VRF_REVERSING); + break; + + case TRTSVF_HEADING_TO_STATION_WAYPOINT: + has_status = v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_WAYPOINT); + break; + + case TRTSVF_HEADING_TO_DEPOT: + has_status = v->current_order.IsType(OT_GOTO_DEPOT); + break; + + case TRTSVF_LOADING: + has_status = v->current_order.IsType(OT_LOADING) || v->current_order.IsType(OT_LOADING_ADVANCE); + break; + + case TRTSVF_WAITING: + has_status = v->current_order.IsType(OT_WAITING); + break; + + case TRTSVF_LOST: + has_status = HasBit(v->vehicle_flags, VF_PATHFINDER_LOST); + break; + + case TRTSVF_REQUIRES_SERVICE: + has_status = v->NeedsServicing(); + break; + } + result = TestBinaryConditionCommon(item, has_status); + break; + } + default: NOT_REACHED(); } @@ -640,6 +704,7 @@ CommandCost TraceRestrictProgram::Validate(const std::vector case TRIT_COND_PHYS_PROP: case TRIT_COND_PHYS_RATIO: case TRIT_COND_TRAIN_OWNER: + case TRIT_COND_TRAIN_STATUS: break; default: @@ -770,6 +835,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp case TRVT_POWER_WEIGHT_RATIO: case TRVT_FORCE_WEIGHT_RATIO: case TRVT_WAIT_AT_PBS: + case TRVT_TRAIN_STATUS: SetTraceRestrictValue(item, 0); if (!IsTraceRestrictTypeAuxSubtype(GetTraceRestrictType(item))) { SetTraceRestrictAuxField(item, 0); diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 42ace7a086..e3fb9b19bc 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -137,6 +137,7 @@ enum TraceRestrictItemType { TRIT_COND_TRAIN_IN_SLOT = 21, ///< Test train slot membership TRIT_COND_SLOT_OCCUPANCY = 22, ///< Test train slot occupancy state TRIT_COND_TRAIN_OWNER = 24, ///< Test train owner + TRIT_COND_TRAIN_STATUS = 25, ///< Test train status /* space up to 31 */ }; @@ -233,6 +234,23 @@ enum TraceRestrictWaitAtPbsValueField { TRWAPVF_CANCEL_PBS_RES_END_WAIT = 3, ///< Cancel PBS reservations ending at this signal wait }; +/** + * TraceRestrictItem value field, for TRIT_COND_TRAIN_STATUS + */ +enum TraceRestrictTrainStatusValueField { + TRTSVF_EMPTY = 0, ///< Train is empty + TRTSVF_FULL = 1, ///< Train is full + TRTSVF_BROKEN_DOWN = 2, ///< Train is broken down + TRTSVF_NEEDS_REPAIR = 3, ///< Train needs repair + TRTSVF_REVERSING = 4, ///< Train is reversing + TRTSVF_HEADING_TO_STATION_WAYPOINT = 5, ///< Train is en-route to a station or waypoint + TRTSVF_HEADING_TO_DEPOT = 6, ///< Train is en-route to a depot + TRTSVF_LOADING = 7, ///< Train is loading + TRTSVF_WAITING = 8, ///< Train is waiting + TRTSVF_LOST = 9, ///< Train is lost + TRTSVF_REQUIRES_SERVICE = 10, ///< Train requires service +}; + /** * TraceRestrictItem repurposed condition operator field, for slot operation type actions */ @@ -522,6 +540,7 @@ enum TraceRestrictValueType { TRVT_SLOT_INDEX = 19,///< takes a TraceRestrictSlotID TRVT_SLOT_INDEX_INT = 20,///< takes a TraceRestrictSlotID, and an integer in the next item slot TRVT_OWNER = 40,///< takes a CompanyID + TRVT_TRAIN_STATUS = 41,///< takes a TraceRestrictTrainStatusValueField }; /** @@ -638,6 +657,11 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR out.cond_type = TRCOT_BINARY; break; + case TRIT_COND_TRAIN_STATUS: + out.value_type = TRVT_TRAIN_STATUS; + out.cond_type = TRCOT_BINARY; + break; + default: NOT_REACHED(); break; diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index 9b721220fb..cb8cc20aba 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -264,6 +264,39 @@ static const TraceRestrictDropDownListSet _direction_value = { _direction_value_str, _direction_value_val, }; +static const StringID _train_status_value_str[] = { + STR_TRACE_RESTRICT_TRAIN_STATUS_EMPTY, + STR_TRACE_RESTRICT_TRAIN_STATUS_FULL, + STR_TRACE_RESTRICT_TRAIN_STATUS_BROKEN_DOWN, + STR_TRACE_RESTRICT_TRAIN_STATUS_NEEDS_REPAIR, + STR_TRACE_RESTRICT_TRAIN_STATUS_REVERSING, + STR_TRACE_RESTRICT_TRAIN_STATUS_HEADING_TO_STATION_WAYPOINT, + STR_TRACE_RESTRICT_TRAIN_STATUS_HEADING_TO_DEPOT, + STR_TRACE_RESTRICT_TRAIN_STATUS_LOADING, + STR_TRACE_RESTRICT_TRAIN_STATUS_WAITING, + STR_TRACE_RESTRICT_TRAIN_STATUS_LOST, + STR_TRACE_RESTRICT_TRAIN_STATUS_REQUIRES_SERVICE, + INVALID_STRING_ID +}; +static const uint _train_status_value_val[] = { + TRTSVF_EMPTY, + TRTSVF_FULL, + TRTSVF_BROKEN_DOWN, + TRTSVF_NEEDS_REPAIR, + TRTSVF_REVERSING, + TRTSVF_HEADING_TO_STATION_WAYPOINT, + TRTSVF_HEADING_TO_DEPOT, + TRTSVF_LOADING, + TRTSVF_WAITING, + TRTSVF_LOST, + TRTSVF_REQUIRES_SERVICE, +}; + +/** value drop down list for train status type strings and values */ +static const TraceRestrictDropDownListSet _train_status_value = { + _train_status_value_str, _train_status_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 @@ -345,6 +378,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL, STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP, STR_TRACE_RESTRICT_VARIABLE_TRAIN_OWNER, + STR_TRACE_RESTRICT_VARIABLE_TRAIN_STATUS, STR_TRACE_RESTRICT_VARIABLE_TRAIN_WEIGHT, STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER, STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE, @@ -367,6 +401,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG TRIT_COND_PBS_ENTRY_SIGNAL, TRIT_COND_TRAIN_GROUP, TRIT_COND_TRAIN_OWNER, + TRIT_COND_TRAIN_STATUS, TRIT_COND_PHYS_PROP | (TRPPCAF_WEIGHT << 16), TRIT_COND_PHYS_PROP | (TRPPCAF_POWER << 16), TRIT_COND_PHYS_PROP | (TRPPCAF_MAX_TE << 16), @@ -386,7 +421,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG if (_settings_client.gui.show_adv_tracerestrict_features) { *hide_mask = 0; } else { - *hide_mask = is_conditional ? 0x38000 : 0x30; + *hide_mask = is_conditional ? 0x70000 : 0x30; } } return is_conditional ? &set_cond : &set_action; @@ -505,6 +540,20 @@ static const TraceRestrictDropDownListSet _cargo_cond_ops = { _cargo_cond_ops_str, _cargo_cond_ops_val, }; +static const StringID _train_status_cond_ops_str[] = { + STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_HAS_STATUS, + STR_TRACE_RESTRICT_CONDITIONAL_COMPARATOR_DOESNT_HAVE_STATUS, + INVALID_STRING_ID, +}; +static const uint _train_status_cond_ops_val[] = { + TRCO_IS, + TRCO_ISNOT, +}; +/** cargo conditional operators dropdown list set */ +static const TraceRestrictDropDownListSet _train_status_cond_ops = { + _train_status_cond_ops_str, _train_status_cond_ops_val, +}; + static const StringID _slot_op_cond_ops_str[] = { STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT, STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE, @@ -587,6 +636,7 @@ static const TraceRestrictDropDownListSet *GetCondOpDropDownListSet(TraceRestric }; if (properties.value_type == TRVT_CARGO_ID) return &_cargo_cond_ops; + if (properties.value_type == TRVT_TRAIN_STATUS) return &_train_status_cond_ops; switch (properties.cond_type) { case TRCOT_NONE: @@ -1008,6 +1058,14 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric break; } + case TRVT_TRAIN_STATUS: + instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_TRAIN_STATUS; + assert(GetTraceRestrictCondFlags(item) <= TRCF_OR); + SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]); + SetDParam(1, GetDropDownStringByValue(&_train_status_cond_ops, GetTraceRestrictCondOp(item))); + SetDParam(2, GetDropDownStringByValue(&_train_status_value, GetTraceRestrictValue(item))); + break; + default: NOT_REACHED(); break; @@ -1420,6 +1478,10 @@ public: break; } + case TRVT_TRAIN_STATUS: + this->ShowDropDownListWithValue(&_train_status_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0, 0); + break; + default: break; } @@ -2395,6 +2457,13 @@ private: break; } + case TRVT_TRAIN_STATUS: + right_sel->SetDisplayedPlane(DPR_VALUE_DROPDOWN); + this->EnableWidget(TR_WIDGET_VALUE_DROPDOWN); + this->GetWidget(TR_WIDGET_VALUE_DROPDOWN)->widget_data = + GetDropDownStringByValue(&_train_status_value, GetTraceRestrictValue(item)); + break; + default: break; }