From 918de7170963faace0bf48a2c8675e4d5a5d3871 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Thu, 1 Feb 2024 11:11:37 -0500 Subject: [PATCH] Change: Prevent unsafe combinations of unbunching orders --- src/lang/english.txt | 8 ++++++++ src/order_cmd.cpp | 30 ++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index b35e934d18abe..7c0ace8cb4828 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -5124,6 +5124,14 @@ STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Unable t STR_ERROR_DEPOT_WRONG_DEPOT_TYPE :Wrong depot type +# Depot unbunching related errors +STR_ERROR_UNBUNCHING_ONLY_ONE_ALLOWED :{WHITE}... can only have one unbunching order +STR_ERROR_UNBUNCHING_NO_FULL_LOAD :{WHITE}... cannot use full load orders when vehicle has an unbunching order +STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD :{WHITE}... cannot unbunch a vehicle with a full load order +STR_ERROR_UNBUNCHING_NO_CONDITIONAL :{WHITE}... cannot use conditional orders when vehicle has an unbunching order +STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL :{WHITE}... cannot unbunch a vehicle with a conditional order +STR_ERROR_UNBUNCHING_MUST_SERVICE :{WHITE}... vehicle must service at the depot to unbunch there + # Autoreplace related errors STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} is too long after replacement STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}No autoreplace/renew rules applied diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 958cb8f12f521..08a39baf4a182 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -743,8 +743,17 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se /* Filter invalid load/unload types. */ switch (new_order.GetLoadType()) { - case OLF_LOAD_IF_POSSIBLE: case OLFB_FULL_LOAD: case OLF_FULL_LOAD_ANY: case OLFB_NO_LOAD: break; - default: return CMD_ERROR; + case OLF_LOAD_IF_POSSIBLE: + case OLFB_NO_LOAD: + break; + + case OLFB_FULL_LOAD: + case OLF_FULL_LOAD_ANY: + if (v->HasUnbunchingOrder()) return_cmd_error(STR_ERROR_UNBUNCHING_NO_FULL_LOAD); + break; + + default: + return CMD_ERROR; } switch (new_order.GetUnloadType()) { case OUF_UNLOAD_IF_POSSIBLE: case OUFB_UNLOAD: case OUFB_TRANSFER: case OUFB_NO_UNLOAD: break; @@ -849,6 +858,7 @@ CommandCost CmdInsertOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se VehicleOrderID skip_to = new_order.GetConditionSkipToOrder(); if (skip_to != 0 && skip_to >= v->GetNumOrders()) return CMD_ERROR; // Always allow jumping to the first (even when there is no order). if (new_order.GetConditionVariable() >= OCV_END) return CMD_ERROR; + if (v->HasUnbunchingOrder()) return_cmd_error(STR_ERROR_UNBUNCHING_NO_CONDITIONAL); OrderConditionComparator occ = new_order.GetConditionComparator(); if (occ >= OCC_END) return CMD_ERROR; @@ -1285,14 +1295,30 @@ CommandCost CmdModifyOrder(DoCommandFlag flags, VehicleID veh, VehicleOrderID se if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return CMD_ERROR; if (data > OLFB_NO_LOAD || data == 1) return CMD_ERROR; if (data == order->GetLoadType()) return CMD_ERROR; + if ((data & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) && v->HasUnbunchingOrder()) return_cmd_error(STR_ERROR_UNBUNCHING_NO_FULL_LOAD); break; case MOF_DEPOT_ACTION: if (data >= DA_END) return CMD_ERROR; + /* The vehicle must always go to the depot (not just if it needs servicing) in order to unbunch there. */ + if ((data & DA_SERVICE) && (order->GetDepotUnbunchingType() & ODUF_UNBUNCH)) return_cmd_error(STR_ERROR_UNBUNCHING_MUST_SERVICE); break; case MOF_DEPOT_UNBUNCHING: if (data > ODUF_UNBUNCH) return CMD_ERROR; + /* Check if we are allowed to add unbunching. We are always allowed to remove it. */ + if (data & ODUF_UNBUNCH) { + /* Only one unbunching order is allowed in a vehicle's orders. */ + if (v->HasUnbunchingOrder()) return_cmd_error(STR_ERROR_UNBUNCHING_ONLY_ONE_ALLOWED); + for (Order *o : v->Orders()) { + /* We don't allow unbunching if the vehicle has a conditional order. */ + if (o->IsType(OT_CONDITIONAL)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_CONDITIONAL); + /* We don't allow unbunching if the vehicle has a full load order. */ + if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) return_cmd_error(STR_ERROR_UNBUNCHING_NO_UNBUNCHING_FULL_LOAD); + /* The vehicle must always go to the depot (not just if it needs servicing) in order to unbunch there. */ + if (o->IsType(OT_GOTO_DEPOT) && o->GetDepotOrderType() & ODTFB_SERVICE) return_cmd_error(STR_ERROR_UNBUNCHING_MUST_SERVICE); + } + } break; case MOF_COND_VARIABLE: