Move Order::cargo_type_flags into a separately allocated object.

Change savegame format, add a new chunk for cargo_type_flags.
pull/155/head
Jonathan G Rennison 8 years ago
parent 3507b51d9e
commit 871d26098e

@ -28,6 +28,12 @@ typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
extern OrderPool _order_pool;
extern OrderListPool _orderlist_pool;
struct OrderExtraInfo {
uint8 cargo_type_flags[NUM_CARGO]; ///< Load/unload types for each cargo type.
OrderExtraInfo();
};
/* If you change this, keep in mind that it is saved on 3 places:
* - Load_ORDR, all the global orders
* - Vehicle -> current_order
@ -38,6 +44,8 @@ private:
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles.
friend void Load_VEHS(); ///< Loading of ancient vehicles.
friend const struct SaveLoad *GetOrderDescription(); ///< Saving and loading of orders.
friend void Load_ORDX(); ///< Saving and loading of orders.
friend void Save_ORDX(); ///< Saving and loading of orders.
uint8 type; ///< The type of order + non-stop flags
uint8 flags; ///< Load/unload types, depot order/action types.
@ -45,20 +53,41 @@ private:
CargoID refit_cargo; ///< Refit CargoID
uint8 cargo_type_flags[NUM_CARGO]; ///< Load/unload types for each cargo type.
OrderExtraInfo *extra;///< Extra order info
uint16 wait_time; ///< How long in ticks to wait at the destination.
uint16 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.
void AllocExtraInfo();
void DeAllocExtraInfo();
inline void CheckExtraInfoAlloced()
{
if (!this->extra) this->AllocExtraInfo();
}
public:
Order *next; ///< Pointer to next order. If NULL, end of list
Order() : refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {}
Order() : refit_cargo(CT_NO_REFIT), extra(NULL), max_speed(UINT16_MAX) {}
~Order();
Order(uint32 packed);
Order(const Order& other) : extra(NULL)
{
*this = other;
}
inline Order& operator=(Order const& other)
{
AssignOrder(other);
this->next = other.next;
this->index = other.index;
return *this;
}
/**
* Check whether this order is of the given type.
* @param type the type to check against.
@ -141,7 +170,8 @@ public:
inline OrderLoadFlags GetCargoLoadTypeRaw(CargoID cargo_id) const
{
assert(cargo_id < NUM_CARGO);
return (OrderLoadFlags) GB(this->cargo_type_flags[cargo_id], 4, 4);
if (!this->extra) return OLF_LOAD_IF_POSSIBLE;
return (OrderLoadFlags) GB(this->extra->cargo_type_flags[cargo_id], 4, 4);
}
/**
@ -169,7 +199,8 @@ public:
inline OrderUnloadFlags GetCargoUnloadTypeRaw(CargoID cargo_id) const
{
assert(cargo_id < NUM_CARGO);
return (OrderUnloadFlags) GB(this->cargo_type_flags[cargo_id], 0, 4);
if (!this->extra) return OUF_UNLOAD_IF_POSSIBLE;
return (OrderUnloadFlags) GB(this->extra->cargo_type_flags[cargo_id], 0, 4);
}
/**
@ -214,7 +245,8 @@ public:
inline void SetLoadType(OrderLoadFlags load_type, CargoID cargo_id)
{
assert(cargo_id < NUM_CARGO);
SB(this->cargo_type_flags[cargo_id], 4, 4, load_type);
this->CheckExtraInfoAlloced();
SB(this->extra->cargo_type_flags[cargo_id], 4, 4, load_type);
}
/** Set how the consist must be unloaded. */
@ -229,7 +261,8 @@ public:
inline void SetUnloadType(OrderUnloadFlags unload_type, CargoID cargo_id)
{
assert(cargo_id < NUM_CARGO);
SB(this->cargo_type_flags[cargo_id], 0, 4, unload_type);
this->CheckExtraInfoAlloced();
SB(this->extra->cargo_type_flags[cargo_id], 0, 4, unload_type);
}
/** Set whether we must stop at stations or not. */

@ -48,6 +48,7 @@ INSTANTIATE_POOL_METHODS(OrderList)
/** Clean everything up. */
Order::~Order()
{
DeAllocExtraInfo();
if (CleaningPool()) return;
/* We can visit oil rigs and buoys that are not our own. They will be shown in
@ -68,6 +69,7 @@ void Order::Free()
this->flags = 0;
this->dest = 0;
this->next = NULL;
DeAllocExtraInfo();
}
/**
@ -238,6 +240,7 @@ Order::Order(uint32 packed)
this->type = (OrderType)GB(packed, 0, 8);
this->flags = GB(packed, 8, 8);
this->dest = GB(packed, 16, 16);
this->extra = NULL;
this->next = NULL;
this->refit_cargo = CT_NO_REFIT;
this->wait_time = 0;
@ -284,13 +287,34 @@ void Order::AssignOrder(const Order &other)
this->travel_time = other.travel_time;
this->max_speed = other.max_speed;
if (this->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD || this->GetLoadType() == OLFB_CARGO_TYPE_LOAD) {
for (uint i = 0; i < NUM_CARGO; i++) {
this->cargo_type_flags[i] = other.cargo_type_flags[i];
}
if ((this->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD || this->GetLoadType() == OLFB_CARGO_TYPE_LOAD) && other.extra != NULL) {
this->AllocExtraInfo();
*(this->extra) = *(other.extra);
} else {
this->DeAllocExtraInfo();
}
}
void Order::AllocExtraInfo()
{
if (this->extra == NULL) {
this->extra = new OrderExtraInfo();
}
}
void Order::DeAllocExtraInfo()
{
if (this->extra != NULL) {
delete this->extra;
this->extra = NULL;
}
}
OrderExtraInfo::OrderExtraInfo()
{
memset(cargo_type_flags, 0, sizeof(cargo_type_flags));
}
void CargoStationIDStackSet::FillNextStoppingStation(const Vehicle *v, const OrderList *o, const Order *first, uint hops)
{
this->more.clear();

@ -45,7 +45,7 @@ std::vector<uint32> _sl_xv_discardable_chunk_ids; ///< list of chunks
static const uint32 _sl_xv_slxi_chunk_version = 0; ///< current version os SLXI chunk
const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 1, 1, "cargo_type_orders", NULL, NULL, NULL },
{ XSLFI_CARGO_TYPE_ORDERS, XSCF_NULL, 1, 1, "cargo_type_orders", NULL, NULL, "ORDX" },
{ XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker
};

@ -113,7 +113,6 @@ const SaveLoad *GetOrderDescription()
SLE_CONDVAR(Order, wait_time, SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDVAR(Order, travel_time, SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDVAR(Order, max_speed, SLE_UINT16, 172, SL_MAX_VERSION),
SLE_CONDARR_X(Order, cargo_type_flags, SLE_UINT8, NUM_CARGO, 0, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 1)),
/* Leftover from the minor savegame version stuff
* We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
@ -195,6 +194,39 @@ static void Load_ORDR()
}
}
const SaveLoad *GetOrderExtraInfoDescription()
{
static const SaveLoad _order_extra_info_desc[] = {
SLE_ARR(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO),
SLE_END()
};
return _order_extra_info_desc;
}
void Save_ORDX()
{
Order *order;
FOR_ALL_ORDERS(order) {
if (order->extra != NULL) {
SlSetArrayIndex(order->index);
SlObject(order->extra, GetOrderExtraInfoDescription());
}
}
}
void Load_ORDX()
{
int index;
while ((index = SlIterateArray()) != -1) {
Order *order = Order::GetIfValid(index);
assert(order != NULL);
order->AllocExtraInfo();
SlObject(order->extra, GetOrderExtraInfoDescription());
}
}
static void Ptrs_ORDR()
{
/* Orders from old savegames have pointers corrected in Load_ORDR */
@ -309,5 +341,6 @@ static void Ptrs_BKOR()
extern const ChunkHandler _order_chunk_handlers[] = {
{ 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, NULL, CH_ARRAY},
{ 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, NULL, CH_ARRAY},
{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, NULL, CH_ARRAY | CH_LAST},
{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, NULL, CH_ARRAY},
{ 'ORDX', Save_ORDX, Load_ORDX, NULL, NULL, CH_SPARSE_ARRAY | CH_LAST},
};

Loading…
Cancel
Save