diff --git a/src/lang/english.txt b/src/lang/english.txt index 2c8c5f6d5c..f8e579d5e6 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -4877,6 +4877,7 @@ STR_ORDERS_SKIP_TOOLTIP :{BLACK}Skip the STR_ORDERS_MANAGE_LIST :{BLACK}Manage List STR_ORDERS_MANAGE_LIST_TOOLTIP :{BLACK}Manage this order list STR_ORDER_REVERSE_ORDER_LIST :Reverse order list +STR_ORDER_APPEND_REVERSED_ORDER_LIST :Append reversed order list STR_ORDERS_DELETE_BUTTON :{BLACK}Delete STR_ORDERS_DELETE_TOOLTIP :{BLACK}Delete the highlighted order diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 164b423bbe..ff25d151ac 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1578,7 +1578,9 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * @param tile unused * @param flags operation to perform * @param p1 the ID of the vehicle - * @param p2 unused + * @param p2 subcommand + * 0: reverse whole order list + * 1: append reversed order list * @param text unused * @return the cost of this operation or an error */ @@ -1590,12 +1592,53 @@ CommandCost CmdReverseOrderList(TileIndex tile, DoCommandFlag flags, uint32 p1, if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; uint order_count = v->GetNumOrders(); - if (order_count < 2) return CMD_ERROR; - uint max_order = order_count - 1; - for (uint i = 0; i < max_order; i++) { - CommandCost cost = DoCommand(tile, p1, max_order | (i << 16), flags, CMD_MOVE_ORDER); - if (cost.Failed()) return cost; + switch (p2) { + case 0: { + if (order_count < 2) return CMD_ERROR; + uint max_order = order_count - 1; + for (uint i = 0; i < max_order; i++) { + CommandCost cost = DoCommand(tile, p1, max_order | (i << 16), flags, CMD_MOVE_ORDER); + if (cost.Failed()) return cost; + } + break; + } + + case 1: { + if (order_count < 3) return CMD_ERROR; + uint max_order = order_count - 1; + if (((order_count * 2) - 2) > MAX_VEH_ORDER_ID) return_cmd_error(STR_ERROR_TOO_MANY_ORDERS); + if (!Order::CanAllocateItem(order_count - 2)) return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); + for (uint i = 0; i < order_count; i++) { + if (v->GetOrder(i)->IsType(OT_CONDITIONAL)) return CMD_ERROR; + } + for (uint i = 1; i < max_order; i++) { + Order new_order; + new_order.AssignOrder(*v->GetOrder(i)); + const bool wait_fixed = new_order.IsWaitFixed(); + const bool wait_timetabled = wait_fixed && new_order.IsWaitTimetabled(); + new_order.SetWaitTimetabled(false); + new_order.SetTravelTimetabled(false); + new_order.SetTravelTime(0); + new_order.SetTravelFixed(false); + CommandCost cost = CmdInsertOrderIntl(flags, v, order_count, new_order, true); + if (cost.Failed()) return cost; + if (flags & DC_EXEC) { + Order *order = v->orders.list->GetOrderAt(order_count); + order->SetRefit(new_order.GetRefitCargo()); + order->SetMaxSpeed(new_order.GetMaxSpeed()); + if (wait_fixed) { + extern void SetOrderFixedWaitTime(Vehicle *v, VehicleOrderID order_number, uint32 wait_time, bool wait_timetabled); + SetOrderFixedWaitTime(v, order_count, new_order.GetWaitTime(), wait_timetabled); + } + } + new_order.Free(); + } + break; + }; + + default: + return CMD_ERROR; } return CommandCost(); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 25f27a2d4c..ddc38d41ba 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -633,6 +633,7 @@ static const StringID _order_goto_dropdown_aircraft[] = { static const StringID _order_manage_list_dropdown[] = { STR_ORDER_REVERSE_ORDER_LIST, + STR_ORDER_APPEND_REVERSED_ORDER_LIST, INVALID_STRING_ID }; @@ -1527,9 +1528,9 @@ private: /** * Handle the click on the reverse order list button. */ - void OrderClick_ReverseOrderList() + void OrderClick_ReverseOrderList(uint subcommand) { - DoCommandP(this->vehicle->tile, this->vehicle->index, 0, CMD_REVERSE_ORDER_LIST | CMD_MSG(STR_ERROR_CAN_T_MOVE_THIS_ORDER)); + DoCommandP(this->vehicle->tile, this->vehicle->index, subcommand, CMD_REVERSE_ORDER_LIST | CMD_MSG(STR_ERROR_CAN_T_MOVE_THIS_ORDER)); } /** Cache auto-refittability of the vehicle chain. */ @@ -2195,7 +2196,14 @@ public: break; case WID_O_MANAGE_LIST: { - uint disabled_mask = (this->vehicle->GetNumOrders() < 2 ? 1 : 0); + uint disabled_mask = (this->vehicle->GetNumOrders() < 2 ? 1 : 0) | (this->vehicle->GetNumOrders() < 3 ? 2 : 0); + uint order_count = this->vehicle->GetNumOrders(); + for (uint i = 0; i < order_count; i++) { + if (this->vehicle->GetOrder(i)->IsType(OT_CONDITIONAL)) { + disabled_mask |= 2; + break; + } + } ShowDropDownMenu(this, _order_manage_list_dropdown, -1, WID_O_MANAGE_LIST, disabled_mask, 0, 0, DDSF_LOST_FOCUS); break; } @@ -2512,7 +2520,8 @@ public: case WID_O_MANAGE_LIST: switch (index) { - case 0: this->OrderClick_ReverseOrderList(); break; + case 0: this->OrderClick_ReverseOrderList(0); break; + case 1: this->OrderClick_ReverseOrderList(1); break; default: NOT_REACHED(); } break;