From 0202211514514df14425e0b0367d5d3b3152811b Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 10 May 2020 21:06:09 +0100 Subject: [PATCH] Conditional orders: Add slot acquire modes to train in slot conditional --- src/lang/english.txt | 2 ++ src/order_cmd.cpp | 33 +++++++++++++++++++---- src/order_func.h | 2 +- src/order_gui.cpp | 46 +++++++++++++++++++++++++------- src/saveload/extended_ver_sl.cpp | 2 +- src/train_cmd.cpp | 2 +- 6 files changed, 69 insertions(+), 18 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index e1ff8716b2..d0133c7620 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4758,6 +4758,8 @@ STR_ORDER_CONDITIONAL_COMPARATOR_FULLY_OCCUPIED :is fully occupi STR_ORDER_CONDITIONAL_COMPARATOR_NOT_YET_FULLY_OCCUPIED :is not fully occupied STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_SLOT :train is in STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_SLOT :train is not in +STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_ACQUIRE_SLOT :train is in/acquire +STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_ACQUIRE_SLOT :train is not in/can't acquire STR_ORDERS_SKIP_BUTTON :{BLACK}Skip STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the current order, and start the next. Ctrl+Click skips to the selected order diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index f2eda18a30..bfdee04b46 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1110,7 +1110,19 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s if (v->type != VEH_TRAIN) return CMD_ERROR; TraceRestrictSlotID slot = new_order.GetXData(); if (slot != INVALID_TRACE_RESTRICT_SLOT_ID && !TraceRestrictSlot::IsValidID(slot)) return CMD_ERROR; - if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) return CMD_ERROR; + switch (occ) { + case OCC_IS_TRUE: + case OCC_IS_FALSE: + break; + + case OCC_EQUALS: + case OCC_NOT_EQUALS: + if (new_order.GetConditionVariable() != OCV_TRAIN_IN_SLOT) return CMD_ERROR; + break; + + default: + return CMD_ERROR; + } break; } @@ -1677,10 +1689,13 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_WAITING: case OCV_SLOT_OCCUPANCY: - case OCV_TRAIN_IN_SLOT: if (data != OCC_IS_TRUE && data != OCC_IS_FALSE) return CMD_ERROR; break; + case OCV_TRAIN_IN_SLOT: + if (data != OCC_IS_TRUE && data != OCC_IS_FALSE && data != OCC_EQUALS && data != OCC_NOT_EQUALS) return CMD_ERROR; + break; + default: if (data == OCC_IS_TRUE || data == OCC_IS_FALSE) return CMD_ERROR; break; @@ -2584,9 +2599,10 @@ static StationID GetNextRealStation(const Vehicle *v, const Order *order, int co * Process a conditional order and determine the next order. * @param order the order the vehicle currently has * @param v the vehicle to update + * @param dry_run whether this is a dry-run, so do not execute side-effects * @return index of next order to jump to, or INVALID_VEH_ORDER_ID to use the next order */ -VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v) +VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, bool dry_run) { if (order->GetType() != OT_CONDITIONAL) return INVALID_VEH_ORDER_ID; @@ -2631,8 +2647,15 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v) break; } case OCV_TRAIN_IN_SLOT: { - const TraceRestrictSlot* slot = TraceRestrictSlot::GetIfValid(order->GetXData()); - if (slot != nullptr) skip_order = OrderConditionCompare(occ, slot->IsOccupant(v->index), value); + TraceRestrictSlot* slot = TraceRestrictSlot::GetIfValid(order->GetXData()); + bool occupant = slot->IsOccupant(v->index); + if (occ == OCC_EQUALS || occ == OCC_NOT_EQUALS) { + if (!occupant && !dry_run) { + occupant = slot->Occupy(v->index); + } + occ = (occ == OCC_EQUALS) ? OCC_IS_TRUE : OCC_IS_FALSE; + } + if (slot != nullptr) skip_order = OrderConditionCompare(occ, occupant, value); break; } case OCV_FREE_PLATFORMS: { diff --git a/src/order_func.h b/src/order_func.h index 7faeb08429..88c3a3a2dc 100644 --- a/src/order_func.h +++ b/src/order_func.h @@ -21,7 +21,7 @@ void CheckOrders(const Vehicle*); void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true); bool ProcessOrders(Vehicle *v); bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth = 0, bool pbs_look_ahead = false); -VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v); +VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, bool dry_run = false); uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int conditional_depth = 0); void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int y, bool selected, bool timetable, int left, int middle, int right); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index b208d50bfb..90591c2309 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -663,8 +663,8 @@ static const StringID _order_conditional_condition_is_fully_occupied[] = { }; static const StringID _order_conditional_condition_is_in_slot[] = { - STR_NULL, - STR_NULL, + STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_ACQUIRE_SLOT, + STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_ACQUIRE_SLOT, STR_NULL, STR_NULL, STR_NULL, @@ -878,7 +878,22 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SetDParam(0, STR_ORDER_CONDITIONAL_IN_INVALID_SLOT); SetDParam(3, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED); } - SetDParam(2, order->GetConditionComparator() == OCC_IS_TRUE ? STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_SLOT : STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_SLOT); + switch (order->GetConditionComparator()) { + case OCC_IS_TRUE: + SetDParam(2, STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_SLOT); + break; + case OCC_IS_FALSE: + SetDParam(2, STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_SLOT); + break; + case OCC_EQUALS: + SetDParam(2, STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_ACQUIRE_SLOT); + break; + case OCC_NOT_EQUALS: + SetDParam(2, STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_ACQUIRE_SLOT); + break; + default: + NOT_REACHED(); + } } else if (ocv == OCV_CARGO_LOAD_PERCENTAGE) { SetDParam(0, STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE_DISPLAY); SetDParam(2, CargoSpec::Get(order->GetConditionValue())->name); @@ -2218,13 +2233,24 @@ public: case WID_O_COND_COMPARATOR: { const Order *o = this->vehicle->GetOrder(this->OrderGetSel()); - OrderConditionVariable cond_var = o->GetConditionVariable(); - ShowDropDownMenu(this, GetComparatorStrings(o), o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, - (cond_var == OCV_REQUIRES_SERVICE || - cond_var == OCV_CARGO_ACCEPTANCE || - cond_var == OCV_CARGO_WAITING || - cond_var == OCV_SLOT_OCCUPANCY || - cond_var == OCV_TRAIN_IN_SLOT) ? 0x3F : 0xC0, 0, DDSF_LOST_FOCUS); + uint mask; + switch (o->GetConditionVariable()) { + case OCV_REQUIRES_SERVICE: + case OCV_CARGO_ACCEPTANCE: + case OCV_CARGO_WAITING: + case OCV_SLOT_OCCUPANCY: + mask = 0x3F; + break; + + case OCV_TRAIN_IN_SLOT: + mask = 0x3C; + break; + + default: + mask = 0xC0; + break; + } + ShowDropDownMenu(this, GetComparatorStrings(o), o->GetConditionComparator(), WID_O_COND_COMPARATOR, 0, mask, 0, DDSF_LOST_FOCUS); break; } diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 67d0902d9b..c211f36b99 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -77,7 +77,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, 2, 2, "variable_day_length", nullptr, nullptr, nullptr }, { XSLFI_ORDER_OCCUPANCY, XSCF_NULL, 2, 2, "order_occupancy", nullptr, nullptr, nullptr }, - { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 4, 4, "more_cond_orders", nullptr, nullptr, nullptr }, + { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 5, 5, "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 }, diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 4173d632c3..dd46e96979 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3051,7 +3051,7 @@ public: this->v->current_order = *order; return UpdateOrderDest(this->v, order, 0, true); case OT_CONDITIONAL: { - VehicleOrderID next = ProcessConditionalOrder(order, this->v); + VehicleOrderID next = ProcessConditionalOrder(order, this->v, true); if (next != INVALID_VEH_ORDER_ID) { depth++; this->index = next;