Extend Order::flags to 16 bits, fixes conditional order target field size

Adjust order packing and CmdInsertOrder

See: #198
This commit is contained in:
Jonathan G Rennison
2020-10-17 15:21:38 +01:00
parent b9f7db9c7e
commit e1aca1ab34
8 changed files with 40 additions and 25 deletions

View File

@@ -70,16 +70,16 @@ private:
friend void Load_VEOX(); ///< Saving and loading of orders. friend void Load_VEOX(); ///< Saving and loading of orders.
friend void Save_VEOX(); ///< Saving and loading of orders. friend void Save_VEOX(); ///< Saving and loading of orders.
uint8 type; ///< The type of order + non-stop flags std::unique_ptr<OrderExtraInfo> extra; ///< Extra order info
uint8 flags; ///< Load/unload types, depot order/action types.
uint16 flags; ///< Load/unload types, depot order/action types.
DestinationID dest; ///< The destination of the order. DestinationID dest; ///< The destination of the order.
uint8 type; ///< The type of order + non-stop flags
CargoID refit_cargo; ///< Refit CargoID 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% uint8 occupancy; ///< Estimate of vehicle occupancy on departure, for the current order, 0 indicates invalid, 1 - 101 indicate 0 - 100%
std::unique_ptr<OrderExtraInfo> extra; ///< Extra order info
TimetableTicks wait_time; ///< How long in ticks to wait at the destination. 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. 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. 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() : flags(0), refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {}
~Order(); ~Order();
Order(uint32 packed); Order(uint64 packed);
Order(const Order& other) Order(const Order& other)
{ {
@@ -504,7 +504,7 @@ public:
void AssignOrder(const Order &other); void AssignOrder(const Order &other);
bool Equals(const Order &other) const; bool Equals(const Order &other) const;
uint32 Pack() const; uint64 Pack() const;
uint16 MapOldOrder() const; uint16 MapOldOrder() const;
void ConvertFromOldSavegame(); void ConvertFromOldSavegame();
}; };

View File

@@ -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. * the type, flags and destination.
* @return the packed representation. * @return the packed representation.
* @note unpacking is done in the constructor. * @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. * Create an order based on a packed representation of that order.
* @param packed the packed representation. * @param packed the packed representation.
*/ */
Order::Order(uint32 packed) Order::Order(uint64 packed)
{ {
this->type = (OrderType)GB(packed, 0, 8); this->type = (OrderType)GB(packed, 0, 8);
this->flags = GB(packed, 8, 8); this->flags = GB(packed, 8, 16);
this->dest = GB(packed, 16, 16); this->dest = GB(packed, 24, 16);
this->extra = nullptr; this->extra = nullptr;
this->next = nullptr; this->next = nullptr;
this->refit_cargo = CT_NO_REFIT; 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 flags operation to perform
* @param p1 various bitstuffed elements * @param p1 various bitstuffed elements
* - p1 = (bit 0 - 19) - ID of the vehicle * - p1 = (bit 0 - 19) - ID of the vehicle
* @param p2 packed order to insert * @param p2 various bitstuffed elements
* @param p3 various bitstuffed elements * - p2 = (bit 0 - 15) - the selected order (if any). If the last order is given,
* - p3 = (bit 0 - 15) - the selected order (if any). If the last order is given,
* the order will be inserted before that one * the order will be inserted before that one
* @param p3 packed order to insert
* @param text unused * @param text unused
* @return the cost of this operation or an error * @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) CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, uint64 p3, const char *text, uint32 binary_length)
{ {
VehicleID veh = GB(p1, 0, 20); VehicleID veh = GB(p1, 0, 20);
VehicleOrderID sel_ord = GB(p3, 0, 16); VehicleOrderID sel_ord = GB(p2, 0, 16);
Order new_order(p2); Order new_order(p3);
return CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false); return CmdInsertOrderIntl(flags, Vehicle::GetIfValid(veh), sel_ord, new_order, false);
} }

View File

@@ -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) bool ModifyOrder(VehicleOrderID sel_ord, uint32 p2, bool error_msg = true)

View File

@@ -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_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_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_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 { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
}; };

View File

@@ -89,6 +89,7 @@ enum SlXvFeatureIndex {
XSLFI_LOCAL_COMPANY, ///< Local company ID XSLFI_LOCAL_COMPANY, ///< Local company ID
XSLFI_THROUGH_TRAIN_DEPOT, ///< Drive-through train depots XSLFI_THROUGH_TRAIN_DEPOT, ///< Drive-through train depots
XSLFI_MORE_VEHICLE_ORDERS, ///< More vehicle orders - VehicleOrderID is 16 bits instead of 8 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_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 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

View File

@@ -82,7 +82,17 @@ void Order::ConvertFromOldSavegame()
*/ */
static Order UnpackVersion4Order(uint16 packed) 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[] = { static const SaveLoad _order_desc[] = {
SLE_VAR(Order, type, SLE_UINT8), 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_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)),
SLE_VAR(Order, dest, SLE_UINT16), SLE_VAR(Order, dest, SLE_UINT16),
SLE_REF(Order, next, REF_ORDER), SLE_REF(Order, next, REF_ORDER),
@@ -169,7 +180,8 @@ static void Load_ORDR()
SlArray(orders, len, SLE_UINT32); SlArray(orders, len, SLE_UINT32);
for (size_t i = 0; i < len; ++i) { 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); free(orders);

View File

@@ -694,7 +694,8 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
/* Orders for version 5 and on */ /* Orders for version 5 and on */
SLE_CONDVAR(Vehicle, current_order.type, SLE_UINT8, SLV_5, SL_MAX_VERSION), 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), SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, SLV_5, SL_MAX_VERSION),
/* Refit in current order */ /* Refit in current order */

View File

@@ -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))); 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) /* 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 order;
order.MakeConditional(jump_to); 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) /* static */ bool ScriptOrder::RemoveOrder(VehicleID vehicle_id, OrderPosition order_position)