diff --git a/src/lang/english.txt b/src/lang/english.txt index 00ab6a6382..9002486a46 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4567,6 +4567,7 @@ STR_ORDER_CONDITIONAL_ACCEPTANCE_DROPDOWN :Accepted cargo STR_ORDER_CONDITIONAL_FREE_PLATFORMS :Free platforms STR_ORDER_CONDITIONAL_PERCENT :Percent of times STR_ORDER_CONDITIONAL_SLOT_OCCUPANCY :Slot occupancy +STR_ORDER_CONDITIONAL_TRAIN_IN_SLOT :Train in slot STR_ORDER_CONDITIONAL_REQUIRES_SERVICE_ORDER :Requires service {STRING} STR_ORDER_CONDITIONAL_CARGO_WAITING_ORDER :Next station {STRING} {STRING} waiting @@ -4601,6 +4602,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_TRAIN_IN_SLOT :train is in +STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_SLOT :train is not in 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 @@ -4713,6 +4716,8 @@ STR_ORDER_CONDITIONAL_NUM :Jump to order { STR_ORDER_CONDITIONAL_CARGO :Jump to order {COMMA} when {STRING} {STRING} {STRING} STR_ORDER_CONDITIONAL_SLOT :Jump to order {COMMA} when {TRSLOT} {STRING} STR_ORDER_CONDITIONAL_INVALID_SLOT :Jump to order {COMMA} when {PUSH_COLOUR}{RED}{STRING} {POP_COLOUR}{STRING} +STR_ORDER_CONDITIONAL_IN_SLOT :Jump to order {COMMA} when {STRING} slot: {TRSLOT} +STR_ORDER_CONDITIONAL_IN_INVALID_SLOT :Jump to order {COMMA} when {STRING} {PUSH_COLOUR}{RED}{STRING} {POP_COLOUR} STR_ORDER_CONDITIONAL_TRUE_FALSE :Jump to order {COMMA} when {STRING} {STRING} STR_INVALID_ORDER :{RED} (Invalid Order) diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 516fd276a2..4a566d3d0b 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1004,7 +1004,8 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 OrderConditionComparator occ = new_order.GetConditionComparator(); if (occ >= OCC_END) return CMD_ERROR; switch (new_order.GetConditionVariable()) { - case OCV_SLOT_OCCUPANCY: { + case OCV_SLOT_OCCUPANCY: + case OCV_TRAIN_IN_SLOT: { 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; @@ -1581,6 +1582,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case MOF_COND_VARIABLE: if (data == OCV_FREE_PLATFORMS && v->type != VEH_TRAIN) return CMD_ERROR; if (data == OCV_SLOT_OCCUPANCY && v->type != VEH_TRAIN) return CMD_ERROR; + if (data == OCV_TRAIN_IN_SLOT && v->type != VEH_TRAIN) return CMD_ERROR; if (data >= OCV_END) return CMD_ERROR; break; @@ -1595,6 +1597,7 @@ 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; @@ -1617,6 +1620,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 break; case OCV_SLOT_OCCUPANCY: + case OCV_TRAIN_IN_SLOT: if (data != INVALID_TRACE_RESTRICT_SLOT_ID && !TraceRestrictSlot::IsValidID(data)) return CMD_ERROR; break; @@ -1707,7 +1711,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case MOF_COND_VARIABLE: { /* Check whether old conditional variable had a cargo as value */ bool old_var_was_cargo = (order->GetConditionVariable() == OCV_CARGO_ACCEPTANCE || order->GetConditionVariable() == OCV_CARGO_WAITING); - bool old_var_was_slot = (order->GetConditionVariable() == OCV_SLOT_OCCUPANCY); + bool old_var_was_slot = (order->GetConditionVariable() == OCV_SLOT_OCCUPANCY || order->GetConditionVariable() == OCV_TRAIN_IN_SLOT); order->SetConditionVariable((OrderConditionVariable)data); OrderConditionComparator occ = order->GetConditionComparator(); @@ -1718,6 +1722,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 break; case OCV_SLOT_OCCUPANCY: + case OCV_TRAIN_IN_SLOT: if (!old_var_was_slot) order->GetXDataRef() = INVALID_TRACE_RESTRICT_SLOT_ID; if (occ != OCC_IS_TRUE && occ != OCC_IS_FALSE) order->SetConditionComparator(OCC_IS_TRUE); break; @@ -1756,6 +1761,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case MOF_COND_VALUE: switch (order->GetConditionVariable()) { case OCV_SLOT_OCCUPANCY: + case OCV_TRAIN_IN_SLOT: order->GetXDataRef() = data; break; @@ -2425,6 +2431,11 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v) if (slot != nullptr) skip_order = OrderConditionCompare(occ, slot->occupants.size() >= slot->max_occupancy, value); 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); + break; + } case OCV_FREE_PLATFORMS: { StationID next_station = GetNextRealStation(v, order); if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, GetFreeStationPlatforms(next_station), value); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index aa124da44f..6044188ad3 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -606,6 +606,7 @@ static const OrderConditionVariable _order_conditional_variable[] = { OCV_CARGO_ACCEPTANCE, OCV_FREE_PLATFORMS, OCV_SLOT_OCCUPANCY, + OCV_TRAIN_IN_SLOT, OCV_PERCENT, OCV_UNCONDITIONALLY, }; @@ -658,6 +659,18 @@ static const StringID _order_conditional_condition_is_fully_occupied[] = { INVALID_STRING_ID, }; +static const StringID _order_conditional_condition_is_in_slot[] = { + STR_NULL, + STR_NULL, + STR_NULL, + STR_NULL, + STR_NULL, + STR_NULL, + STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_IN_SLOT, + STR_ORDER_CONDITIONAL_COMPARATOR_TRAIN_NOT_IN_SLOT, + INVALID_STRING_ID, +}; + extern uint ConvertSpeedToDisplaySpeed(uint speed); extern uint ConvertDisplaySpeedToSpeed(uint speed); @@ -854,6 +867,15 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int 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); + } else if (ocv == OCV_TRAIN_IN_SLOT) { + if (TraceRestrictSlot::IsValidID(order->GetXData())) { + SetDParam(0, STR_ORDER_CONDITIONAL_IN_SLOT); + SetDParam(3, order->GetXData()); + } else { + 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); } else { OrderConditionComparator occ = order->GetConditionComparator(); bool is_cargo = ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING; @@ -1147,6 +1169,9 @@ private: case OCV_SLOT_OCCUPANCY: return _order_conditional_condition_is_fully_occupied; + case OCV_TRAIN_IN_SLOT: + return _order_conditional_condition_is_in_slot; + default: return _order_conditional_condition; } @@ -1685,7 +1710,7 @@ public: OrderConditionVariable ocv = (order == nullptr) ? OCV_LOAD_PERCENTAGE : order->GetConditionVariable(); bool is_cargo = (ocv == OCV_CARGO_ACCEPTANCE || ocv == OCV_CARGO_WAITING); - bool is_slot_occupancy = (ocv == OCV_SLOT_OCCUPANCY); + bool is_slot_occupancy = (ocv == OCV_SLOT_OCCUPANCY || ocv == OCV_TRAIN_IN_SLOT); if (is_cargo) { if (order == NULL || !CargoSpec::Get(order->GetConditionValue())->IsValid()) { @@ -2083,7 +2108,8 @@ public: (cond_var == OCV_REQUIRES_SERVICE || cond_var == OCV_CARGO_ACCEPTANCE || cond_var == OCV_CARGO_WAITING || - cond_var == OCV_SLOT_OCCUPANCY) ? 0x3F : 0xC0, 0, DDSF_LOST_FOCUS); + cond_var == OCV_SLOT_OCCUPANCY || + cond_var == OCV_TRAIN_IN_SLOT) ? 0x3F : 0xC0, 0, DDSF_LOST_FOCUS); break; } diff --git a/src/order_type.h b/src/order_type.h index 8e5371e327..e55fd4be13 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -147,6 +147,7 @@ enum OrderConditionVariable { OCV_FREE_PLATFORMS, ///< Skip based on free platforms at next station OCV_PERCENT, ///< Skip xx percent of times OCV_SLOT_OCCUPANCY, ///< Test if train slot is fully occupied + OCV_TRAIN_IN_SLOT, ///< Test if train is in slot OCV_END }; diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 11e815cc20..37ac2030ec 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -49,7 +49,7 @@ static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_TRACE_RESTRICT, XSCF_NULL, 9, 9, "tracerestrict", NULL, NULL, "TRRM,TRRP,TRRS" }, { XSLFI_TRACE_RESTRICT_OWNER, XSCF_NULL, 1, 1, "tracerestrict_owner", NULL, NULL, NULL }, - { XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 1, 1, "tracerestrict_order_cond", NULL, NULL, NULL }, + { XSLFI_TRACE_RESTRICT_ORDRCND, XSCF_NULL, 2, 2, "tracerestrict_order_cond", NULL, NULL, NULL }, { XSLFI_TRACE_RESTRICT_STATUSCND,XSCF_NULL, 1, 1, "tracerestrict_status_cond", NULL, NULL, NULL }, { XSLFI_PROG_SIGS, XSCF_NULL, 1, 1, "programmable_signals", NULL, NULL, "SPRG" }, { XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", NULL, NULL, NULL }, diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 9f1b895dd5..18c986905b 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -1736,7 +1736,9 @@ void TraceRestrictRemoveSlotID(TraceRestrictSlotID index) bool changed_order = false; Order *o; FOR_ALL_ORDERS(o) { - if (o->IsType(OT_CONDITIONAL) && o->GetConditionVariable() == OCV_SLOT_OCCUPANCY && o->GetXData() == index) { + if (o->IsType(OT_CONDITIONAL) && + (o->GetConditionVariable() == OCV_SLOT_OCCUPANCY || o->GetConditionVariable() == OCV_TRAIN_IN_SLOT) && + o->GetXData() == index) { o->GetXDataRef() = INVALID_TRACE_RESTRICT_SLOT_ID; changed_order = true; }