mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Saveload: Use table format for order chunks
This commit is contained in:
parent
a6d0a37386
commit
ce84b8995a
@ -42,7 +42,8 @@ namespace upstream_sl {
|
||||
*/
|
||||
struct OrderBackup : OrderBackupPool::PoolItem<&_order_backup_pool>, BaseConsist {
|
||||
private:
|
||||
friend SaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups.
|
||||
friend NamedSaveLoadTable GetOrderBackupDescription(); ///< Saving and loading of order backups.
|
||||
friend struct OrderBackupDispatchScheduleStructHandler; ///< Saving and loading of order backups.
|
||||
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderBackupDescription(); ///< Saving and loading of order backups.
|
||||
friend void Load_BKOR(); ///< Creating empty orders upon savegame loading.
|
||||
friend void Save_BKOR(); ///< Saving orders upon savegame saving.
|
||||
|
@ -104,12 +104,12 @@ struct Order : OrderPool::PoolItem<&_order_pool> {
|
||||
private:
|
||||
friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< Saving and loading the current order of vehicles.
|
||||
friend void Load_VEHS(); ///< Loading of ancient vehicles.
|
||||
friend SaveLoadTable GetOrderDescription(); ///< Saving and loading of orders.
|
||||
friend NamedSaveLoadTable GetOrderDescription(); ///< Saving and loading of orders.
|
||||
friend struct OrderExtraDataStructHandler; ///< Saving and loading of orders.
|
||||
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderDescription(); ///< Saving and loading of orders.
|
||||
friend upstream_sl::SlVehicleCommon;
|
||||
friend upstream_sl::SlVehicleDisaster;
|
||||
friend void Load_ORDX(); ///< Saving and loading of orders.
|
||||
friend void Save_ORDX(); ///< Saving and loading of orders.
|
||||
friend void Load_VEOX(); ///< Saving and loading of orders.
|
||||
friend void Save_VEOX(); ///< Saving and loading of orders.
|
||||
|
||||
@ -750,7 +750,7 @@ struct DispatchSchedule {
|
||||
static constexpr uint DEPARTURE_TAG_COUNT = 4;
|
||||
|
||||
private:
|
||||
friend SaveLoadTable GetDispatchScheduleDescription(); ///< Saving and loading of dispatch schedules
|
||||
friend NamedSaveLoadTable GetDispatchScheduleDescription(); ///< Saving and loading of dispatch schedules
|
||||
|
||||
std::vector<DispatchSlot> scheduled_dispatch; ///< Scheduled dispatch slots
|
||||
StateTicks scheduled_dispatch_start_tick = -1; ///< Scheduled dispatch start tick
|
||||
@ -891,7 +891,7 @@ static_assert(DispatchSchedule::DEPARTURE_TAG_COUNT == 1 + (DispatchSlot::SDSF_L
|
||||
struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> {
|
||||
private:
|
||||
friend void AfterLoadVehiclesPhase1(bool part_of_load); ///< For instantiating the shared vehicle chain
|
||||
friend SaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists.
|
||||
friend NamedSaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists.
|
||||
friend upstream_sl::SaveLoadTable upstream_sl::GetOrderListDescription(); ///< Saving and loading of order lists.
|
||||
friend void Ptrs_ORDL(); ///< Saving and loading of order lists.
|
||||
|
||||
|
@ -124,7 +124,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_TRAIN_FLAGS_EXTRA, XSCF_NULL, 1, 1, "train_flags_extra", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_VEHICLE_FLAGS_EXTRA, XSCF_NULL, 1, 1, "veh_flags_extra", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_TRAIN_THROUGH_LOAD, XSCF_NULL, 2, 2, "train_through_load", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_ORDER_EXTRA_DATA, XSCF_NULL, 3, 3, "order_extra_data", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_ORDER_EXTRA_DATA, XSCF_NULL, 4, 4, "order_extra_data", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_WHOLE_MAP_CHUNK, XSCF_NULL, 2, 2, "whole_map_chunk", nullptr, nullptr, "WMAP" },
|
||||
{ XSLFI_ST_LAST_VEH_TYPE, XSCF_NULL, 1, 1, "station_last_veh_type", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_SELL_AT_DEPOT_ORDER, XSCF_NULL, 1, 1, "sell_at_depot_order", nullptr, nullptr, nullptr },
|
||||
|
@ -117,41 +117,77 @@ Order UnpackOldOrder(uint16_t packed)
|
||||
return order;
|
||||
}
|
||||
|
||||
SaveLoadTable GetOrderDescription()
|
||||
NamedSaveLoadTable GetOrderExtraInfoDescription()
|
||||
{
|
||||
static const SaveLoad _order_desc[] = {
|
||||
SLE_VAR(Order, type, 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),
|
||||
SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION),
|
||||
SLE_CONDNULL(1, SLV_36, SLV_182), // refit_subtype
|
||||
SLE_CONDVAR_X(Order, occupancy, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_OCCUPANCY)),
|
||||
SLE_CONDVAR_X(Order, wait_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 0, 5)),
|
||||
SLE_CONDVAR_X(Order, wait_time, SLE_UINT32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 6)),
|
||||
SLE_CONDVAR_X(Order, travel_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 0, 5)),
|
||||
SLE_CONDVAR_X(Order, travel_time, SLE_UINT32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 6)),
|
||||
SLE_CONDVAR(Order, max_speed, SLE_UINT16, SLV_172, SL_MAX_VERSION),
|
||||
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_MORE_COND_ORDERS, 1, 6)), // jump_counter
|
||||
static const NamedSaveLoad _order_extra_info_desc[] = {
|
||||
NSL("cargo_type_flags", SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, 32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 1, 2))),
|
||||
NSL("cargo_type_flags", SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 3))),
|
||||
NSL("xflags", SLE_CONDVAR_X(OrderExtraInfo, xflags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA))),
|
||||
NSL("xdata", SLE_CONDVAR_X(OrderExtraInfo, xdata, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA))),
|
||||
NSL("xdata2", SLE_CONDVAR_X(OrderExtraInfo, xdata2, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA, 3))),
|
||||
NSL("dispatch_index", SLE_CONDVAR_X(OrderExtraInfo, dispatch_index, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 3))),
|
||||
NSL("colour", SLE_CONDVAR_X(OrderExtraInfo, colour, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA, 2))),
|
||||
};
|
||||
|
||||
return _order_extra_info_desc;
|
||||
}
|
||||
|
||||
struct OrderExtraDataStructHandler final : public TypedSaveLoadStructHandler<OrderExtraDataStructHandler, Order> {
|
||||
NamedSaveLoadTable GetDescription() const override
|
||||
{
|
||||
return GetOrderExtraInfoDescription();
|
||||
}
|
||||
|
||||
void Save(Order *order) const override
|
||||
{
|
||||
if (!order->extra) return;
|
||||
|
||||
SlObjectSaveFiltered(order->extra.get(), this->GetLoadDescription());
|
||||
}
|
||||
|
||||
void Load(Order *order) const override
|
||||
{
|
||||
order->AllocExtraInfo();
|
||||
SlObjectLoadFiltered(order->extra.get(), this->GetLoadDescription());
|
||||
}
|
||||
};
|
||||
|
||||
NamedSaveLoadTable GetOrderDescription()
|
||||
{
|
||||
static const NamedSaveLoad _order_desc[] = {
|
||||
NSL("type", SLE_VAR(Order, type, SLE_UINT8)),
|
||||
NSL("flags", 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))),
|
||||
NSL("flags", SLE_CONDVAR_X(Order, flags, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_FLAGS_EXTRA, 1))),
|
||||
NSL("", SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP))),
|
||||
NSL("dest", SLE_VAR(Order, dest, SLE_UINT16)),
|
||||
NSL("next", SLE_REF(Order, next, REF_ORDER)),
|
||||
NSL("refit_cargo", SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, SLV_36, SL_MAX_VERSION)),
|
||||
NSL("", SLE_CONDNULL(1, SLV_36, SLV_182)), // refit_subtype
|
||||
NSL("occupancy", SLE_CONDVAR_X(Order, occupancy, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_OCCUPANCY))),
|
||||
NSL("wait_time", SLE_CONDVAR_X(Order, wait_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 0, 5))),
|
||||
NSL("wait_time", SLE_CONDVAR_X(Order, wait_time, SLE_UINT32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 6))),
|
||||
NSL("travel_time", SLE_CONDVAR_X(Order, travel_time, SLE_FILE_U16 | SLE_VAR_U32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 0, 5))),
|
||||
NSL("travel_time", SLE_CONDVAR_X(Order, travel_time, SLE_UINT32, SLV_67, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA, 6))),
|
||||
NSL("max_speed", SLE_CONDVAR(Order, max_speed, SLE_UINT16, SLV_172, SL_MAX_VERSION)),
|
||||
NSL("", SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_MORE_COND_ORDERS, 1, 6))), // jump_counter
|
||||
|
||||
/* 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 */
|
||||
SLE_CONDNULL(10, SLV_5, SLV_36),
|
||||
NSL("", SLE_CONDNULL(10, SLV_5, SLV_36)),
|
||||
|
||||
NSLT_STRUCT<OrderExtraDataStructHandler>("extra"),
|
||||
};
|
||||
|
||||
return _order_desc;
|
||||
}
|
||||
|
||||
static std::vector<SaveLoad> _filtered_desc;
|
||||
|
||||
static void Save_ORDR()
|
||||
{
|
||||
_filtered_desc = SlFilterObject(GetOrderDescription());
|
||||
SaveLoadTableData slt = SlTableHeader(GetOrderDescription());
|
||||
|
||||
for (Order *order : Order::Iterate()) {
|
||||
SlSetArrayIndex(order->index);
|
||||
SlObjectSaveFiltered(order, _filtered_desc);
|
||||
SlObjectSaveFiltered(order, slt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,51 +240,26 @@ static void Load_ORDR()
|
||||
if (prev != nullptr) prev->next = o;
|
||||
}
|
||||
} else {
|
||||
_filtered_desc = SlFilterObject(GetOrderDescription());
|
||||
int index;
|
||||
SaveLoadTableData slt = SlTableHeaderOrRiff(GetOrderDescription());
|
||||
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Order *order = new (index) Order();
|
||||
SlObjectLoadFiltered(order, _filtered_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SaveLoadTable GetOrderExtraInfoDescription()
|
||||
{
|
||||
static const SaveLoad _order_extra_info_desc[] = {
|
||||
SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, 32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 1, 2)),
|
||||
SLE_CONDARR_X(OrderExtraInfo, cargo_type_flags, SLE_UINT8, NUM_CARGO, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_CARGO_TYPE_ORDERS, 3)),
|
||||
SLE_CONDVAR_X(OrderExtraInfo, xflags, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)),
|
||||
SLE_CONDVAR_X(OrderExtraInfo, xdata, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA)),
|
||||
SLE_CONDVAR_X(OrderExtraInfo, xdata2, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA, 3)),
|
||||
SLE_CONDVAR_X(OrderExtraInfo, dispatch_index, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 3)),
|
||||
SLE_CONDVAR_X(OrderExtraInfo, colour, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ORDER_EXTRA_DATA, 2)),
|
||||
};
|
||||
|
||||
return _order_extra_info_desc;
|
||||
}
|
||||
|
||||
void Save_ORDX()
|
||||
{
|
||||
_filtered_desc = SlFilterObject(GetOrderExtraInfoDescription());
|
||||
for (Order *order : Order::Iterate()) {
|
||||
if (order->extra) {
|
||||
SlSetArrayIndex(order->index);
|
||||
SlObjectSaveFiltered(order->extra.get(), _filtered_desc);
|
||||
SlObjectLoadFiltered(order, slt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load_ORDX()
|
||||
{
|
||||
_filtered_desc = SlFilterObject(GetOrderExtraInfoDescription());
|
||||
SaveLoadTableData slt = SlTableHeaderOrRiff(GetOrderExtraInfoDescription());
|
||||
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Order *order = Order::GetIfValid(index);
|
||||
assert(order != nullptr);
|
||||
order->AllocExtraInfo();
|
||||
SlObjectLoadFiltered(order->extra.get(), _filtered_desc);
|
||||
SlObjectLoadFiltered(order->extra.get(), slt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,138 +268,259 @@ static void Ptrs_ORDR()
|
||||
/* Orders from old savegames have pointers corrected in Load_ORDR */
|
||||
if (IsSavegameVersionBefore(SLV_5, 2)) return;
|
||||
|
||||
SaveLoadTableData slt = SlPrepareNamedSaveLoadTableForPtrOrNull(GetOrderDescription());
|
||||
|
||||
for (Order *o : Order::Iterate()) {
|
||||
SlObject(o, GetOrderDescription());
|
||||
SlObjectPtrOrNullFiltered(o, slt);
|
||||
}
|
||||
}
|
||||
|
||||
SaveLoadTable GetDispatchScheduleDescription()
|
||||
NamedSaveLoadTable GetDispatchSlotDescription()
|
||||
{
|
||||
static const SaveLoad _dispatch_scheduled_info_desc[] = {
|
||||
SLEG_CONDVARVEC_X(_old_scheduled_dispatch_slots, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 6)),
|
||||
SLE_VAR(DispatchSchedule, scheduled_dispatch_duration, SLE_UINT32),
|
||||
SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_start_tick, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 4)),
|
||||
SLEG_CONDVAR_X(_old_scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 4)),
|
||||
SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_start_tick, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 5)),
|
||||
SLE_VAR(DispatchSchedule, scheduled_dispatch_last_dispatch, SLE_INT32),
|
||||
SLE_VAR(DispatchSchedule, scheduled_dispatch_max_delay, SLE_INT32),
|
||||
SLE_CONDSSTR_X(DispatchSchedule, name, SLE_STR, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 4)),
|
||||
SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_flags, SLE_FILE_U32 | SLE_VAR_U8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 6)),
|
||||
};
|
||||
|
||||
return _dispatch_scheduled_info_desc;
|
||||
}
|
||||
|
||||
SaveLoadTable GetDispatchSlotDescription()
|
||||
{
|
||||
static const SaveLoad _dispatch_slot_info_desc[] = {
|
||||
SLE_VAR(DispatchSlot, offset, SLE_UINT32),
|
||||
SLE_VAR(DispatchSlot, flags, SLE_UINT16),
|
||||
static const NamedSaveLoad _dispatch_slot_info_desc[] = {
|
||||
NSL("offset", SLE_VAR(DispatchSlot, offset, SLE_UINT32)),
|
||||
NSL("flags", SLE_VAR(DispatchSlot, flags, SLE_UINT16)),
|
||||
};
|
||||
|
||||
return _dispatch_slot_info_desc;
|
||||
}
|
||||
|
||||
SaveLoadTable GetOrderListDescription()
|
||||
struct DispatchSlotStructHandler final : public TypedSaveLoadStructHandler<DispatchSlotStructHandler, DispatchSchedule> {
|
||||
NamedSaveLoadTable GetDescription() const override
|
||||
{
|
||||
return GetDispatchSlotDescription();
|
||||
}
|
||||
|
||||
void Save(DispatchSchedule *ds) const override
|
||||
{
|
||||
SlSetStructListLength(ds->GetScheduledDispatchMutable().size());
|
||||
for (DispatchSlot &slot : ds->GetScheduledDispatchMutable()) {
|
||||
SlObjectSaveFiltered(&slot, this->GetLoadDescription());
|
||||
}
|
||||
}
|
||||
|
||||
void Load(DispatchSchedule *ds) const override
|
||||
{
|
||||
ds->GetScheduledDispatchMutable().resize(SlGetStructListLength(UINT32_MAX));
|
||||
for (DispatchSlot &slot : ds->GetScheduledDispatchMutable()) {
|
||||
SlObjectLoadFiltered(&slot, this->GetLoadDescription());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using DispatchSupplementaryNamePair = std::pair<const uint32_t, std::string>;
|
||||
|
||||
NamedSaveLoadTable GetDispatchSupplementaryNamePairDescription()
|
||||
{
|
||||
static const SaveLoad _orderlist_desc[] = {
|
||||
SLE_REF(OrderList, first, REF_ORDER),
|
||||
SLEG_CONDVAR_X(_jokerpp_separation_mode, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
|
||||
SLE_CONDNULL_X(21, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
|
||||
static const NamedSaveLoad _dispatch_name_pair_desc[] = {
|
||||
NSL("key", SLTAG(SLTAG_CUSTOM_START, SLE_VAR(DispatchSupplementaryNamePair, first, SLE_UINT32))),
|
||||
NSL("value", SLTAG(SLTAG_CUSTOM_START + 1, SLE_SSTR(DispatchSupplementaryNamePair, second, SLE_STR))),
|
||||
};
|
||||
|
||||
return _dispatch_name_pair_desc;
|
||||
}
|
||||
|
||||
struct DispatchNameStructHandler final : public TypedSaveLoadStructHandler<DispatchNameStructHandler, DispatchSchedule> {
|
||||
NamedSaveLoadTable GetDescription() const override
|
||||
{
|
||||
return GetDispatchSupplementaryNamePairDescription();
|
||||
}
|
||||
|
||||
void Save(DispatchSchedule *ds) const override
|
||||
{
|
||||
btree::btree_map<uint32_t, std::string> &names = ds->GetSupplementaryNameMap();
|
||||
SlSetStructListLength(names.size());
|
||||
for (DispatchSupplementaryNamePair &it : names) {
|
||||
SlObjectSaveFiltered(&it, this->GetLoadDescription());
|
||||
}
|
||||
}
|
||||
|
||||
void Load(DispatchSchedule *ds) const override
|
||||
{
|
||||
SaveLoadTable slt = this->GetLoadDescription();
|
||||
if (slt.size() != 2 || slt[0].label_tag != SLTAG_CUSTOM_START || slt[1].label_tag != SLTAG_CUSTOM_START + 1) {
|
||||
SlErrorCorrupt("Dispatch names sub-chunk fields not as expected");
|
||||
}
|
||||
|
||||
size_t string_count = SlGetStructListLength(UINT32_MAX);
|
||||
btree::btree_map<uint32_t, std::string> &names = ds->GetSupplementaryNameMap();
|
||||
for (size_t i = 0; i < string_count; i++) {
|
||||
uint32_t key = SlReadUint32();
|
||||
SlStdString(&(names[key]), SLE_STR);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
NamedSaveLoadTable GetDispatchScheduleDescription()
|
||||
{
|
||||
static const NamedSaveLoad _dispatch_scheduled_info_desc[] = {
|
||||
NSL("", SLEG_CONDVARVEC_X(_old_scheduled_dispatch_slots, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 6))),
|
||||
NSL("duration", SLE_VAR(DispatchSchedule, scheduled_dispatch_duration, SLE_UINT32)),
|
||||
NSL("", SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_start_tick, SLE_FILE_I32 | SLE_VAR_I64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 4))),
|
||||
NSL("", SLEG_CONDVAR_X(_old_scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 1, 4))),
|
||||
NSL("start_tick", SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_start_tick, SLE_INT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 5))),
|
||||
NSL("last_dispatch", SLE_VAR(DispatchSchedule, scheduled_dispatch_last_dispatch, SLE_INT32)),
|
||||
NSL("max_delay", SLE_VAR(DispatchSchedule, scheduled_dispatch_max_delay, SLE_INT32)),
|
||||
NSL("name", SLE_CONDSSTR_X(DispatchSchedule, name, SLE_STR, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 4))),
|
||||
NSL("flags", SLE_CONDVAR_X(DispatchSchedule, scheduled_dispatch_flags, SLE_FILE_U32 | SLE_VAR_U8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 6))),
|
||||
|
||||
NSLT_STRUCTLIST<DispatchSlotStructHandler>("slots"),
|
||||
NSLT_STRUCTLIST<DispatchNameStructHandler>("names"),
|
||||
};
|
||||
|
||||
return _dispatch_scheduled_info_desc;
|
||||
}
|
||||
|
||||
struct ScheduledDispatchNonTableHelper {
|
||||
std::vector<SaveLoad> dispatch_desc;
|
||||
std::vector<SaveLoad> slot_desc;
|
||||
|
||||
void Setup()
|
||||
{
|
||||
this->dispatch_desc = SlFilterNamedSaveLoadTable(GetDispatchScheduleDescription());
|
||||
this->slot_desc = SlFilterNamedSaveLoadTable(GetDispatchSlotDescription());
|
||||
}
|
||||
|
||||
void LoadDispatchSchedule(DispatchSchedule &ds)
|
||||
{
|
||||
SlObjectLoadFiltered(&ds, this->dispatch_desc);
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 4) && _old_scheduled_dispatch_start_full_date_fract != 0) {
|
||||
_old_scheduled_dispatch_start_full_date_fract_map[&ds] = _old_scheduled_dispatch_start_full_date_fract;
|
||||
}
|
||||
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 6)) {
|
||||
ds.GetScheduledDispatchMutable().reserve(_old_scheduled_dispatch_slots.size());
|
||||
for (uint32_t slot : _old_scheduled_dispatch_slots) {
|
||||
ds.GetScheduledDispatchMutable().push_back({ slot, 0 });
|
||||
}
|
||||
} else {
|
||||
ds.GetScheduledDispatchMutable().resize(SlReadUint32());
|
||||
for (DispatchSlot &slot : ds.GetScheduledDispatchMutable()) {
|
||||
SlObjectLoadFiltered(&slot, this->slot_desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 8)) {
|
||||
uint32_t string_count = SlReadUint32();
|
||||
btree::btree_map<uint32_t, std::string> &names = ds.GetSupplementaryNameMap();
|
||||
for (uint32_t i = 0; i < string_count; i++) {
|
||||
uint32_t key = SlReadUint32();
|
||||
SlStdString(&(names[key]), SLE_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct DispatchScheduleStructHandlerBase : public SaveLoadStructHandler {
|
||||
NamedSaveLoadTable GetDescription() const override
|
||||
{
|
||||
return GetDispatchScheduleDescription();
|
||||
}
|
||||
|
||||
void SaveSchedules(std::vector<DispatchSchedule> &schedules) const
|
||||
{
|
||||
SlSetStructListLength(schedules.size());
|
||||
for (DispatchSchedule &ds : schedules) {
|
||||
SlObjectSaveFiltered(&ds, this->GetLoadDescription());
|
||||
}
|
||||
}
|
||||
|
||||
void LoadSchedules(std::vector<DispatchSchedule> &schedules) const
|
||||
{
|
||||
schedules.resize(SlGetStructListLength(UINT32_MAX));
|
||||
for (DispatchSchedule &ds : schedules) {
|
||||
SlObjectLoadFiltered(&ds, this->GetLoadDescription());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct OrderListDispatchScheduleStructHandler final : public DispatchScheduleStructHandlerBase {
|
||||
void Save(void *object) const override { this->SaveSchedules(static_cast<OrderList *>(object)->GetScheduledDispatchScheduleSet()); }
|
||||
|
||||
void Load(void *object) const override { this->LoadSchedules(static_cast<OrderList *>(object)->GetScheduledDispatchScheduleSet()); }
|
||||
};
|
||||
|
||||
struct OrderBackupDispatchScheduleStructHandler final : public DispatchScheduleStructHandlerBase {
|
||||
void Save(void *object) const override { this->SaveSchedules(static_cast<OrderBackup *>(object)->dispatch_schedules); }
|
||||
|
||||
void Load(void *object) const override { this->LoadSchedules(static_cast<OrderBackup *>(object)->dispatch_schedules); }
|
||||
};
|
||||
|
||||
NamedSaveLoadTable GetOrderListDescription()
|
||||
{
|
||||
static const NamedSaveLoad _orderlist_desc[] = {
|
||||
NSL("first", SLE_REF(OrderList, first, REF_ORDER)),
|
||||
NSL("", SLEG_CONDVAR_X(_jokerpp_separation_mode, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP))),
|
||||
NSL("", SLE_CONDNULL_X(21, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP))),
|
||||
|
||||
NSLT_STRUCTLIST<OrderListDispatchScheduleStructHandler>("dispatch_schedule"),
|
||||
};
|
||||
|
||||
return _orderlist_desc;
|
||||
}
|
||||
|
||||
static std::vector<SaveLoad> _filtered_ordl_desc;
|
||||
static std::vector<SaveLoad> _filtered_ordl_sd_desc;
|
||||
static std::vector<SaveLoad> _filtered_ordl_slot_desc;
|
||||
|
||||
static void SetupDescs_ORDL()
|
||||
NamedSaveLoadTable GetOrderBackupDescription()
|
||||
{
|
||||
_filtered_ordl_desc = SlFilterObject(GetOrderListDescription());
|
||||
_filtered_ordl_sd_desc = SlFilterObject(GetDispatchScheduleDescription());
|
||||
_filtered_ordl_slot_desc = SlFilterObject(GetDispatchSlotDescription());
|
||||
}
|
||||
static const NamedSaveLoad _order_backup_desc[] = {
|
||||
NSL("user", SLE_VAR(OrderBackup, user, SLE_UINT32)),
|
||||
NSL("tile", SLE_VAR(OrderBackup, tile, SLE_UINT32)),
|
||||
NSL("group", SLE_VAR(OrderBackup, group, SLE_UINT16)),
|
||||
NSL("service_interval", SLE_CONDVAR(OrderBackup, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_192)),
|
||||
NSL("service_interval", SLE_CONDVAR(OrderBackup, service_interval, SLE_UINT16, SLV_192, SL_MAX_VERSION)),
|
||||
NSL("name", SLE_STR(OrderBackup, name, SLE_STR, 0)),
|
||||
NSL("", SLE_CONDNULL(2, SL_MIN_VERSION, SLV_192)), // clone (2 bytes of pointer, i.e. garbage)
|
||||
NSL("clone", SLE_CONDREF(OrderBackup, clone, REF_VEHICLE, SLV_192, SL_MAX_VERSION)),
|
||||
NSL("cur_real_order_index", SLE_VAR(OrderBackup, cur_real_order_index, SLE_VEHORDERID)),
|
||||
NSL("cur_implicit_order_index", SLE_CONDVAR(OrderBackup, cur_implicit_order_index, SLE_VEHORDERID, SLV_176, SL_MAX_VERSION)),
|
||||
NSL("cur_timetable_order_index", SLE_CONDVAR_X(OrderBackup, cur_timetable_order_index, SLE_VEHORDERID, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA))),
|
||||
NSL("current_order_time", SLE_CONDVAR(OrderBackup, current_order_time, SLE_UINT32, SLV_176, SL_MAX_VERSION)),
|
||||
NSL("lateness_counter", SLE_CONDVAR(OrderBackup, lateness_counter, SLE_INT32, SLV_176, SL_MAX_VERSION)),
|
||||
NSL("timetable_start", SLE_CONDVAR_X(OrderBackup, timetable_start, SLE_FILE_I32 | SLE_VAR_I64, SLV_176, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLES_START_TICKS, 0, 2))),
|
||||
NSL("timetable_start", SLE_CONDVAR_X(OrderBackup, timetable_start, SLE_INT64, SLV_176, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLES_START_TICKS, 3))),
|
||||
NSL("", SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLES_START_TICKS, 2, 2))),
|
||||
NSL("vehicle_flags", SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U32, SLV_176, SLV_180)),
|
||||
NSL("vehicle_flags", SLE_CONDVAR_X(OrderBackup, vehicle_flags, SLE_FILE_U16 | SLE_VAR_U32, SLV_180, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VEHICLE_FLAGS_EXTRA, 0, 0))),
|
||||
NSL("vehicle_flags", SLE_CONDVAR_X(OrderBackup, vehicle_flags, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VEHICLE_FLAGS_EXTRA, 1))),
|
||||
NSL("orders", SLE_REF(OrderBackup, orders, REF_ORDER)),
|
||||
NSL("", SLE_CONDNULL_X(18, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2, 2))),
|
||||
|
||||
static void SaveDispatchSchedule(DispatchSchedule &ds)
|
||||
{
|
||||
SlObjectSaveFiltered(&ds, _filtered_ordl_sd_desc);
|
||||
NSLT_STRUCTLIST<OrderBackupDispatchScheduleStructHandler>("dispatch_schedule"),
|
||||
};
|
||||
|
||||
SlWriteUint32((uint32_t)ds.GetScheduledDispatchMutable().size());
|
||||
for (DispatchSlot &slot : ds.GetScheduledDispatchMutable()) {
|
||||
SlObjectSaveFiltered(&slot, _filtered_ordl_slot_desc);
|
||||
}
|
||||
|
||||
{
|
||||
btree::btree_map<uint32_t, std::string> &names = ds.GetSupplementaryNameMap();
|
||||
SlWriteUint32((uint32_t)names.size());
|
||||
for (auto &it : names) {
|
||||
SlWriteUint32(it.first);
|
||||
SlStdString(&(it.second), SLE_STR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void LoadDispatchSchedule(DispatchSchedule &ds)
|
||||
{
|
||||
SlObjectLoadFiltered(&ds, _filtered_ordl_sd_desc);
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 4) && _old_scheduled_dispatch_start_full_date_fract != 0) {
|
||||
_old_scheduled_dispatch_start_full_date_fract_map[&ds] = _old_scheduled_dispatch_start_full_date_fract;
|
||||
}
|
||||
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 6)) {
|
||||
ds.GetScheduledDispatchMutable().reserve(_old_scheduled_dispatch_slots.size());
|
||||
for (uint32_t slot : _old_scheduled_dispatch_slots) {
|
||||
ds.GetScheduledDispatchMutable().push_back({ slot, 0 });
|
||||
}
|
||||
} else {
|
||||
ds.GetScheduledDispatchMutable().resize(SlReadUint32());
|
||||
for (DispatchSlot &slot : ds.GetScheduledDispatchMutable()) {
|
||||
SlObjectLoadFiltered(&slot, _filtered_ordl_slot_desc);
|
||||
}
|
||||
}
|
||||
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 8)) {
|
||||
uint32_t string_count = SlReadUint32();
|
||||
btree::btree_map<uint32_t, std::string> &names = ds.GetSupplementaryNameMap();
|
||||
for (uint32_t i = 0; i < string_count; i++) {
|
||||
uint32_t key = SlReadUint32();
|
||||
SlStdString(&(names[key]), SLE_STR);
|
||||
}
|
||||
}
|
||||
return _order_backup_desc;
|
||||
}
|
||||
|
||||
static void Save_ORDL()
|
||||
{
|
||||
SetupDescs_ORDL();
|
||||
SaveLoadTableData slt = SlTableHeader(GetOrderListDescription());
|
||||
|
||||
for (OrderList *list : OrderList::Iterate()) {
|
||||
SlSetArrayIndex(list->index);
|
||||
SlAutolength([&]() {
|
||||
SlObjectSaveFiltered(list, _filtered_ordl_desc);
|
||||
SlWriteUint32(list->GetScheduledDispatchScheduleCount());
|
||||
for (DispatchSchedule &ds : list->GetScheduledDispatchScheduleSet()) {
|
||||
SaveDispatchSchedule(ds);
|
||||
}
|
||||
});
|
||||
SlObjectSaveFiltered(list, slt);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_ORDL()
|
||||
{
|
||||
SetupDescs_ORDL();
|
||||
|
||||
_jokerpp_auto_separation.clear();
|
||||
_jokerpp_non_auto_separation.clear();
|
||||
|
||||
_old_scheduled_dispatch_start_full_date_fract = 0;
|
||||
_old_scheduled_dispatch_start_full_date_fract_map.clear();
|
||||
|
||||
const bool is_table = SlIsTableChunk();
|
||||
SaveLoadTableData slt = SlTableHeaderOrRiff(GetOrderListDescription());
|
||||
|
||||
if (is_table && SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 6)) SlErrorCorrupt("XSLFI_SCHEDULED_DISPATCH versions 1 - 6 not supported in table format");
|
||||
|
||||
ScheduledDispatchNonTableHelper helper;
|
||||
if (!is_table) helper.Setup();
|
||||
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
/* set num_orders to 0 so it's a valid OrderList */
|
||||
OrderList *list = new (index) OrderList(0);
|
||||
SlObjectLoadFiltered(list, _filtered_ordl_desc);
|
||||
SlObjectLoadFiltered(list, slt);
|
||||
if (SlXvIsFeaturePresent(XSLFI_JOKERPP)) {
|
||||
if (_jokerpp_separation_mode == 0) {
|
||||
_jokerpp_auto_separation.push_back(list);
|
||||
@ -396,11 +528,11 @@ static void Load_ORDL()
|
||||
_jokerpp_non_auto_separation.push_back(list);
|
||||
}
|
||||
}
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH)) {
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH) && !is_table) {
|
||||
uint count = SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 3) ? SlReadUint32() : 1;
|
||||
list->GetScheduledDispatchScheduleSet().resize(count);
|
||||
for (DispatchSchedule &ds : list->GetScheduledDispatchScheduleSet()) {
|
||||
LoadDispatchSchedule(ds);
|
||||
helper.LoadDispatchSchedule(ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -410,81 +542,59 @@ static void Load_ORDL()
|
||||
|
||||
void Ptrs_ORDL()
|
||||
{
|
||||
std::vector<SaveLoad> filtered_desc = SlFilterObject(GetOrderListDescription());
|
||||
SaveLoadTableData slt = SlPrepareNamedSaveLoadTableForPtrOrNull(GetOrderListDescription());
|
||||
|
||||
for (OrderList *list : OrderList::Iterate()) {
|
||||
SlObjectPtrOrNullFiltered(list, filtered_desc);
|
||||
list->ReindexOrderList();
|
||||
SlObjectPtrOrNullFiltered(list, slt);
|
||||
}
|
||||
}
|
||||
|
||||
SaveLoadTable GetOrderBackupDescription()
|
||||
{
|
||||
static const SaveLoad _order_backup_desc[] = {
|
||||
SLE_VAR(OrderBackup, user, SLE_UINT32),
|
||||
SLE_VAR(OrderBackup, tile, SLE_UINT32),
|
||||
SLE_VAR(OrderBackup, group, SLE_UINT16),
|
||||
SLE_CONDVAR(OrderBackup, service_interval, SLE_FILE_U32 | SLE_VAR_U16, SL_MIN_VERSION, SLV_192),
|
||||
SLE_CONDVAR(OrderBackup, service_interval, SLE_UINT16, SLV_192, SL_MAX_VERSION),
|
||||
SLE_STR(OrderBackup, name, SLE_STR, 0),
|
||||
SLE_CONDNULL(2, SL_MIN_VERSION, SLV_192), // clone (2 bytes of pointer, i.e. garbage)
|
||||
SLE_CONDREF(OrderBackup, clone, REF_VEHICLE, SLV_192, SL_MAX_VERSION),
|
||||
SLE_VAR(OrderBackup, cur_real_order_index, SLE_VEHORDERID),
|
||||
SLE_CONDVAR(OrderBackup, cur_implicit_order_index, SLE_VEHORDERID, SLV_176, SL_MAX_VERSION),
|
||||
SLE_CONDVAR_X(OrderBackup, cur_timetable_order_index, SLE_VEHORDERID, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLE_EXTRA)),
|
||||
SLE_CONDVAR(OrderBackup, current_order_time, SLE_UINT32, SLV_176, SL_MAX_VERSION),
|
||||
SLE_CONDVAR(OrderBackup, lateness_counter, SLE_INT32, SLV_176, SL_MAX_VERSION),
|
||||
SLE_CONDVAR_X(OrderBackup, timetable_start, SLE_FILE_I32 | SLE_VAR_I64, SLV_176, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLES_START_TICKS, 0, 2)),
|
||||
SLE_CONDVAR_X(OrderBackup, timetable_start, SLE_INT64, SLV_176, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLES_START_TICKS, 3)),
|
||||
SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TIMETABLES_START_TICKS, 2, 2)),
|
||||
SLE_CONDVAR(OrderBackup, vehicle_flags, SLE_FILE_U8 | SLE_VAR_U32, SLV_176, SLV_180),
|
||||
SLE_CONDVAR_X(OrderBackup, vehicle_flags, SLE_FILE_U16 | SLE_VAR_U32, SLV_180, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VEHICLE_FLAGS_EXTRA, 0, 0)),
|
||||
SLE_CONDVAR_X(OrderBackup, vehicle_flags, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_VEHICLE_FLAGS_EXTRA, 1)),
|
||||
SLE_REF(OrderBackup, orders, REF_ORDER),
|
||||
SLE_CONDNULL_X(18, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH, 2, 2)),
|
||||
};
|
||||
|
||||
return _order_backup_desc;
|
||||
}
|
||||
|
||||
void Save_BKOR()
|
||||
{
|
||||
SaveLoadTableData slt = SlTableHeader(GetOrderBackupDescription());
|
||||
|
||||
/* We only save this when we're a network server
|
||||
* as we want this information on our clients. For
|
||||
* normal games this information isn't needed. */
|
||||
if (!_networking || !_network_server) return;
|
||||
|
||||
SetupDescs_ORDL();
|
||||
|
||||
for (OrderBackup *ob : OrderBackup::Iterate()) {
|
||||
SlSetArrayIndex(ob->index);
|
||||
SlAutolength([&]() {
|
||||
SlObject(ob, GetOrderBackupDescription());
|
||||
SlWriteUint32((uint)ob->dispatch_schedules.size());
|
||||
for (DispatchSchedule &ds : ob->dispatch_schedules) {
|
||||
SaveDispatchSchedule(ds);
|
||||
}
|
||||
});
|
||||
SlObjectSaveFiltered(ob, slt);
|
||||
}
|
||||
}
|
||||
|
||||
void Load_BKOR()
|
||||
{
|
||||
SaveLoadTableData slt = SlTableHeaderOrRiff(GetOrderBackupDescription());
|
||||
|
||||
if (SlIsTableChunk()) {
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 1, 6)) SlErrorCorrupt("XSLFI_SCHEDULED_DISPATCH versions 1 - 6 not supported in table format");
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
/* set num_orders to 0 so it's a valid OrderList */
|
||||
OrderBackup *ob = new (index) OrderBackup();
|
||||
SlObjectLoadFiltered(ob, slt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ScheduledDispatchNonTableHelper helper;
|
||||
helper.Setup();
|
||||
|
||||
int index;
|
||||
|
||||
SetupDescs_ORDL();
|
||||
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
/* set num_orders to 0 so it's a valid OrderList */
|
||||
OrderBackup *ob = new (index) OrderBackup();
|
||||
SlObject(ob, GetOrderBackupDescription());
|
||||
SlObjectLoadFiltered(ob, slt);
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 3)) {
|
||||
uint count = SlReadUint32();
|
||||
ob->dispatch_schedules.resize(count);
|
||||
for (DispatchSchedule &ds : ob->dispatch_schedules) {
|
||||
if (SlXvIsFeaturePresent(XSLFI_SCHEDULED_DISPATCH, 8)) {
|
||||
LoadDispatchSchedule(ds);
|
||||
helper.LoadDispatchSchedule(ds);
|
||||
} else {
|
||||
SlObject(&ds, GetDispatchScheduleDescription());
|
||||
SlObjectLoadFiltered(&ds, helper.dispatch_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -493,16 +603,18 @@ void Load_BKOR()
|
||||
|
||||
static void Ptrs_BKOR()
|
||||
{
|
||||
SaveLoadTableData slt = SlPrepareNamedSaveLoadTableForPtrOrNull(GetOrderBackupDescription());
|
||||
|
||||
for (OrderBackup *ob : OrderBackup::Iterate()) {
|
||||
SlObject(ob, GetOrderBackupDescription());
|
||||
SlObjectPtrOrNullFiltered(ob, slt);
|
||||
}
|
||||
}
|
||||
|
||||
static const ChunkHandler order_chunk_handlers[] = {
|
||||
{ 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_ARRAY },
|
||||
{ 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_ARRAY },
|
||||
{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_ARRAY },
|
||||
{ 'ORDX', Save_ORDX, Load_ORDX, nullptr, nullptr, CH_SPARSE_ARRAY },
|
||||
{ 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_TABLE },
|
||||
{ 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_TABLE },
|
||||
{ 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_TABLE },
|
||||
{ 'ORDX', nullptr, Load_ORDX, nullptr, nullptr, CH_READONLY },
|
||||
};
|
||||
|
||||
extern const ChunkHandlerTable _order_chunk_handlers(order_chunk_handlers);
|
||||
|
@ -2243,8 +2243,13 @@ void SlSkipTableHeader()
|
||||
static uint8_t GetSavegameTableFileType(const SaveLoad &sld)
|
||||
{
|
||||
switch (sld.cmd) {
|
||||
case SL_VAR:
|
||||
return GetVarFileType(sld.conv); break;
|
||||
case SL_VAR: {
|
||||
VarType type = GetVarFileType(sld.conv);
|
||||
if (type == SLE_FILE_VEHORDERID) {
|
||||
return SlXvIsFeaturePresent(XSLFI_MORE_VEHICLE_ORDERS) ? SLE_FILE_U16 : SLE_FILE_U8;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
case SL_STR:
|
||||
case SL_STDSTR:
|
||||
|
@ -1216,28 +1216,32 @@ static void Ptrs_VEHS()
|
||||
}
|
||||
}
|
||||
|
||||
const SaveLoadTable GetOrderExtraInfoDescription();
|
||||
const NamedSaveLoadTable GetOrderExtraInfoDescription();
|
||||
|
||||
void Save_VEOX()
|
||||
{
|
||||
std::vector<SaveLoad> slt = SlFilterNamedSaveLoadTable(GetOrderExtraInfoDescription());
|
||||
|
||||
/* save extended order info for vehicle current order */
|
||||
for (Vehicle *v : Vehicle::Iterate()) {
|
||||
if (v->current_order.extra) {
|
||||
SlSetArrayIndex(v->index);
|
||||
SlObject(v->current_order.extra.get(), GetOrderExtraInfoDescription());
|
||||
SlObject(v->current_order.extra.get(), slt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load_VEOX()
|
||||
{
|
||||
std::vector<SaveLoad> slt = SlFilterNamedSaveLoadTable(GetOrderExtraInfoDescription());
|
||||
|
||||
/* load extended order info for vehicle current order */
|
||||
int index;
|
||||
while ((index = SlIterateArray()) != -1) {
|
||||
Vehicle *v = Vehicle::GetIfValid(index);
|
||||
assert(v != nullptr);
|
||||
v->current_order.AllocExtraInfo();
|
||||
SlObject(v->current_order.extra.get(), GetOrderExtraInfoDescription());
|
||||
SlObject(v->current_order.extra.get(), slt);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user