diff --git a/src/order_base.h b/src/order_base.h index 487826360e..49185c34bd 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -70,16 +70,16 @@ private: friend void Load_VEOX(); ///< Saving and loading of orders. friend void Save_VEOX(); ///< Saving and loading of orders. - uint8 type; ///< The type of order + non-stop flags - uint8 flags; ///< Load/unload types, depot order/action types. + std::unique_ptr extra; ///< Extra order info + + uint16 flags; ///< Load/unload types, depot order/action types. DestinationID dest; ///< The destination of the order. + uint8 type; ///< The type of order + non-stop flags CargoID refit_cargo; ///< Refit CargoID uint8 occupancy; ///< Estimate of vehicle occupancy on departure, for the current order, 0 indicates invalid, 1 - 101 indicate 0 - 100% - std::unique_ptr extra; ///< Extra order info - TimetableTicks wait_time; ///< How long in ticks to wait at the destination. TimetableTicks travel_time; ///< How long in ticks the journey to this destination should take. uint16 max_speed; ///< How fast the vehicle may go on the way to the destination. @@ -120,7 +120,7 @@ public: Order() : flags(0), refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {} ~Order(); - Order(uint32 packed); + Order(uint64 packed); Order(const Order& other) { @@ -504,7 +504,7 @@ public: void AssignOrder(const Order &other); bool Equals(const Order &other) const; - uint32 Pack() const; + uint64 Pack() const; uint16 MapOldOrder() const; void ConvertFromOldSavegame(); }; diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 9c92be563a..0f50ca3d80 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -269,14 +269,14 @@ bool Order::Equals(const Order &other) const } /** - * Pack this order into a 32 bits integer, or actually only + * Pack this order into a 64 bits integer, or actually only * the type, flags and destination. * @return the packed representation. * @note unpacking is done in the constructor. */ -uint32 Order::Pack() const +uint64 Order::Pack() const { - return this->dest << 16 | this->flags << 8 | this->type; + return ((uint64) this->dest) << 24 | ((uint64) this->flags) << 8 | ((uint64) this->type); } /** @@ -310,11 +310,11 @@ uint16 Order::MapOldOrder() const * Create an order based on a packed representation of that order. * @param packed the packed representation. */ -Order::Order(uint32 packed) +Order::Order(uint64 packed) { this->type = (OrderType)GB(packed, 0, 8); - this->flags = GB(packed, 8, 8); - this->dest = GB(packed, 16, 16); + this->flags = GB(packed, 8, 16); + this->dest = GB(packed, 24, 16); this->extra = nullptr; this->next = nullptr; this->refit_cargo = CT_NO_REFIT; @@ -943,18 +943,18 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int * @param flags operation to perform * @param p1 various bitstuffed elements * - p1 = (bit 0 - 19) - ID of the vehicle - * @param p2 packed order to insert - * @param p3 various bitstuffed elements - * - p3 = (bit 0 - 15) - the selected order (if any). If the last order is given, + * @param p2 various bitstuffed elements + * - p2 = (bit 0 - 15) - the selected order (if any). If the last order is given, * the order will be inserted before that one + * @param p3 packed order to insert * @param text unused * @return the cost of this operation or an error */ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length) { VehicleID veh = GB(p1, 0, 20); - VehicleOrderID sel_ord = GB(p3, 0, 16); - Order new_order(p2); + VehicleOrderID sel_ord = GB(p2, 0, 16); + Order new_order(p3); return CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false); } diff --git a/src/order_gui.cpp b/src/order_gui.cpp index cd4c2ef790..ba8ebf5afa 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -1290,9 +1290,9 @@ private: } } - bool InsertNewOrder(uint32 order_pack) + bool InsertNewOrder(uint64 order_pack) { - return DoCommandPEx(this->vehicle->tile, this->vehicle->index, order_pack, this->OrderGetSel(), CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), nullptr, nullptr, 0); + return DoCommandPEx(this->vehicle->tile, this->vehicle->index, this->OrderGetSel(), order_pack, CMD_INSERT_ORDER | CMD_MSG(STR_ERROR_CAN_T_INSERT_NEW_ORDER), nullptr, nullptr, 0); } bool ModifyOrder(VehicleOrderID sel_ord, uint32 p2, bool error_msg = true) diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 4c1ff4b20f..71277da019 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -135,6 +135,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_LOCAL_COMPANY, XSCF_IGNORABLE_ALL, 1, 1, "local_company", saveLC, loadLC, nullptr }, { XSLFI_THROUGH_TRAIN_DEPOT, XSCF_NULL, 1, 1, "drive_through_train_depot", nullptr, nullptr, nullptr }, { XSLFI_MORE_VEHICLE_ORDERS, XSCF_NULL, 1, 1, "more_veh_orders", nullptr, nullptr, nullptr }, + { XSLFI_ORDER_FLAGS_EXTRA, XSCF_NULL, 1, 1, "order_flags_extra", nullptr, nullptr, nullptr }, { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index ea841ad5e1..421cbb4765 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -89,6 +89,7 @@ enum SlXvFeatureIndex { XSLFI_LOCAL_COMPANY, ///< Local company ID XSLFI_THROUGH_TRAIN_DEPOT, ///< Drive-through train depots XSLFI_MORE_VEHICLE_ORDERS, ///< More vehicle orders - VehicleOrderID is 16 bits instead of 8 + XSLFI_ORDER_FLAGS_EXTRA, ///< Order flags field extra size XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index da4de36812..952afb2d5f 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -82,7 +82,17 @@ void Order::ConvertFromOldSavegame() */ static Order UnpackVersion4Order(uint16 packed) { - return Order(GB(packed, 8, 8) << 16 | GB(packed, 4, 4) << 8 | GB(packed, 0, 4)); + return Order(((uint64) GB(packed, 8, 8)) << 24 | ((uint64) GB(packed, 4, 4)) << 8 | ((uint64) GB(packed, 0, 4))); +} + +/** + * Unpacks a order from savegames with version 5.1 and lower + * @param packed packed order + * @return unpacked order + */ +static Order UnpackVersion5Order(uint32 packed) +{ + return Order(((uint64) GB(packed, 16, 16)) << 24 | ((uint64) GB(packed, 8, 8)) << 8 | ((uint64) GB(packed, 0, 8))); } /** @@ -107,7 +117,8 @@ const SaveLoad *GetOrderDescription() { static const SaveLoad _order_desc[] = { SLE_VAR(Order, type, SLE_UINT8), - SLE_VAR(Order, flags, SLE_UINT8), + SLE_CONDVAR_X(Order, flags, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_FLAGS_EXTRA, 0, 0)), + SLE_CONDVAR_X(Order, flags, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_FLAGS_EXTRA, 1)), SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)), SLE_VAR(Order, dest, SLE_UINT16), SLE_REF(Order, next, REF_ORDER), @@ -169,7 +180,8 @@ static void Load_ORDR() SlArray(orders, len, SLE_UINT32); for (size_t i = 0; i < len; ++i) { - new (i) Order(orders[i]); + Order *o = new (i) Order(); + o->AssignOrder(UnpackVersion5Order(orders[i])); } free(orders); diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 0b1508b531..c81d9eb6d8 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -694,7 +694,8 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) /* Orders for version 5 and on */ SLE_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SLV_5, SL_MAX_VERSION), - SLE_CONDVAR(Vehicle, current_order.flags, SLE_UINT8, SLV_5, SL_MAX_VERSION), + SLE_CONDVAR_X(Vehicle, current_order.flags, SLE_FILE_U8 | SLE_VAR_U16, SLV_5, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_FLAGS_EXTRA, 0, 0)), + SLE_CONDVAR_X(Vehicle, current_order.flags, SLE_UINT16, SLV_5, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_FLAGS_EXTRA, 1)), SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION), /* Refit in current order */ diff --git a/src/script/api/script_order.cpp b/src/script/api/script_order.cpp index 3f08444e2a..ba9c2565c9 100644 --- a/src/script/api/script_order.cpp +++ b/src/script/api/script_order.cpp @@ -509,7 +509,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr order.SetNonStopType((OrderNonStopFlags)(GB(order_flags, 0, 2) | ((_settings_game.order.nonstop_only && ::Vehicle::Get(vehicle_id)->IsGroundVehicle()) ? OF_NON_STOP_INTERMEDIATE : 0))); - return ScriptObject::DoCommandEx(0, vehicle_id, order.Pack(), ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position), CMD_INSERT_ORDER); + return ScriptObject::DoCommandEx(0, vehicle_id, ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position), order.Pack(), CMD_INSERT_ORDER); } /* static */ bool ScriptOrder::InsertConditionalOrder(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to) @@ -524,7 +524,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr Order order; order.MakeConditional(jump_to); - return ScriptObject::DoCommandEx(0, vehicle_id, order.Pack(), ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position), CMD_INSERT_ORDER); + return ScriptObject::DoCommandEx(0, vehicle_id, ScriptOrderPositionToRealOrderPosition(vehicle_id, order_position), order.Pack(), CMD_INSERT_ORDER); } /* static */ bool ScriptOrder::RemoveOrder(VehicleID vehicle_id, OrderPosition order_position)