diff --git a/src/lang/extra/english.txt b/src/lang/extra/english.txt index ec850ca802..0ff6b7802e 100644 --- a/src/lang/extra/english.txt +++ b/src/lang/extra/english.txt @@ -1640,6 +1640,8 @@ STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_FIRST :is first slot STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_FIRST :is not first slot STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_LAST :is last slot STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_LAST :is not last slot +STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG :has tag {NUM} +STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG :doesn't have tag {NUM} STR_ORDERS_MANAGE_LIST :{BLACK}Manage List STR_ORDERS_MANAGE_LIST_TOOLTIP :{BLACK}Manage this order list @@ -2105,6 +2107,8 @@ STR_SCHDISPATCH_REUSE_DEPARTURE_SLOTS_TOOLTIP :{BLACK}Set whet STR_SCHDISPATCH_MANAGE_SLOT :{BLACK}Manage Slot STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_SLOT :Re-use departure slot STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_SLOT_TOOLTIP :{BLACK}Set whether the selected departure slot may be used more than once. +STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_TAG :Tag {NUM} +STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_TAG_TOOLTIP :{BLACK}Tag the selected departure slot (for use with conditional orders). STR_SCHDISPATCH_NO_SCHEDULES :{BLACK}No Schedules STR_SCHDISPATCH_SCHEDULE_ID :{BLACK}Schedule {NUM} of {NUM} STR_SCHDISPATCH_NAMED_SCHEDULE_ID :{BLACK}{RAW_STRING} ({NUM} of {NUM}) @@ -2119,6 +2123,7 @@ STR_SCHDISPATCH_SLOT_TOOLTIP_LAST :{}Last departur STR_SCHDISPATCH_SLOT_TOOLTIP_NEXT :{}Next available departure slot STR_SCHDISPATCH_SLOT_TOOLTIP_REUSE :{}Departure slot may be used more than once STR_SCHDISPATCH_SLOT_TOOLTIP_TIME_SUFFIX : ({DATE_WALLCLOCK_TINY}) +STR_SCHDISPATCH_SLOT_TOOLTIP_TAG :{}Tag {NUM} STR_SCHDISPATCH_SUMMARY_NO_LAST_DEPARTURE :{BLACK}No previous departures. STR_SCHDISPATCH_SUMMARY_LAST_DEPARTURE_PAST :{BLACK}Last departure at {DATE_WALLCLOCK_TINY}. diff --git a/src/order_base.h b/src/order_base.h index 7bd6da4b9c..570803aa79 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -730,6 +730,8 @@ struct DispatchSlot { */ enum ScheduledDispatchSlotFlags { SDSF_REUSE_SLOT = 0, ///< Allow this slot to be used more than once + SDSF_FIRST_TAG = 8, ///< First tag flag + SDSF_LAST_TAG = 11, ///< Last tag flag }; }; diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 0cc122cd95..c47e13738a 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1992,7 +1992,6 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin case OCV_COUNTER_VALUE: case OCV_TIME_DATE: case OCV_TIMETABLE: - case OCV_DISPATCH_SLOT: break; default: @@ -2021,7 +2020,9 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin break; case OCV_DISPATCH_SLOT: - if (data >= OSDSCM_END) return CMD_ERROR; + if (data != UINT16_MAX && data >= v->orders->GetScheduledDispatchScheduleCount()) { + return CMD_ERROR; + } break; default: @@ -2293,7 +2294,6 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin case OCV_CARGO_WAITING_AMOUNT: case OCV_COUNTER_VALUE: - case OCV_DISPATCH_SLOT: SB(order->GetXDataRef(), 0, 16, data); break; @@ -2309,6 +2309,10 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, uin SB(order->GetXDataRef(), 16, 16, data); break; + case OCV_DISPATCH_SLOT: + SB(order->GetXDataRef(), 0, 16, data); + break; + default: order->SetConditionValue(data); break; @@ -3051,7 +3055,7 @@ bool EvaluateDispatchSlotConditionalOrder(const Order *order, const Vehicle *v, if (predicted != nullptr) *predicted = true; int32_t offset; - if (order->GetConditionValue() & 2) { + if (HasBit(order->GetConditionValue(), ODCB_LAST_DISPATCHED)) { int32_t last = sched.GetScheduledDispatchLastDispatch(); if (last == INVALID_SCHEDULED_DISPATCH_OFFSET) { /* No last dispatched */ @@ -3066,11 +3070,26 @@ bool EvaluateDispatchSlotConditionalOrder(const Order *order, const Vehicle *v, offset = (slot - sched.GetScheduledDispatchStartTick()).base() % sched.GetScheduledDispatchDuration(); } - bool value; - if (order->GetConditionValue() & 1) { - value = (offset == (int32_t)sched.GetScheduledDispatch().back().offset); - } else { - value = (offset == (int32_t)sched.GetScheduledDispatch().front().offset); + bool value = false; + switch ((OrderDispatchConditionModes)GB(order->GetConditionValue(), ODCB_MODE_START, ODCB_MODE_COUNT)) { + case ODCM_FIRST_LAST: + if (HasBit(order->GetConditionValue(), ODFLCB_LAST_SLOT)) { + value = (offset == (int32_t)sched.GetScheduledDispatch().back().offset); + } else { + value = (offset == (int32_t)sched.GetScheduledDispatch().front().offset); + } + break; + + case OCDM_TAG: { + uint8_t tag = (uint8_t)GB(order->GetConditionValue(), ODFLCB_TAG_START, ODFLCB_TAG_COUNT); + for (const DispatchSlot &slot : sched.GetScheduledDispatch()) { + if (offset == (int32_t)slot.offset) { + value = HasBit(slot.flags, DispatchSlot::SDSF_FIRST_TAG + tag); + break; + } + } + break; + } } return OrderConditionCompare(order->GetConditionComparator(), value ? 1 : 0, 0); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index cb8548510b..8bd7e2add0 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -756,6 +756,18 @@ static const StringID _order_conditional_condition_dispatch_slot_last[] = { INVALID_STRING_ID, }; +static const StringID _order_conditional_condition_dispatch_slot_tag[] = { + STR_NULL, + STR_NULL, + STR_NULL, + STR_NULL, + STR_NULL, + STR_NULL, + STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG, + STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG, + INVALID_STRING_ID, +}; + extern uint ConvertSpeedToDisplaySpeed(uint speed, VehicleType type); extern uint ConvertDisplaySpeedToSpeed(uint speed, VehicleType type); @@ -1101,20 +1113,43 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int } else if (ocv == OCV_DISPATCH_SLOT) { SetDParam(0, STR_ORDER_CONDITIONAL_DISPATCH_SLOT_DISPLAY); if (GB(order->GetXData(), 0, 16) != UINT16_MAX) { - const DispatchSchedule &ds = v->orders->GetDispatchScheduleByIndex(GB(order->GetXData(), 0, 16)); - if (ds.ScheduleName().empty()) { + bool have_name = false; + if (GB(order->GetXData(), 0, 16) < v->orders->GetScheduledDispatchScheduleCount()) { + const DispatchSchedule &ds = v->orders->GetDispatchScheduleByIndex(GB(order->GetXData(), 0, 16)); + if (!ds.ScheduleName().empty()) { + _temp_special_strings[0] = ds.ScheduleName(); + have_name = true; + } + } + if (!have_name) { auto tmp_params = MakeParameters(GB(order->GetXData(), 0, 16) + 1); _temp_special_strings[0] = GetStringWithArgs(STR_TIMETABLE_ASSIGN_SCHEDULE_ID, tmp_params); - } else { - _temp_special_strings[0] = ds.ScheduleName(); } SetDParam(2, SPECSTR_TEMP_START); } else { SetDParam(2, STR_TIMETABLE_ASSIGN_SCHEDULE_NONE); } - SetDParam(3, STR_TRACE_RESTRICT_DISPATCH_SLOT_NEXT + (order->GetConditionValue() / 2)); - SetDParam(4, STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_FIRST + ((order->GetConditionComparator() == OCC_IS_FALSE) ? 1 : 0) + - ((order->GetConditionValue() % 2) ? 2 : 0)); + + const uint16_t value = order->GetConditionValue(); + SetDParam(3, HasBit(value, ODCB_LAST_DISPATCHED) ? STR_TRACE_RESTRICT_DISPATCH_SLOT_LAST : STR_TRACE_RESTRICT_DISPATCH_SLOT_NEXT); + + switch ((OrderDispatchConditionModes)GB(value, ODCB_MODE_START, ODCB_MODE_COUNT)) { + case ODCM_FIRST_LAST: + SetDParam(4, STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_FIRST + ((order->GetConditionComparator() == OCC_IS_FALSE) ? 1 : 0) + + (HasBit(value, ODFLCB_LAST_SLOT) ? 2 : 0)); + break; + + case OCDM_TAG: { + auto tmp_params = MakeParameters(GB(value, ODFLCB_TAG_START, ODFLCB_TAG_COUNT) + 1); + _temp_special_strings[1] = GetStringWithArgs((order->GetConditionComparator() == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG : STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG, tmp_params); + SetDParam(4, SPECSTR_TEMP_START + 1); + break; + } + + default: + SetDParam(4, STR_UNDEFINED); + break; + } } else { OrderConditionComparator occ = order->GetConditionComparator(); SetDParam(0, (occ == OCC_IS_TRUE || occ == OCC_IS_FALSE) ? STR_ORDER_CONDITIONAL_TRUE_FALSE : STR_ORDER_CONDITIONAL_NUM); @@ -1562,8 +1597,19 @@ private: case OCV_VEH_IN_SLOT: return v->type == VEH_TRAIN ? _order_conditional_condition_is_in_slot : _order_conditional_condition_is_in_slot_non_train; - case OCV_DISPATCH_SLOT: - return (order->GetConditionValue() % 2) == 0 ? _order_conditional_condition_dispatch_slot_first : _order_conditional_condition_dispatch_slot_last; + case OCV_DISPATCH_SLOT: { + const uint16_t value = order->GetConditionValue(); + switch ((OrderDispatchConditionModes)GB(value, ODCB_MODE_START, ODCB_MODE_COUNT)) { + case ODCM_FIRST_LAST: + return HasBit(value, ODFLCB_LAST_SLOT) ? _order_conditional_condition_dispatch_slot_last : _order_conditional_condition_dispatch_slot_first; + + case OCDM_TAG: + return _order_conditional_condition_dispatch_slot_tag; + + default: + return _order_conditional_condition; + } + } default: return _order_conditional_condition; @@ -2288,7 +2334,7 @@ public: if (ocv == OCV_CARGO_WAITING_AMOUNT) { aux2_sel->SetDisplayedPlane(DP_COND_AUX2_VIA); } else if (is_sched_dispatch) { - this->GetWidget(WID_O_COND_SCHED_TEST)->widget_data = STR_TRACE_RESTRICT_DISPATCH_SLOT_SHORT_NEXT + (order->GetConditionValue() / 2); + this->GetWidget(WID_O_COND_SCHED_TEST)->widget_data = HasBit(order->GetConditionValue(), ODCB_LAST_DISPATCHED) ? STR_TRACE_RESTRICT_DISPATCH_SLOT_SHORT_LAST : STR_TRACE_RESTRICT_DISPATCH_SLOT_SHORT_NEXT; aux2_sel->SetDisplayedPlane(DP_COND_AUX2_SCHED_TEST); } else { aux2_sel->SetDisplayedPlane(SZSP_NONE); @@ -2564,6 +2610,16 @@ public: break; } + case WID_O_COND_COMPARATOR: { + VehicleOrderID sel = this->OrderGetSel(); + const Order *order = this->vehicle->GetOrder(sel); + + if (order != nullptr && order->IsType(OT_CONDITIONAL) && order->GetConditionVariable() == OCV_DISPATCH_SLOT) { + SetDParam(0, GB(order->GetConditionValue(), ODFLCB_TAG_START, ODFLCB_TAG_COUNT) + 1); + } + break; + } + case WID_O_COND_SLOT: { VehicleOrderID sel = this->OrderGetSel(); const Order *order = this->vehicle->GetOrder(sel); @@ -2986,8 +3042,8 @@ public: } case WID_O_COND_SCHED_TEST: { - ShowDropDownMenu(this, _order_dispatch_slot_dropdown, this->vehicle->GetOrder(this->OrderGetSel())->GetConditionValue() / 2, - WID_O_COND_SCHED_TEST, 0, 0); + uint16_t value = this->vehicle->GetOrder(this->OrderGetSel())->GetConditionValue(); + ShowDropDownMenu(this, _order_dispatch_slot_dropdown, HasBit(value, ODCB_LAST_DISPATCHED) ? 1 : 0, WID_O_COND_SCHED_TEST, 0, 0); break; } @@ -3062,11 +3118,38 @@ public: const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); if (o->GetConditionVariable() == OCV_DISPATCH_SLOT) { DropDownList list; - list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_FIRST, 0x100, false)); - list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_FIRST, 0x101, false)); - list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_LAST, 0x102, false)); - list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_LAST, 0x103, false)); - int selected = 0x100 + ((o->GetConditionValue() % 2) * 2) + ((o->GetConditionComparator() == OCC_IS_FALSE) ? 1 : 0); + + const int true_cond = ((int)OCC_IS_TRUE) << 16; + const int false_cond = ((int)OCC_IS_FALSE) << 16; + int first_last_value = 0; + SB(first_last_value, ODCB_MODE_START, ODCB_MODE_COUNT, ODCM_FIRST_LAST); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_FIRST, true_cond | first_last_value, false)); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_FIRST, false_cond | first_last_value, false)); + SetBit(first_last_value, ODFLCB_LAST_SLOT); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_LAST, true_cond | first_last_value, false)); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_IS_NOT_LAST, false_cond | first_last_value, false)); + + uint16_t slot_flags = 0; + uint schedule_index = GB(o->GetXData(), 0, 16); + if (schedule_index < this->vehicle->orders->GetScheduledDispatchScheduleCount()) { + const DispatchSchedule &ds = this->vehicle->orders->GetDispatchScheduleByIndex(schedule_index); + for (const DispatchSlot &slot : ds.GetScheduledDispatch()) { + slot_flags |= slot.flags; + } + } + + for (uint8_t tag = 0; tag <= (DispatchSlot::SDSF_LAST_TAG - DispatchSlot::SDSF_FIRST_TAG); tag++) { + if (HasBit(slot_flags, tag + DispatchSlot::SDSF_FIRST_TAG)) { + int tag_cond_value = 0; + SB(tag_cond_value, ODCB_MODE_START, ODCB_MODE_COUNT, OCDM_TAG); + SB(tag_cond_value, ODFLCB_TAG_START, ODFLCB_TAG_COUNT, tag); + SetDParam(0, tag + 1); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_HAS_TAG, true_cond | tag_cond_value, false)); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_COMPARATOR_DISPATCH_SLOT_DOESNT_HAVE_TAG, false_cond | tag_cond_value, false)); + } + } + + int selected = (((int)o->GetConditionComparator()) << 16) | (o->GetConditionValue() & ~GetBitMaskSC(ODCB_LAST_DISPATCHED, 1)); ShowDropDownList(this, std::move(list), selected, WID_O_COND_COMPARATOR, 0); break; } @@ -3295,16 +3378,17 @@ public: this->ModifyOrder(this->OrderGetSel(), MOF_COND_VARIABLE | index << 8); break; - case WID_O_COND_COMPARATOR: - if (index >= 0x100) { - const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); - if (o == nullptr || o->GetConditionVariable() != OCV_DISPATCH_SLOT) return; - this->ModifyOrder(this->OrderGetSel(), MOF_COND_COMPARATOR | ((index & 1) ? OCC_IS_FALSE : OCC_IS_TRUE) << 8); - this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE_2 | ((o->GetConditionValue() & 2) | ((index & 2) >> 1)) << 8); + case WID_O_COND_COMPARATOR: { + const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); + if (o == nullptr) return; + if (o->GetConditionVariable() == OCV_DISPATCH_SLOT) { + this->ModifyOrder(this->OrderGetSel(), MOF_COND_COMPARATOR | (index >> 16) << 8); + this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE | ((o->GetConditionValue() & GetBitMaskSC(ODCB_LAST_DISPATCHED, 1)) | (index & 0xFFFF)) << 8); } else { this->ModifyOrder(this->OrderGetSel(), MOF_COND_COMPARATOR | index << 8); } break; + } case WID_O_COND_CARGO: this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE | index << 8); @@ -3331,14 +3415,15 @@ public: break; case WID_O_COND_SCHED_SELECT: - this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE | index << 8); + this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE_2 | index << 8); break; case WID_O_COND_SCHED_TEST: { const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); if (o == nullptr) return; - index = (index * 2) | (o->GetConditionValue() & 1); - this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE_2 | index << 8); + const uint16_t last = GetBitMaskSC(ODCB_LAST_DISPATCHED, 1); + index = (index != 0 ? last : 0) | (o->GetConditionValue() & ~last); + this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE | index << 8); break; } diff --git a/src/order_type.h b/src/order_type.h index ca2acd7d91..0c6626d304 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -268,12 +268,24 @@ enum OrderTimetableConditionMode { OTCM_END }; -enum OrderScheduledDispatchSlotConditionMode { - OSDSCM_NEXT_FIRST = 0, ///< Test if next departure is first slot - OSDSCM_NEXT_LAST = 1, ///< Test if next departure is last slot - OSDSCM_LAST_FIRST = 2, ///< Test if last departure was first slot - OSDSCM_LAST_LAST = 3, ///< Test if last departure was last slot - OSDSCM_END +enum OrderDispatchConditionBits { + ODCB_LAST_DISPATCHED = 1, + ODCB_MODE_START = 8, + ODCB_MODE_COUNT = 3, +}; + +enum OrderDispatchConditionModes : uint8_t { + ODCM_FIRST_LAST = 0, + OCDM_TAG = 1, +}; + +enum OrderDispatchFirstLastConditionBits { + ODFLCB_LAST_SLOT = 0, +}; + +enum OrderDispatchTagConditionBits { + ODFLCB_TAG_START = 4, + ODFLCB_TAG_COUNT = 2, }; /** diff --git a/src/schdispatch_cmd.cpp b/src/schdispatch_cmd.cpp index a31b7f931a..3657a05445 100644 --- a/src/schdispatch_cmd.cpp +++ b/src/schdispatch_cmd.cpp @@ -667,7 +667,7 @@ CommandCost CmdScheduledDispatchSetSlotFlags(TileIndex tile, DoCommandFlag flags uint16_t values = (uint16_t)GB(p3, 0, 16); uint16_t mask = (uint16_t)GB(p3, 16, 16); - const uint16_t permitted_mask = (1 << DispatchSlot::SDSF_REUSE_SLOT); + const uint16_t permitted_mask = GetBitMaskSC(DispatchSlot::SDSF_REUSE_SLOT, 1) | GetBitMaskFL(DispatchSlot::SDSF_FIRST_TAG, DispatchSlot::SDSF_LAST_TAG); if ((mask & permitted_mask) != mask) return CMD_ERROR; if ((values & (~mask)) != 0) return CMD_ERROR; diff --git a/src/schdispatch_gui.cpp b/src/schdispatch_gui.cpp index 3942fd96e7..5c56e4dfb2 100644 --- a/src/schdispatch_gui.cpp +++ b/src/schdispatch_gui.cpp @@ -216,10 +216,6 @@ struct SchdispatchWindow : GeneralVehicleWindow { SCH_MD_REUSE_DEPARTURE_SLOTS, }; - enum SlotManagementDropdown { - SCH_SMD_REUSE_DEPARTURE_SLOT, - }; - SchdispatchWindow(WindowDesc *desc, WindowNumber window_number) : GeneralVehicleWindow(desc, Vehicle::Get(window_number)) @@ -451,6 +447,11 @@ struct SchdispatchWindow : GeneralVehicleWindow { case WID_SCHDISPATCH_MANAGE_SLOT: { _temp_special_strings[0] = GetString(STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_SLOT_TOOLTIP); + auto add_suffix = [&](StringID str) { + SetDParam(0, str); + _temp_special_strings[0] += GetString(STR_SCHDISPATCH_MANAGE_TOOLTIP_SUFFIX); + }; + add_suffix(STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_TAG_TOOLTIP); GuiShowTooltips(this, SPECSTR_TEMP_START, close_cond); return true; } @@ -512,6 +513,13 @@ struct SchdispatchWindow : GeneralVehicleWindow { if (HasBit(flags, DispatchSlot::SDSF_REUSE_SLOT)) { _temp_special_strings[0] += GetString(STR_SCHDISPATCH_SLOT_TOOLTIP_REUSE); } + + for (uint8_t flag_bit = DispatchSlot::SDSF_FIRST_TAG; flag_bit <= DispatchSlot::SDSF_LAST_TAG; flag_bit++) { + if (HasBit(flags, flag_bit)) { + SetDParam(0, 1 + flag_bit - DispatchSlot::SDSF_FIRST_TAG); + _temp_special_strings[0] += GetString(STR_SCHDISPATCH_SLOT_TOOLTIP_TAG); + } + } } GuiShowTooltips(this, SPECSTR_TEMP_START, close_cond); } @@ -1033,8 +1041,15 @@ struct SchdispatchWindow : GeneralVehicleWindow { const DispatchSchedule &schedule = this->GetSelectedSchedule(); DropDownList list; - list.push_back(std::make_unique(HasBit(selected_slot->flags, DispatchSlot::SDSF_REUSE_SLOT), - STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_SLOT, SCH_SMD_REUSE_DEPARTURE_SLOT, schedule.GetScheduledDispatchReuseSlots())); + auto add_item = [&](StringID str, uint bit, bool disabled) { + list.push_back(std::make_unique(HasBit(selected_slot->flags, bit), str, bit, disabled)); + }; + add_item(STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_SLOT, DispatchSlot::SDSF_REUSE_SLOT, schedule.GetScheduledDispatchReuseSlots()); + for (uint8_t flag_bit = DispatchSlot::SDSF_FIRST_TAG; flag_bit <= DispatchSlot::SDSF_LAST_TAG; flag_bit++) { + SetDParam(0, 1 + flag_bit - DispatchSlot::SDSF_FIRST_TAG); + add_item(STR_SCHDISPATCH_REUSE_THIS_DEPARTURE_TAG, flag_bit, false); + } + ShowDropDownList(this, std::move(list), -1, WID_SCHDISPATCH_MANAGE_SLOT); break; } @@ -1124,15 +1139,10 @@ struct SchdispatchWindow : GeneralVehicleWindow { const DispatchSlot *selected_slot = this->GetSelectedDispatchSlot(); if (selected_slot == nullptr) break; - switch((SlotManagementDropdown)index) { - case SCH_SMD_REUSE_DEPARTURE_SLOT: { - uint64_t p3 = 0; - SetBit(p3, SCH_SMD_REUSE_DEPARTURE_SLOT + 16); - if (!HasBit(selected_slot->flags, SCH_SMD_REUSE_DEPARTURE_SLOT)) SetBit(p3, SCH_SMD_REUSE_DEPARTURE_SLOT); - DoCommandPEx(0, this->vehicle->index | (this->schedule_index << 20), this->selected_slot, p3, CMD_SCHEDULED_DISPATCH_SET_SLOT_FLAGS | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, nullptr, 0); - break; - } - } + uint64_t p3 = 0; + SetBit(p3, index + 16); + if (!HasBit(selected_slot->flags, index)) SetBit(p3, index); + DoCommandPEx(0, this->vehicle->index | (this->schedule_index << 20), this->selected_slot, p3, CMD_SCHEDULED_DISPATCH_SET_SLOT_FLAGS | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE), nullptr, nullptr, 0); break; } diff --git a/src/sl/extended_ver_sl.cpp b/src/sl/extended_ver_sl.cpp index e8187ba341..4487ad4655 100644 --- a/src/sl/extended_ver_sl.cpp +++ b/src/sl/extended_ver_sl.cpp @@ -105,7 +105,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_INFRA_SHARING, XSCF_NULL, 2, 2, "infra_sharing", nullptr, nullptr, "CPDP" }, { XSLFI_VARIABLE_DAY_LENGTH, XSCF_NULL, 3, 3, "variable_day_length", nullptr, nullptr, nullptr }, { XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr }, - { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 16, 16, "more_cond_orders", nullptr, nullptr, nullptr }, + { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 17, 17, "more_cond_orders", nullptr, nullptr, nullptr }, { XSLFI_EXTRA_LARGE_MAP, XSCF_NULL, 0, 1, "extra_large_map", nullptr, nullptr, nullptr }, { XSLFI_REVERSE_AT_WAYPOINT, XSCF_NULL, 1, 1, "reverse_at_waypoint", nullptr, nullptr, nullptr }, { XSLFI_VEH_LIFETIME_PROFIT, XSCF_NULL, 1, 1, "veh_lifetime_profit", nullptr, nullptr, nullptr },