diff --git a/src/sl/extended_ver_sl.cpp b/src/sl/extended_ver_sl.cpp index 4c832992d1..4010ab22c1 100644 --- a/src/sl/extended_ver_sl.cpp +++ b/src/sl/extended_ver_sl.cpp @@ -76,7 +76,7 @@ static uint32_t saveSTC(const SlxiSubChunkInfo *info, bool dry_run); const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { 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_TRACE_RESTRICT, XSCF_NULL, 16, 16, "tracerestrict", nullptr, nullptr, "TRRM,TRRP,TRRS" }, + { XSLFI_TRACE_RESTRICT, XSCF_NULL, 17, 17, "tracerestrict", nullptr, nullptr, "TRRM,TRRP,TRRS" }, { 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_STATUSCND, XSCF_NULL, 2, 2, "tracerestrict_status_cond", nullptr, nullptr, nullptr }, diff --git a/src/sl/tracerestrict_sl.cpp b/src/sl/tracerestrict_sl.cpp index 1ebfea95e8..9c2be84d8d 100644 --- a/src/sl/tracerestrict_sl.cpp +++ b/src/sl/tracerestrict_sl.cpp @@ -72,6 +72,20 @@ static void Load_TRRP() if (IsTraceRestrictDoubleItem(item)) i++; } } + if (SlXvIsFeatureMissing(XSLFI_TRACE_RESTRICT, 17)) { + /* TRIT_SLOT subtype moved from cond op to combined aux and cond op field in version 17. + * Do this for all previous versions to avoid cases where it is unexpectedly present despite the version, + * e.g. in JokerPP and non-SLXI tracerestrict saves. + */ + 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) { + TraceRestrictSlotSubtypeField subtype = static_cast(GetTraceRestrictCondOp(item)); + SetTraceRestrictCombinedAuxCondOpField(item, subtype); + } + if (IsTraceRestrictDoubleItem(item)) i++; + } + } CommandCost validation_result = prog->Validate(); if (validation_result.Failed()) { char str[4096]; diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 5ed9937e4d..d401912a33 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -727,7 +727,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp if (!input.permitted_slot_operations) break; TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(GetTraceRestrictValue(item)); if (slot == nullptr || slot->vehicle_type != v->type) break; - switch (static_cast(GetTraceRestrictCondOp(item))) { + switch (static_cast(GetTraceRestrictCombinedAuxCondOpField(item))) { case TRSCOF_ACQUIRE_WAIT: if (input.permitted_slot_operations & TRPISP_ACQUIRE) { if (!slot->Occupy(v->index)) out.flags |= TRPRF_WAIT_AT_PBS; @@ -1349,7 +1349,7 @@ CommandCost TraceRestrictProgram::Validate(const std::vector break; case TRIT_SLOT: - switch (static_cast(GetTraceRestrictCondOp(item))) { + switch (static_cast(GetTraceRestrictCombinedAuxCondOpField(item))) { case TRSCOF_ACQUIRE_WAIT: actions_used_flags |= TRPAUF_SLOT_ACQUIRE | TRPAUF_SLOT_CONDITIONALS | TRPAUF_WAIT_AT_PBS; break; diff --git a/src/tracerestrict.h b/src/tracerestrict.h index 077478b4f6..61f839304e 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -377,9 +377,9 @@ enum TraceRestrictTimeDateValueField { }; /** - * TraceRestrictItem repurposed condition operator field, for slot operation type actions + * TraceRestrictItem subtype field, using the combined auxiliary and cond op bits, for slot operation type actions */ -enum TraceRestrictSlotCondOpField { +enum TraceRestrictSlotSubtypeField { TRSCOF_ACQUIRE_WAIT = 0, ///< acquire a slot, or wait at the current signal TRSCOF_ACQUIRE_TRY = 1, ///< try to acquire a slot, or carry on otherwise TRSCOF_RELEASE_BACK = 2, ///< release a slot (back of train) @@ -388,7 +388,7 @@ enum TraceRestrictSlotCondOpField { TRSCOF_PBS_RES_END_ACQ_TRY = 5, ///< PBS reservations ending at this signal: acquire a slot, or carry on otherwise TRSCOF_PBS_RES_END_RELEASE = 6, ///< PBS reservations ending at this signal: release a slot TRSCOF_ACQUIRE_TRY_ON_RESERVE = 7, ///< try to acquire a slot (on reserve), or carry on otherwise - /* space up to 7 */ + /* space up to 31 */ }; /** diff --git a/src/tracerestrict_gui.cpp b/src/tracerestrict_gui.cpp index d1af054e1e..b2b1c7c48b 100644 --- a/src/tracerestrict_gui.cpp +++ b/src/tracerestrict_gui.cpp @@ -810,7 +810,7 @@ static const TraceRestrictDropDownListSet _passes_through_cond_ops = { _passes_through_cond_ops_str, _passes_through_cond_ops_val, }; -static const StringID _slot_op_cond_ops_str[] = { +static const StringID _slot_op_subtypes_str[] = { STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT, STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE, STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT, @@ -821,7 +821,7 @@ static const StringID _slot_op_cond_ops_str[] = { STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE_ON_RES, INVALID_STRING_ID, }; -static const uint _slot_op_cond_ops_val[] = { +static const uint _slot_op_subtypes_val[] = { TRSCOF_ACQUIRE_WAIT, TRSCOF_ACQUIRE_TRY, TRSCOF_RELEASE_FRONT, @@ -831,9 +831,9 @@ static const uint _slot_op_cond_ops_val[] = { TRSCOF_PBS_RES_END_RELEASE, TRSCOF_ACQUIRE_TRY_ON_RESERVE, }; -/** cargo conditional operators dropdown list set */ -static const TraceRestrictDropDownListSet _slot_op_cond_ops = { - _slot_op_cond_ops_str, _slot_op_cond_ops_val, +/** slot op subtypes dropdown list set */ +static const TraceRestrictDropDownListSet _slot_op_subtypes = { + _slot_op_subtypes_str, _slot_op_subtypes_val, }; static const StringID _counter_op_cond_ops_str[] = { @@ -1588,7 +1588,7 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric break; case TRIT_SLOT: - switch (static_cast(GetTraceRestrictCondOp(item))) { + switch (static_cast(GetTraceRestrictCombinedAuxCondOpField(item))) { case TRSCOF_ACQUIRE_WAIT: instruction_string = STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT_ITEM; break; @@ -2002,7 +2002,7 @@ public: case TR_WIDGET_SLOT_OP: { TraceRestrictItem item = this->GetSelected(); - this->ShowDropDownListWithValue(&_slot_op_cond_ops, GetTraceRestrictCondOp(item), false, TR_WIDGET_SLOT_OP, 0, 0); + this->ShowDropDownListWithValue(&_slot_op_subtypes, GetTraceRestrictCombinedAuxCondOpField(item), false, TR_WIDGET_SLOT_OP, 0, 0); break; } @@ -2348,13 +2348,18 @@ public: } case TR_WIDGET_COMPARATOR: - case TR_WIDGET_SLOT_OP: case TR_WIDGET_COUNTER_OP: { SetTraceRestrictCondOp(item, static_cast(value)); TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_ITEM, this->selected_instruction - 1, item, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM); break; } + case TR_WIDGET_SLOT_OP: { + SetTraceRestrictCombinedAuxCondOpField(item, value); + TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_ITEM, this->selected_instruction - 1, item, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM); + break; + } + case TR_WIDGET_VALUE_DROPDOWN: { if (GetTraceRestrictTypeProperties(item).value_type == TRVT_PF_PENALTY) { if (value == TRPPPI_END) { @@ -3258,7 +3263,7 @@ private: } this->GetWidget(TR_WIDGET_SLOT_OP)->widget_data = - GetDropDownStringByValue(&_slot_op_cond_ops, GetTraceRestrictCondOp(item)); + GetDropDownStringByValue(&_slot_op_subtypes, GetTraceRestrictCombinedAuxCondOpField(item)); switch (GetTraceRestrictValue(item)) { case INVALID_TRACE_RESTRICT_SLOT_ID: this->GetWidget(TR_WIDGET_VALUE_DROPDOWN)->widget_data = STR_TRACE_RESTRICT_VARIABLE_UNDEFINED;