diff --git a/src/lang/extra/english.txt b/src/lang/extra/english.txt index 776b19146f..c8cc9d00c6 100644 --- a/src/lang/extra/english.txt +++ b/src/lang/extra/english.txt @@ -1531,6 +1531,8 @@ STR_ORDER_CONDITIONAL_COMPARATOR_HAS_MORE_THAN :has more than STR_ORDER_CONDITIONAL_COMPARATOR_HAS_MORE_EQUALS :has more than or exactly STR_ORDER_CONDITIONAL_COMPARATOR_FULLY_OCCUPIED :is fully occupied STR_ORDER_CONDITIONAL_COMPARATOR_NOT_YET_FULLY_OCCUPIED :is not fully occupied +STR_ORDER_CONDITIONAL_COMPARATOR_OCCUPANCY_EMPTY :is empty +STR_ORDER_CONDITIONAL_COMPARATOR_OCCUPANCY_NOT_EMPTY :is not empty 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 diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 487e3987a0..9b29a9c8e9 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1233,11 +1233,8 @@ CommandCost CmdInsertOrderIntl(DoCommandFlag flags, Vehicle *v, VehicleOrderID s switch (occ) { case OCC_IS_TRUE: case OCC_IS_FALSE: - break; - case OCC_EQUALS: case OCC_NOT_EQUALS: - if (new_order.GetConditionVariable() != OCV_VEH_IN_SLOT) return CMD_ERROR; break; default: @@ -1943,11 +1940,14 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case OCV_REQUIRES_SERVICE: case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_WAITING: - case OCV_SLOT_OCCUPANCY: case OCV_DISPATCH_SLOT: if (data != OCC_IS_TRUE && data != OCC_IS_FALSE) return CMD_ERROR; break; + case OCV_SLOT_OCCUPANCY: + if (data != OCC_IS_TRUE && data != OCC_IS_FALSE && data != OCC_EQUALS && data != OCC_NOT_EQUALS) return CMD_ERROR; + break; + case OCV_VEH_IN_SLOT: { if (data != OCC_IS_TRUE && data != OCC_IS_FALSE && data != OCC_EQUALS && data != OCC_NOT_EQUALS) return CMD_ERROR; const TraceRestrictSlot *slot = TraceRestrictSlot::GetIfValid(order->GetXData()); @@ -2180,6 +2180,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case MOF_COND_VARIABLE: { /* Check whether old conditional variable had a cargo as value */ + OrderConditionVariable old_condition = order->GetConditionVariable(); bool old_var_was_cargo = (order->GetConditionVariable() == OCV_CARGO_ACCEPTANCE || order->GetConditionVariable() == OCV_CARGO_WAITING || order->GetConditionVariable() == OCV_CARGO_LOAD_PERCENTAGE || order->GetConditionVariable() == OCV_CARGO_WAITING_AMOUNT); bool old_var_was_slot = (order->GetConditionVariable() == OCV_SLOT_OCCUPANCY || order->GetConditionVariable() == OCV_VEH_IN_SLOT); @@ -2202,7 +2203,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } else if (order->GetConditionVariable() == OCV_VEH_IN_SLOT && order->GetXData() != INVALID_TRACE_RESTRICT_SLOT_ID && TraceRestrictSlot::Get(order->GetXData())->vehicle_type != v->type) { order->GetXDataRef() = INVALID_TRACE_RESTRICT_SLOT_ID; } - if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE); + if (old_condition != order->GetConditionVariable()) order->SetConditionComparator(OCC_IS_TRUE); break; case OCV_COUNTER_VALUE: @@ -3126,7 +3127,14 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, Pro count++; } } - skip_order = OrderConditionCompare(occ, count >= slot->max_occupancy, value); + bool result; + if (occ == OCC_EQUALS || occ == OCC_NOT_EQUALS) { + occ = (occ == OCC_EQUALS) ? OCC_IS_TRUE : OCC_IS_FALSE; + result = (count == 0); + } else { + result = (count >= slot->max_occupancy); + } + skip_order = OrderConditionCompare(occ, result, value); } break; } diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 2c9cf39b7c..915097da6f 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -707,9 +707,9 @@ static const StringID _order_conditional_condition_accepts[] = { INVALID_STRING_ID, }; -static const StringID _order_conditional_condition_is_fully_occupied[] = { - STR_NULL, - STR_NULL, +static const StringID _order_conditional_condition_occupancy[] = { + STR_ORDER_CONDITIONAL_COMPARATOR_OCCUPANCY_EMPTY, + STR_ORDER_CONDITIONAL_COMPARATOR_OCCUPANCY_NOT_EMPTY, STR_NULL, STR_NULL, STR_NULL, @@ -1009,7 +1009,17 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SetDParam(0, STR_ORDER_CONDITIONAL_INVALID_SLOT); SetDParam(2, STR_TRACE_RESTRICT_VARIABLE_UNDEFINED); } - SetDParam(3, order->GetConditionComparator() == OCC_IS_TRUE ? STR_ORDER_CONDITIONAL_COMPARATOR_FULLY_OCCUPIED : STR_ORDER_CONDITIONAL_COMPARATOR_NOT_YET_FULLY_OCCUPIED); + switch (order->GetConditionComparator()) { + case OCC_IS_TRUE: + case OCC_IS_FALSE: + case OCC_EQUALS: + case OCC_NOT_EQUALS: { + SetDParam(3, _order_conditional_condition_occupancy[order->GetConditionComparator()]); + break; + } + default: + NOT_REACHED(); + } } else if (ocv == OCV_VEH_IN_SLOT) { if (TraceRestrictSlot::IsValidID(order->GetXData())) { SetDParam(0, STR_ORDER_CONDITIONAL_IN_SLOT); @@ -1519,7 +1529,7 @@ private: return _order_conditional_condition_accepts; case OCV_SLOT_OCCUPANCY: - return _order_conditional_condition_is_fully_occupied; + return _order_conditional_condition_occupancy; case OCV_VEH_IN_SLOT: return v->type == VEH_TRAIN ? _order_conditional_condition_is_in_slot : _order_conditional_condition_is_in_slot_non_train; @@ -2965,11 +2975,11 @@ public: case OCV_REQUIRES_SERVICE: case OCV_CARGO_ACCEPTANCE: case OCV_CARGO_WAITING: - case OCV_SLOT_OCCUPANCY: mask = 0x3F; break; case OCV_VEH_IN_SLOT: + case OCV_SLOT_OCCUPANCY: mask = 0x3C; break; diff --git a/src/order_type.h b/src/order_type.h index 8e08d71e46..724daa4391 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -169,7 +169,7 @@ enum OrderConditionVariable { OCV_CARGO_ACCEPTANCE, ///< Skip if specified cargo is accepted at next station OCV_FREE_PLATFORMS, ///< Skip based on free platforms at next station OCV_PERCENT, ///< Skip xx percent of times - OCV_SLOT_OCCUPANCY, ///< Test if vehicle slot is fully occupied + OCV_SLOT_OCCUPANCY, ///< Test if vehicle slot is fully occupied, or empty OCV_VEH_IN_SLOT, ///< Test if vehicle is in slot OCV_CARGO_LOAD_PERCENTAGE, ///< Skip based on the amount of load of a specific cargo OCV_CARGO_WAITING_AMOUNT, ///< Skip based on the amount of a specific cargo waiting at next station diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index edb72755e8..b01aa14183 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -103,7 +103,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, 13, 13, "more_cond_orders", nullptr, nullptr, nullptr }, + { XSLFI_MORE_COND_ORDERS, XSCF_NULL, 14, 14, "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 },