Add try to acquire slot order subtype

pull/642/head
Jonathan G Rennison 5 months ago
parent 2fc631b15b
commit 041f36d565

@ -1636,9 +1636,11 @@ STR_ORDER_APPEND_REVERSED_ORDER_LIST :Append reversed
STR_ORDER_DUPLICATE_ORDER :Duplicate order
STR_ORDER_CHANGE_JUMP_TARGET :Change jump target
STR_ORDER_TRY_ACQUIRE_SLOT_BUTTON :Try acquire slot
STR_ORDER_RELEASE_SLOT_BUTTON :Release slot
STR_ORDER_CHANGE_COUNTER_BUTTON :Change counter
STR_ORDER_RELEASE_SLOT_TOOLTIP :{BLACK}The train slot to release
STR_ORDER_TRY_ACQUIRE_SLOT_TOOLTIP :{BLACK}The train slot to try to acquire
STR_ORDER_CHANGE_COUNTER_TOOLTIP :{BLACK}The counter to change
@ -1706,6 +1708,7 @@ STR_ORDER_CONDITIONAL_TIME_HHMM :Jump to order {
STR_ORDER_CONDITIONAL_TIMETABLE :Jump to order {COMMA} when {STRING} {STRING} {TT_TICKS}
STR_ORDER_CONDITIONAL_DISPATCH_SLOT_DISPLAY :Jump to order {COMMA} when {STRING} {STRING} {STRING}
STR_ORDER_TRY_ACQUIRE_SLOT :Try to acquire slot: {STRING1}
STR_ORDER_RELEASE_SLOT :Release slot: {STRING1}
STR_TIMETABLE_MINUTES :{COMMA}{NBSP}minute{P "" s}

@ -223,6 +223,7 @@ public:
void MakeWaiting();
void MakeLoadingAdvance(StationID destination);
void MakeReleaseSlot();
void MakeTryAcquireSlot();
void MakeChangeCounter();
void MakeLabel(OrderLabelSubType subtype);

@ -247,6 +247,13 @@ void Order::MakeReleaseSlot()
this->flags = OSST_RELEASE;
}
void Order::MakeTryAcquireSlot()
{
this->type = OT_SLOT;
this->dest = INVALID_TRACE_RESTRICT_SLOT_ID;
this->flags = OSST_TRY_ACQUIRE;
}
void Order::MakeChangeCounter()
{
this->type = OT_COUNTER;
@ -1277,6 +1284,7 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s
}
switch (new_order.GetSlotSubType()) {
case OSST_RELEASE:
case OSST_TRY_ACQUIRE:
break;
default:
@ -3070,6 +3078,31 @@ static std::vector<TraceRestrictSlotID> _pco_deferred_slot_releases;
static btree::btree_map<TraceRestrictCounterID, int32_t> _pco_deferred_counter_values;
static btree::btree_map<Order *, int8_t> _pco_deferred_original_percent_cond;
static bool ExecuteVehicleInSlotOrderCondition(VehicleID vehicle, TraceRestrictSlot *slot, ProcessConditionalOrderMode mode, bool acquire)
{
bool occupant = slot->IsOccupant(vehicle);
if (mode == PCO_DEFERRED) {
if (occupant && find_index(_pco_deferred_slot_releases, slot->index) >= 0) {
occupant = false;
} else if (!occupant && find_index(_pco_deferred_slot_acquires, slot->index) >= 0) {
occupant = true;
}
}
if (acquire) {
if (!occupant && mode == PCO_EXEC) {
occupant = slot->Occupy(vehicle);
}
if (!occupant && mode == PCO_DEFERRED) {
occupant = slot->OccupyDryRun(vehicle);
if (occupant) {
include(_pco_deferred_slot_acquires, slot->index);
container_unordered_remove(_pco_deferred_slot_releases, slot->index);
}
}
}
return occupant;
}
/**
* Process a conditional order and determine the next order.
* @param order the order the vehicle currently has
@ -3140,30 +3173,14 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, Pro
break;
}
case OCV_VEH_IN_SLOT: {
TraceRestrictSlotID slot_id = order->GetXData();
TraceRestrictSlot* slot = TraceRestrictSlot::GetIfValid(slot_id);
TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(order->GetXData());
if (slot != nullptr) {
bool occupant = slot->IsOccupant(v->index);
if (mode == PCO_DEFERRED) {
if (occupant && find_index(_pco_deferred_slot_releases, slot_id) >= 0) {
occupant = false;
} else if (!occupant && find_index(_pco_deferred_slot_acquires, slot_id) >= 0) {
occupant = true;
}
}
bool acquire = false;
if (occ == OCC_EQUALS || occ == OCC_NOT_EQUALS) {
if (!occupant && mode == PCO_EXEC) {
occupant = slot->Occupy(v->index);
}
if (!occupant && mode == PCO_DEFERRED) {
occupant = slot->OccupyDryRun(v->index);
if (occupant) {
include(_pco_deferred_slot_acquires, slot_id);
container_unordered_remove(_pco_deferred_slot_releases, slot_id);
}
}
acquire = true;
occ = (occ == OCC_EQUALS) ? OCC_IS_TRUE : OCC_IS_FALSE;
}
bool occupant = ExecuteVehicleInSlotOrderCondition(v->index, slot, mode, acquire);
skip_order = OrderConditionCompare(occ, occupant, value);
}
break;
@ -3254,6 +3271,9 @@ VehicleOrderID AdvanceOrderIndexDeferred(const Vehicle *v, VehicleOrderID index)
include(_pco_deferred_slot_releases, order->GetDestination());
container_unordered_remove(_pco_deferred_slot_acquires, order->GetDestination());
break;
case OSST_TRY_ACQUIRE:
ExecuteVehicleInSlotOrderCondition(v->index, TraceRestrictSlot::Get(order->GetDestination()), PCO_DEFERRED, true);
break;
}
}
break;
@ -3435,6 +3455,9 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
case OSST_RELEASE:
slot->Vacate(v->index);
break;
case OSST_TRY_ACQUIRE:
slot->Occupy(v->index);
break;
}
}
}

@ -618,28 +618,16 @@ static const StringID _order_unload_drowdown[] = {
INVALID_STRING_ID
};
static const StringID _order_goto_dropdown[] = {
STR_ORDER_GO_TO,
STR_ORDER_GO_TO_NEAREST_DEPOT,
STR_ORDER_CONDITIONAL,
STR_ORDER_SHARE,
STR_ORDER_RELEASE_SLOT_BUTTON,
STR_ORDER_CHANGE_COUNTER_BUTTON,
STR_ORDER_LABEL_TEXT_BUTTON,
STR_ORDER_LABEL_DEPARTURES_VIA_BUTTON,
INVALID_STRING_ID
};
static const StringID _order_goto_dropdown_aircraft[] = {
STR_ORDER_GO_TO,
STR_ORDER_GO_TO_NEAREST_HANGAR,
STR_ORDER_CONDITIONAL,
STR_ORDER_SHARE,
STR_ORDER_RELEASE_SLOT_BUTTON,
STR_ORDER_CHANGE_COUNTER_BUTTON,
STR_ORDER_LABEL_TEXT_BUTTON,
STR_ORDER_LABEL_DEPARTURES_VIA_BUTTON,
INVALID_STRING_ID
enum OrderDropDownID {
ODDI_GO_TO,
ODDI_GO_TO_NEAREST_DEPOT,
ODDI_CONDITIONAL,
ODDI_SHARE,
ODDI_TRY_ACQUIRE_SLOT,
ODDI_RELEASE_SLOT,
ODDI_CHANGE_COUNTER,
ODDI_LABEL_TEXT,
ODDI_LABEL_DEPARTURES_VIA,
};
static const StringID _order_manage_list_dropdown[] = {
@ -1175,6 +1163,10 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int
SetDParam(0, STR_ORDER_RELEASE_SLOT);
break;
case OSST_TRY_ACQUIRE:
SetDParam(0, STR_ORDER_TRY_ACQUIRE_SLOT);
break;
default:
NOT_REACHED();
break;
@ -1664,6 +1656,19 @@ private:
this->InsertNewOrder(order.Pack());
}
/**
* Handle the click on the try acquire slot button.
*/
void OrderClick_TryAcquireSlot()
{
Order order;
order.next = nullptr;
order.index = 0;
order.MakeTryAcquireSlot();
this->InsertNewOrder(order.Pack());
}
/**
* Handle the click on the release slot button.
*/
@ -2313,7 +2318,9 @@ public:
TraceRestrictSlotID slot_id = (order != nullptr && TraceRestrictSlot::IsValidID(order->GetDestination()) ? order->GetDestination() : INVALID_TRACE_RESTRICT_SLOT_ID);
this->GetWidget<NWidgetCore>(WID_O_RELEASE_SLOT)->widget_data = (slot_id != INVALID_TRACE_RESTRICT_SLOT_ID) ? STR_TRACE_RESTRICT_SLOT_NAME : STR_TRACE_RESTRICT_VARIABLE_UNDEFINED;
NWidgetCore *slot_widget = this->GetWidget<NWidgetCore>(WID_O_SLOT);
slot_widget->widget_data = (slot_id != INVALID_TRACE_RESTRICT_SLOT_ID) ? STR_TRACE_RESTRICT_SLOT_NAME : STR_TRACE_RESTRICT_VARIABLE_UNDEFINED;
slot_widget->SetToolTip((order != nullptr && order->GetSlotSubType() == OSST_RELEASE) ? STR_ORDER_RELEASE_SLOT_TOOLTIP : STR_ORDER_TRY_ACQUIRE_SLOT_TOOLTIP);
break;
}
@ -2616,7 +2623,7 @@ public:
}
break;
case WID_O_RELEASE_SLOT: {
case WID_O_SLOT: {
VehicleOrderID sel = this->OrderGetSel();
const Order *order = this->vehicle->GetOrder(sel);
@ -2859,32 +2866,37 @@ public:
if (this->goto_type == OPOS_COND_VIA || this->goto_type == OPOS_COND_STATION) ResetObjectToPlace();
int sel;
switch (this->goto_type) {
case OPOS_NONE: sel = -1; break;
case OPOS_GOTO: sel = 0; break;
case OPOS_CONDITIONAL: sel = 2; break;
case OPOS_SHARE: sel = 3; break;
case OPOS_NONE: sel = -1; break;
case OPOS_GOTO: sel = ODDI_GO_TO; break;
case OPOS_CONDITIONAL: sel = ODDI_CONDITIONAL; break;
case OPOS_SHARE: sel = ODDI_SHARE; break;
case OPOS_CONDITIONAL_RETARGET: sel = -1; break;
case OPOS_DEPARTURE_VIA: sel = 7; break;
case OPOS_DEPARTURE_VIA: sel = ODDI_LABEL_DEPARTURES_VIA; break;
default: NOT_REACHED();
}
uint32_t hidden_mask = 0;
bool show_counters = false;
if (_settings_client.gui.show_adv_tracerestrict_features) {
bool have_counters = false;
for (const TraceRestrictCounter *ctr : TraceRestrictCounter::Iterate()) {
if (ctr->owner == this->vehicle->owner) {
have_counters = true;
show_counters = true;
break;
}
}
if (!have_counters) {
// Owner has no counters, don't both showing the menu item
hidden_mask |= 0x20;
}
} else {
hidden_mask |= 0x30;
}
ShowDropDownMenu(this, this->vehicle->type == VEH_AIRCRAFT ? _order_goto_dropdown_aircraft : _order_goto_dropdown, sel, WID_O_GOTO,
0, hidden_mask, 0, DDSF_LOST_FOCUS);
DropDownList list;
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_GO_TO, ODDI_GO_TO, false));
list.push_back(std::make_unique<DropDownListStringItem>((this->vehicle->type == VEH_AIRCRAFT) ? STR_ORDER_GO_TO_NEAREST_HANGAR : STR_ORDER_GO_TO_NEAREST_DEPOT, ODDI_GO_TO_NEAREST_DEPOT, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_CONDITIONAL, ODDI_CONDITIONAL, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_SHARE, ODDI_SHARE, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_TRY_ACQUIRE_SLOT_BUTTON, ODDI_TRY_ACQUIRE_SLOT, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_RELEASE_SLOT_BUTTON, ODDI_RELEASE_SLOT, false));
if (show_counters) {
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_CHANGE_COUNTER_BUTTON, ODDI_CHANGE_COUNTER, false));
}
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_LABEL_TEXT_BUTTON, ODDI_LABEL_TEXT, false));
list.push_back(std::make_unique<DropDownListStringItem>(STR_ORDER_LABEL_DEPARTURES_VIA_BUTTON, ODDI_LABEL_DEPARTURES_VIA, false));
ShowDropDownList(this, std::move(list), sel, WID_O_GOTO, 0, false, DDSF_LOST_FOCUS);
}
break;
@ -3134,11 +3146,11 @@ public:
this->ReInit();
break;
case WID_O_RELEASE_SLOT: {
case WID_O_SLOT: {
int selected;
TraceRestrictSlotID value = this->vehicle->GetOrder(this->OrderGetSel())->GetDestination();
DropDownList list = GetSlotDropDownList(this->vehicle->owner, value, selected, this->vehicle->type, false);
if (!list.empty()) ShowDropDownList(this, std::move(list), selected, WID_O_RELEASE_SLOT, 0);
if (!list.empty()) ShowDropDownList(this, std::move(list), selected, WID_O_SLOT, 0);
break;
}
@ -3258,14 +3270,15 @@ public:
case WID_O_GOTO:
switch (index) {
case 0: this->OrderClick_Goto(OPOS_GOTO); break;
case 1: this->OrderClick_NearestDepot(); break;
case 2: this->OrderClick_Goto(OPOS_CONDITIONAL); break;
case 3: this->OrderClick_Goto(OPOS_SHARE); break;
case 4: this->OrderClick_ReleaseSlot(); break;
case 5: this->OrderClick_ChangeCounter(); break;
case 6: this->OrderClick_TextLabel(); break;
case 7: this->OrderClick_Goto(OPOS_DEPARTURE_VIA); break;
case ODDI_GO_TO: this->OrderClick_Goto(OPOS_GOTO); break;
case ODDI_GO_TO_NEAREST_DEPOT: this->OrderClick_NearestDepot(); break;
case ODDI_CONDITIONAL: this->OrderClick_Goto(OPOS_CONDITIONAL); break;
case ODDI_SHARE: this->OrderClick_Goto(OPOS_SHARE); break;
case ODDI_TRY_ACQUIRE_SLOT: this->OrderClick_TryAcquireSlot(); break;
case ODDI_RELEASE_SLOT: this->OrderClick_ReleaseSlot(); break;
case ODDI_CHANGE_COUNTER: this->OrderClick_ChangeCounter(); break;
case ODDI_LABEL_TEXT: this->OrderClick_TextLabel(); break;
case ODDI_LABEL_DEPARTURES_VIA: this->OrderClick_Goto(OPOS_DEPARTURE_VIA); break;
default: NOT_REACHED();
}
break;
@ -3329,7 +3342,7 @@ public:
break;
}
case WID_O_RELEASE_SLOT:
case WID_O_SLOT:
this->ModifyOrder(this->OrderGetSel(), MOF_SLOT | index << 8);
break;
@ -3723,8 +3736,8 @@ static const NWidgetPart _nested_orders_train_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_RELEASE_SLOT), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_RELEASE_SLOT_TOOLTIP), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_SLOT), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_NULL), SetResize(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_COUNTER_OP), SetMinimalSize(124, 12), SetFill(1, 0),
@ -3868,8 +3881,8 @@ static const NWidgetPart _nested_orders_widgets[] = {
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_RELEASE_SLOT), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_ORDER_RELEASE_SLOT_TOOLTIP), SetResize(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_O_SLOT), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_NULL, STR_NULL), SetResize(1, 0),
EndContainer(),
/* Buttons for changing a counter. */

@ -54,6 +54,7 @@ enum OrderType : byte {
enum OrderSlotSubType : byte {
OSST_RELEASE = 0,
OSST_TRY_ACQUIRE = 1,
};
enum OrderLabelSubType : byte {

@ -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, 15, 15, "more_cond_orders", nullptr, nullptr, nullptr },
{ XSLFI_MORE_COND_ORDERS, XSCF_NULL, 16, 16, "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 },

@ -45,7 +45,7 @@ enum OrderWidgets : WidgetID {
WID_O_COND_AUX_VIA, ///< Condition via button.
WID_O_COND_SCHED_TEST, ///< Choose scheduled dispatch test.
WID_O_COND_AUX_STATION, ///< Condition station button.
WID_O_RELEASE_SLOT, ///< Choose slot to release.
WID_O_SLOT, ///< Choose slot to try acquire/release.
WID_O_COUNTER_OP, ///< Choose counter operation.
WID_O_CHANGE_COUNTER, ///< Choose counter to change.
WID_O_COUNTER_VALUE, ///< Choose counter value.

Loading…
Cancel
Save