From c44141bad6972b16f6aa1f97743f98f49ae24d48 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 10 Apr 2017 19:00:52 +0100 Subject: [PATCH] Add conditional to test slot occupancy state. Bump tracerestrict version. --- src/lang/english.txt | 8 ++- src/saveload/extended_ver_sl.cpp | 2 +- src/tracerestrict.cpp | 40 +++++++++-- src/tracerestrict.h | 23 +++++- src/tracerestrict_gui.cpp | 119 +++++++++++++++++++++++++++++-- 5 files changed, 178 insertions(+), 14 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index e2d27bbbda..505a6a163f 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2405,7 +2405,11 @@ STR_TRACE_RESTRICT_VARIABLE_ENTRY_DIRECTION :entry direction STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL :PBS entry signal STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG :entered signal of PBS block STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP :train group -STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT :slot +STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT :train in slot +STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY :slot occupancy +STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_REMAINING :slot occupancy remaining +STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_SHORT :occupancy +STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_REMAINING_SHORT :occupancy remaining STR_TRACE_RESTRICT_VARIABLE_TRAIN_WEIGHT :weight STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER :power STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE :max T.E. @@ -2431,6 +2435,8 @@ STR_TRACE_RESTRICT_CONDITIONAL_GROUP :{STRING} train STR_TRACE_RESTRICT_CONDITIONAL_GROUP_STR :{STRING} train {STRING} in group: {STRING} {BLACK}{STRING}then STR_TRACE_RESTRICT_CONDITIONAL_SLOT :{STRING} train {STRING} in slot: {TRSLOT} then 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_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} diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 62e6b4d767..3e8ac50914 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -45,7 +45,7 @@ std::vector _sl_xv_discardable_chunk_ids; ///< list of chunks static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { - { XSLFI_TRACE_RESTRICT, XSCF_NULL, 7, 7, "tracerestrict", NULL, NULL, "TRRM,TRRP,TRRS" }, + { XSLFI_TRACE_RESTRICT, XSCF_NULL, 8, 8, "tracerestrict", NULL, NULL, "TRRM,TRRP,TRRS" }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 3aa26935bc..d090dd6015 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -147,7 +147,7 @@ static void HandleCondition(std::vector &condstack, * Integer condition testing * Test value op condvalue */ -static bool TestCondition(uint16 value, TraceRestrictCondOp condop, uint16 condvalue) +static bool TestCondition(int value, TraceRestrictCondOp condop, int condvalue) { switch (condop) { case TRCO_IS: @@ -357,12 +357,33 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp break; } - case TRIT_COND_SLOT: { + case TRIT_COND_TRAIN_IN_SLOT: { const TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(GetTraceRestrictValue(item)); result = TestBinaryConditionCommon(item, slot != NULL && slot->IsOccupant(v->index)); break; } + case TRIT_COND_SLOT_OCCUPANCY: { + // TRIT_COND_SLOT_OCCUPANCY value type uses the next slot + i++; + uint32_t value = this->items[i]; + const TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(GetTraceRestrictValue(item)); + switch (static_cast(GetTraceRestrictAuxField(item))) { + case TRSOCAF_OCCUPANTS: + result = TestCondition(slot != NULL ? slot->occupants.size() : 0, condop, value); + break; + + case TRSOCAF_REMAINING: + result = TestCondition(slot != NULL ? slot->max_occupancy - slot->occupants.size() : 0, condop, value); + break; + + default: + NOT_REACHED(); + break; + } + break; + } + case TRIT_COND_PHYS_PROP: { switch (static_cast(GetTraceRestrictAuxField(item))) { case TRPPCAF_WEIGHT: @@ -576,7 +597,8 @@ CommandCost TraceRestrictProgram::Validate(const std::vector case TRIT_COND_ENTRY_DIRECTION: case TRIT_COND_PBS_ENTRY_SIGNAL: case TRIT_COND_TRAIN_GROUP: - case TRIT_COND_SLOT: + case TRIT_COND_TRAIN_IN_SLOT: + case TRIT_COND_SLOT_OCCUPANCY: case TRIT_COND_PHYS_PROP: case TRIT_COND_PHYS_RATIO: break; @@ -723,6 +745,10 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp SetTraceRestrictAuxField(item, 0); break; + case TRVT_SLOT_INDEX_INT: + SetTraceRestrictValue(item, INVALID_TRACE_RESTRICT_SLOT_ID); + break; + default: NOT_REACHED(); break; @@ -926,6 +952,9 @@ static uint32 GetDualInstructionInitialValue(TraceRestrictItem item) case TRIT_COND_PBS_ENTRY_SIGNAL: return INVALID_TILE; + case TRIT_COND_SLOT_OCCUPANCY: + return 0; + default: NOT_REACHED(); } @@ -1500,9 +1529,12 @@ void TraceRestrictRemoveSlotID(TraceRestrictSlotID index) FOR_ALL_TRACE_RESTRICT_PROGRAMS(prog) { for (size_t i = 0; i < prog->items.size(); i++) { TraceRestrictItem &item = prog->items[i]; // note this is a reference, - if ((GetTraceRestrictType(item) == TRIT_SLOT || GetTraceRestrictType(item) == TRIT_COND_SLOT) && GetTraceRestrictValue(item) == index) { + if ((GetTraceRestrictType(item) == TRIT_SLOT || GetTraceRestrictType(item) == TRIT_COND_TRAIN_IN_SLOT) && GetTraceRestrictValue(item) == index) { SetTraceRestrictValueDefault(item, TRVT_SLOT_INDEX); // this updates the instruction in-place } + if ((GetTraceRestrictType(item) == TRIT_COND_SLOT_OCCUPANCY) && GetTraceRestrictValue(item) == index) { + SetTraceRestrictValueDefault(item, TRVT_SLOT_INDEX_INT); // this updates the instruction in-place + } if (IsTraceRestrictDoubleItem(item)) i++; } } diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 8d21b16256..e85733e8e1 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -133,7 +133,8 @@ enum TraceRestrictItemType { TRIT_COND_TRAIN_GROUP = 18, ///< Test train group membership TRIT_COND_PHYS_PROP = 19, ///< Test train physical property TRIT_COND_PHYS_RATIO = 20, ///< Test train physical property ratio - TRIT_COND_SLOT = 21, ///< Test train slot membership + 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: reserved for future use /* space up to 31 */ }; @@ -232,6 +233,15 @@ enum TraceRestrictSlotCondOpField { /* space up to 8 */ }; +/** + * TraceRestrictItem auxiliary type field, for TRIT_COND_SLOT_OCCUPANCY + */ +enum TraceRestrictSlotOccupancyCondAuxField { + TRSOCAF_OCCUPANTS = 0, ///< value field is the occupancy count of the slot + TRSOCAF_REMAINING = 1, ///< value field is the remaining occupancy of the slot + /* space up to 3 */ +}; + /** * TraceRestrictItem pathfinder penalty preset index * This may not be shortened, only lengthened, as preset indexes are stored in save games @@ -451,7 +461,8 @@ static inline bool IsTraceRestrictConditional(TraceRestrictItem item) /** Is TraceRestrictItem a double-item type? */ static inline bool IsTraceRestrictDoubleItem(TraceRestrictItem item) { - return GetTraceRestrictType(item) == TRIT_COND_PBS_ENTRY_SIGNAL; + const TraceRestrictItemType type = GetTraceRestrictType(item); + return type == TRIT_COND_PBS_ENTRY_SIGNAL || type == TRIT_COND_SLOT_OCCUPANCY; } /** @@ -489,6 +500,7 @@ enum TraceRestrictValueType { TRVT_FORCE_WEIGHT_RATIO = 17,///< takes a force / weight ratio, * 100 TRVT_WAIT_AT_PBS = 18,///< takes a value 0 = wait at PBS signal, 1 = cancel wait at PBS signal TRVT_SLOT_INDEX = 19,///< takes a TraceRestrictSlotID + TRVT_SLOT_INDEX_INT = 20,///< takes a TraceRestrictSlotID, and an integer in the next item slot }; /** @@ -555,11 +567,15 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR out.cond_type = TRCOT_BINARY; break; - case TRIT_COND_SLOT: + case TRIT_COND_TRAIN_IN_SLOT: out.value_type = TRVT_SLOT_INDEX; out.cond_type = TRCOT_BINARY; break; + case TRIT_COND_SLOT_OCCUPANCY: + out.value_type = TRVT_SLOT_INDEX_INT; + break; + case TRIT_COND_PHYS_PROP: switch (static_cast(GetTraceRestrictAuxField(item))) { case TRPPCAF_WEIGHT: @@ -628,6 +644,7 @@ static inline bool IsTraceRestrictTypeAuxSubtype(TraceRestrictItemType type) switch (type) { case TRIT_COND_PHYS_PROP: case TRIT_COND_PHYS_RATIO: + case TRIT_COND_SLOT_OCCUPANCY: return true; default: diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index 5bc9b5fe05..0041d33771 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -41,6 +41,7 @@ #include "vehicle_base.h" #include "vehicle_gui.h" #include "vehicle_gui_base.h" +#include "scope.h" #include "table/sprites.h" #include "core/geometry_func.hpp" @@ -54,6 +55,7 @@ enum TraceRestrictWindowWidgets { TR_WIDGET_SEL_TOP_LEFT_2, TR_WIDGET_SEL_TOP_LEFT, + TR_WIDGET_SEL_TOP_LEFT_AUX, TR_WIDGET_SEL_TOP_MIDDLE, TR_WIDGET_SEL_TOP_RIGHT, TR_WIDGET_SEL_SHARE, @@ -71,6 +73,7 @@ enum TraceRestrictWindowWidgets { TR_WIDGET_VALUE_DROPDOWN, TR_WIDGET_VALUE_DEST, TR_WIDGET_VALUE_SIGNAL, + TR_WIDGET_LEFT_AUX_DROPDOWN, TR_WIDGET_BLANK_L2, TR_WIDGET_BLANK_L, @@ -97,6 +100,9 @@ enum PanelWidgets { DPL_TYPE = 0, DPL_BLANK, + // Left aux + DPLA_DROPDOWN = 0, + // Middle DPM_COMPARATOR = 0, DPM_SLOT_OP, @@ -332,6 +338,8 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG STR_TRACE_RESTRICT_VARIABLE_TRAIN_POWER_WEIGHT_RATIO, STR_TRACE_RESTRICT_VARIABLE_TRAIN_MAX_TE_WEIGHT_RATIO, STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT, + STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY, + STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_REMAINING, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED, INVALID_STRING_ID, }; @@ -350,7 +358,9 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG TRIT_COND_PHYS_PROP | (TRPPCAF_MAX_TE << 16), TRIT_COND_PHYS_RATIO | (TRPPRCAF_POWER_WEIGHT << 16), TRIT_COND_PHYS_RATIO | (TRPPRCAF_MAX_TE_WEIGHT << 16), - TRIT_COND_SLOT, + TRIT_COND_TRAIN_IN_SLOT, + TRIT_COND_SLOT_OCCUPANCY | (TRSOCAF_OCCUPANTS << 16), + TRIT_COND_SLOT_OCCUPANCY | (TRSOCAF_REMAINING << 16), TRIT_COND_UNDEFINED, }; static const TraceRestrictDropDownListSet set_cond = { @@ -362,7 +372,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG if (_settings_client.gui.show_adv_tracerestrict_features) { *hide_mask = 0; } else { - *hide_mask = is_conditional ? 0x4000 : 0x30; + *hide_mask = is_conditional ? 0x1C000 : 0x30; } } return is_conditional ? &set_cond : &set_action; @@ -941,6 +951,27 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric } break; + case TRVT_SLOT_INDEX_INT: { + assert(prog != NULL); + assert(GetTraceRestrictType(item) == TRIT_COND_SLOT_OCCUPANCY); + uint32 value = *(TraceRestrictProgram::InstructionAt(prog->items, index - 1) + 1); + SetDParam(0, _program_cond_type[GetTraceRestrictCondFlags(item)]); + SetDParam(1, GetTraceRestrictAuxField(item) ? STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_REMAINING_SHORT : STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY_SHORT); + if (GetTraceRestrictValue(item) == INVALID_TRACE_RESTRICT_SLOT_ID) { + instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_SLOT_OCCUPANCY_STR; + SetDParam(2, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED_RED); + SetDParam(3, selected ? STR_TRACE_RESTRICT_WHITE : STR_EMPTY); + SetDParam(4, GetDropDownStringByValue(GetCondOpDropDownListSet(properties), GetTraceRestrictCondOp(item))); + SetDParam(5, value); + } else { + instruction_string = STR_TRACE_RESTRICT_CONDITIONAL_SLOT_OCCUPANCY; + SetDParam(2, GetTraceRestrictValue(item)); + SetDParam(3, GetDropDownStringByValue(GetCondOpDropDownListSet(properties), GetTraceRestrictCondOp(item))); + SetDParam(4, value); + } + break; + } + default: NOT_REACHED(); break; @@ -1049,6 +1080,7 @@ class TraceRestrictWindow: public Window { std::map drop_down_list_mapping; ///< mapping of widget IDs to drop down list sets TraceRestrictItem expecting_inserted_item; ///< set to instruction when performing an instruction insertion, used to handle selection update on insertion int current_placement_widget; ///< which widget has a SetObjectToPlaceWnd, if any + int current_left_aux_plane; ///< current plane for TR_WIDGET_SEL_TOP_LEFT_AUX widget public: TraceRestrictWindow(WindowDesc *desc, TileIndex tile, Track track) @@ -1062,6 +1094,8 @@ public: this->CreateNestedTree(); this->vscroll = this->GetScrollbar(TR_WIDGET_SCROLLBAR); + this->GetWidget(TR_WIDGET_SEL_TOP_LEFT_AUX)->SetDisplayedPlane(SZSP_NONE); + this->current_left_aux_plane = SZSP_NONE; this->FinishInitNested(MakeTraceRestrictRefId(tile, track)); this->ReloadProgramme(); @@ -1245,6 +1279,9 @@ public: if (IsIntegerValueType(type)) { SetDParam(0, ConvertIntegerValue(type, GetTraceRestrictValue(item), true)); ShowQueryString(STR_JUST_INT, STR_TRACE_RESTRICT_VALUE_CAPTION, 10, this, CS_NUMERAL, QSF_NONE); + } else if (type == TRVT_SLOT_INDEX_INT) { + SetDParam(0, *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, this->selected_instruction - 1) + 1)); + ShowQueryString(STR_JUST_INT, STR_TRACE_RESTRICT_VALUE_CAPTION, 10, this, CS_NUMERAL, QSF_NONE); } break; } @@ -1316,6 +1353,22 @@ public: break; } + case TR_WIDGET_LEFT_AUX_DROPDOWN: { + TraceRestrictItem item = this->GetSelected(); + switch (GetTraceRestrictTypeProperties(item).value_type) { + case TRVT_SLOT_INDEX_INT: { + int selected; + DropDownList *dlist = GetSlotDropDownList(this->GetOwner(), + *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, this->selected_instruction - 1) + 1), selected); + if (dlist != NULL) ShowDropDownList(this, dlist, selected, TR_WIDGET_LEFT_AUX_DROPDOWN); + break; + } + + default: + break; + } + } + case TR_WIDGET_VALUE_DEST: { SetObjectToPlaceAction(widget, ANIMCURSOR_PICKSTATION); break; @@ -1384,6 +1437,10 @@ public: ShowErrorMessage(STR_TRACE_RESTRICT_ERROR_VALUE_TOO_LARGE, STR_EMPTY, WL_INFO); return; } + } else if (type == TRVT_SLOT_INDEX_INT) { + value = atoi(str); + TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_DUAL_ITEM, this->selected_instruction - 1, value, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM); + return; } else { return; } @@ -1399,9 +1456,9 @@ public: return; } - if (widget == TR_WIDGET_VALUE_DROPDOWN) { + if (widget == TR_WIDGET_VALUE_DROPDOWN || widget == TR_WIDGET_LEFT_AUX_DROPDOWN) { TraceRestrictTypePropertySet type = GetTraceRestrictTypeProperties(item); - if (type.value_type == TRVT_GROUP_INDEX || type.value_type == TRVT_SLOT_INDEX) { + if (type.value_type == TRVT_GROUP_INDEX || type.value_type == TRVT_SLOT_INDEX || type.value_type == TRVT_SLOT_INDEX_INT) { SetTraceRestrictValue(item, index); TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_ITEM, this->selected_instruction - 1, item, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM); return; @@ -1721,6 +1778,8 @@ public: TraceRestrictValueType type = GetTraceRestrictTypeProperties(item).value_type; if (IsIntegerValueType(type)) { SetDParam(0, ConvertIntegerValue(type, GetTraceRestrictValue(item), true)); + } else if (type == TRVT_SLOT_INDEX_INT) { + SetDParam(0, *(TraceRestrictProgram::InstructionAt(this->GetProgram()->items, this->selected_instruction - 1) + 1)); } break; } @@ -1760,6 +1819,15 @@ public: } break; } + + case TR_WIDGET_LEFT_AUX_DROPDOWN: { + TraceRestrictItem item = this->GetSelected(); + TraceRestrictTypePropertySet type = GetTraceRestrictTypeProperties(item); + if (type.value_type == TRVT_SLOT_INDEX_INT) { + SetDParam(0, GetTraceRestrictValue(item)); + } + break; + } } } @@ -1930,9 +1998,11 @@ private: this->RaiseWidget(TR_WIDGET_VALUE_DROPDOWN); this->RaiseWidget(TR_WIDGET_VALUE_DEST); this->RaiseWidget(TR_WIDGET_VALUE_SIGNAL); + this->RaiseWidget(TR_WIDGET_LEFT_AUX_DROPDOWN); NWidgetStacked *left_2_sel = this->GetWidget(TR_WIDGET_SEL_TOP_LEFT_2); NWidgetStacked *left_sel = this->GetWidget(TR_WIDGET_SEL_TOP_LEFT); + NWidgetStacked *left_aux_sel = this->GetWidget(TR_WIDGET_SEL_TOP_LEFT_AUX); NWidgetStacked *middle_sel = this->GetWidget(TR_WIDGET_SEL_TOP_MIDDLE); NWidgetStacked *right_sel = this->GetWidget(TR_WIDGET_SEL_TOP_RIGHT); NWidgetStacked *share_sel = this->GetWidget(TR_WIDGET_SEL_SHARE); @@ -1947,6 +2017,7 @@ private: this->DisableWidget(TR_WIDGET_VALUE_DROPDOWN); this->DisableWidget(TR_WIDGET_VALUE_DEST); this->DisableWidget(TR_WIDGET_VALUE_SIGNAL); + this->DisableWidget(TR_WIDGET_LEFT_AUX_DROPDOWN); this->DisableWidget(TR_WIDGET_INSERT); this->DisableWidget(TR_WIDGET_REMOVE); @@ -1965,6 +2036,7 @@ private: left_2_sel->SetDisplayedPlane(DPL2_BLANK); left_sel->SetDisplayedPlane(DPL_BLANK); + left_aux_sel->SetDisplayedPlane(SZSP_NONE); middle_sel->SetDisplayedPlane(DPM_BLANK); right_sel->SetDisplayedPlane(DPR_BLANK); share_sel->SetDisplayedPlane(DPS_SHARE); @@ -1974,6 +2046,13 @@ private: this->GetWidget(TR_WIDGET_CAPTION)->widget_data = (prog && prog->refcount > 1) ? STR_TRACE_RESTRICT_CAPTION_SHARED : STR_TRACE_RESTRICT_CAPTION; + auto left_aux_guard = scope_guard([&]() { + if (this->current_left_aux_plane != left_aux_sel->shown_plane) { + this->current_left_aux_plane = left_aux_sel->shown_plane; + this->ReInit(); + } + }); + // Don't allow modifications if don't own if (this->GetOwner() != _local_company) { this->SetDirty(); @@ -2168,7 +2247,7 @@ private: } break; - case TRVT_SLOT_INDEX: + case TRVT_SLOT_INDEX: { right_sel->SetDisplayedPlane(DPR_VALUE_DROPDOWN); if (!IsTraceRestrictConditional(item)) { middle_sel->SetDisplayedPlane(DPM_SLOT_OP); @@ -2195,6 +2274,32 @@ private: break; } break; + } + + case TRVT_SLOT_INDEX_INT: { + right_sel->SetDisplayedPlane(DPR_VALUE_INT); + left_aux_sel->SetDisplayedPlane(DPLA_DROPDOWN); + this->EnableWidget(TR_WIDGET_VALUE_INT); + + const TraceRestrictSlot *slot; + FOR_ALL_TRACE_RESTRICT_SLOTS(slot) { + if (slot->owner == this->GetOwner()) { + this->EnableWidget(TR_WIDGET_LEFT_AUX_DROPDOWN); + break; + } + } + + switch (GetTraceRestrictValue(item)) { + case INVALID_TRACE_RESTRICT_SLOT_ID: + this->GetWidget(TR_WIDGET_LEFT_AUX_DROPDOWN)->widget_data = STR_TRACE_RESTRICT_VARIABLE_UNDEFINED; + break; + + default: + this->GetWidget(TR_WIDGET_LEFT_AUX_DROPDOWN)->widget_data = STR_TRACE_RESTRICT_SLOT_NAME; + break; + } + break; + } default: break; @@ -2328,6 +2433,10 @@ static const NWidgetPart _nested_program_widgets[] = { NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_BLANK_L), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_EMPTY, STR_NULL), SetResize(1, 0), EndContainer(), + NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_TOP_LEFT_AUX), + NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_LEFT_AUX_DROPDOWN), SetMinimalSize(124, 12), SetFill(1, 0), + SetDataTip(STR_NULL, STR_TRACE_RESTRICT_COND_VALUE_TOOLTIP), SetResize(1, 0), + EndContainer(), NWidget(NWID_SELECTION, INVALID_COLOUR, TR_WIDGET_SEL_TOP_MIDDLE), NWidget(WWT_DROPDOWN, COLOUR_GREY, TR_WIDGET_COMPARATOR), SetMinimalSize(124, 12), SetFill(1, 0), SetDataTip(STR_NULL, STR_TRACE_RESTRICT_COND_COMPARATOR_TOOLTIP), SetResize(1, 0),