Scheduled dispatch: Allow tagging departure slots, add to conditional order

pull/642/head
Jonathan G Rennison 4 months ago
parent be469405df
commit 9bea1e3cc3

@ -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}.

@ -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
};
};

@ -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);

@ -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<NWidgetCore>(WID_O_COND_SCHED_TEST)->widget_data = STR_TRACE_RESTRICT_DISPATCH_SLOT_SHORT_NEXT + (order->GetConditionValue() / 2);
this->GetWidget<NWidgetCore>(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<uint16_t>(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<uint16_t>(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<uint16_t>(ODCB_LAST_DISPATCHED, 1);
index = (index != 0 ? last : 0) | (o->GetConditionValue() & ~last);
this->ModifyOrder(this->OrderGetSel(), MOF_COND_VALUE | index << 8);
break;
}

@ -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,
};
/**

@ -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<uint16_t>(DispatchSlot::SDSF_REUSE_SLOT, 1) | GetBitMaskFL<uint16_t>(DispatchSlot::SDSF_FIRST_TAG, DispatchSlot::SDSF_LAST_TAG);
if ((mask & permitted_mask) != mask) return CMD_ERROR;
if ((values & (~mask)) != 0) return CMD_ERROR;

@ -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<DropDownListCheckedItem>(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<DropDownListCheckedItem>(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;
}

@ -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 },

Loading…
Cancel
Save