Add initial support for loading JokerPP savegames

See #123
This commit is contained in:
Jonathan G Rennison
2019-12-28 13:06:22 +00:00
parent c75ed00f0f
commit d56d4ea51f
15 changed files with 207 additions and 13 deletions

View File

@@ -794,7 +794,7 @@ bool AfterLoadGame()
/* The value of _date_fract got divided, so make sure that old games are converted correctly. */
if (IsSavegameVersionBefore(SLV_11, 1) || (IsSavegameVersionBefore(SLV_147) && _date_fract > DAY_TICKS)) _date_fract /= 885;
if (SlXvIsFeaturePresent(XSLFI_SPRINGPP)) {
if (SlXvIsFeaturePresent(XSLFI_SPRINGPP) || SlXvIsFeaturePresent(XSLFI_JOKERPP)) {
assert(_settings_game.economy.day_length_factor >= 1);
_tick_skip_counter = _date_fract % _settings_game.economy.day_length_factor;
_date_fract /= _settings_game.economy.day_length_factor;
@@ -803,7 +803,7 @@ bool AfterLoadGame()
}
/* Set day length factor to 1 if loading a pre day length savegame */
if (SlXvIsFeatureMissing(XSLFI_VARIABLE_DAY_LENGTH) && SlXvIsFeatureMissing(XSLFI_SPRINGPP)) {
if (SlXvIsFeatureMissing(XSLFI_VARIABLE_DAY_LENGTH) && SlXvIsFeatureMissing(XSLFI_SPRINGPP) && SlXvIsFeatureMissing(XSLFI_JOKERPP)) {
_settings_game.economy.day_length_factor = 1;
}
@@ -1424,7 +1424,7 @@ bool AfterLoadGame()
}
}
if (IsSavegameVersionBefore(SLV_ROAD_TYPES)) {
if (IsSavegameVersionBefore(SLV_ROAD_TYPES) && !SlXvIsFeaturePresent(XSLFI_JOKERPP, SL_JOKER_1_27)) {
/* Add road subtypes */
for (TileIndex t = 0; t < map_size; t++) {
bool has_road = false;
@@ -1971,6 +1971,13 @@ bool AfterLoadGame()
v->current_order.SetLoadType(OLFB_NO_LOAD);
}
}
} else if (SlXvIsFeaturePresent(XSLFI_JOKERPP, 1, SL_JOKER_1_23)) {
Order* order;
FOR_ALL_ORDERS(order) {
if (order->IsType(OT_CONDITIONAL) && order->GetConditionVariable() == OCV_SLOT_OCCUPANCY) {
order->GetXDataRef() = order->GetConditionValue();
}
}
}
if (IsSavegameVersionBefore(SLV_84)) {
@@ -3364,6 +3371,35 @@ bool AfterLoadGame()
}
}
if (SlXvIsFeaturePresent(XSLFI_JOKERPP)) {
for (TileIndex t = 0; t < map_size; t++) {
if (IsTileType(t, MP_RAILWAY) && HasSignals(t)) {
if (GetSignalType(t, TRACK_LOWER) == SIGTYPE_PROG) SetSignalType(t, TRACK_LOWER, SIGTYPE_NORMAL);
if (GetSignalType(t, TRACK_UPPER) == SIGTYPE_PROG) SetSignalType(t, TRACK_UPPER, SIGTYPE_NORMAL);
}
}
Vehicle *v;
FOR_ALL_VEHICLES(v) {
SB(v->vehicle_flags, 10, 2, 0);
}
extern std::vector<OrderList *> _jokerpp_auto_separation;
extern std::vector<OrderList *> _jokerpp_non_auto_separation;
for (OrderList *list : _jokerpp_auto_separation) {
for (Vehicle *w = list->GetFirstSharedVehicle(); w != nullptr; w = w->NextShared()) {
SetBit(w->vehicle_flags, VF_TIMETABLE_SEPARATION);
w->ClearSeparation();
}
}
for (OrderList *list : _jokerpp_non_auto_separation) {
for (Vehicle *w = list->GetFirstSharedVehicle(); w != nullptr; w = w->NextShared()) {
ClrBit(w->vehicle_flags, VF_TIMETABLE_SEPARATION);
w->ClearSeparation();
}
}
_jokerpp_auto_separation.clear();
_jokerpp_non_auto_separation.clear();
}
/*
* Only keep order-backups for network clients (and when replaying).
* If we are a network server or not networking, then we just loaded a previously
@@ -3688,11 +3724,6 @@ bool AfterLoadGame()
_settings_game.economy.town_cargo_scale_factor = _settings_game.economy.old_town_cargo_factor * 10;
}
/* Set day length factor to 1 if loading a pre day length savegame */
if (SlXvIsFeatureMissing(XSLFI_VARIABLE_DAY_LENGTH) && SlXvIsFeatureMissing(XSLFI_SPRINGPP)) {
_settings_game.economy.day_length_factor = 1;
}
if (SlXvIsFeatureMissing(XSLFI_SAFER_CROSSINGS)) {
for (TileIndex t = 0; t < map_size; t++) {
if (IsLevelCrossingTile(t)) {

View File

@@ -46,6 +46,7 @@ static const SaveLoad _economy_desc[] = {
SLE_VAR(Economy, infl_amount, SLE_UINT8),
SLE_VAR(Economy, infl_amount_pr, SLE_UINT8),
SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32, SLV_102, SL_MAX_VERSION),
SLE_CONDNULL_X(8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_END()
};

View File

@@ -230,6 +230,30 @@ bool SlXvCheckSpecialSavegameVersions()
_sl_maybe_springpp = true;
return true;
}
if (_sl_version >= SL_JOKER_1_19 && _sl_version <= SL_JOKER_1_27) { /* 278 - 286 */
DEBUG(sl, 1, "Loading a JokerPP savegame version %d as version 197", _sl_version);
_sl_xv_feature_versions[XSLFI_JOKERPP] = _sl_version;
_sl_xv_feature_versions[XSLFI_TOWN_CARGO_ADJ] = 1;
_sl_xv_feature_versions[XSLFI_TEMPLATE_REPLACEMENT] = 1;
_sl_xv_feature_versions[XSLFI_VEH_LIFETIME_PROFIT] = 1;
_sl_xv_feature_versions[XSLFI_TRAIN_FLAGS_EXTRA] = 1;
_sl_xv_feature_versions[XSLFI_SIG_TUNNEL_BRIDGE] = 5;
_sl_xv_feature_versions[XSLFI_REVERSE_AT_WAYPOINT] = 1;
_sl_xv_feature_versions[XSLFI_MULTIPLE_DOCKS] = 1;
_sl_xv_feature_versions[XSLFI_ST_LAST_VEH_TYPE] = 1;
_sl_xv_feature_versions[XSLFI_MORE_RAIL_TYPES] = 1;
_sl_xv_feature_versions[XSLFI_CHUNNEL] = 1;
_sl_xv_feature_versions[XSLFI_MORE_COND_ORDERS] = 1;
_sl_xv_feature_versions[XSLFI_TRACE_RESTRICT] = 1;
if (_sl_version >= SL_JOKER_1_21) _sl_xv_feature_versions[XSLFI_LINKGRAPH_DAY_SCALE] = 1;
if (_sl_version >= SL_JOKER_1_24) _sl_xv_feature_versions[XSLFI_TIMETABLE_EXTRA] = 1;
if (_sl_version >= SL_JOKER_1_24) _sl_xv_feature_versions[XSLFI_ORDER_EXTRA_DATA] = 1;
_sl_xv_discardable_chunk_ids.push_back('SPRG');
_sl_xv_discardable_chunk_ids.push_back('SLNK');
_sl_version = SLV_197;
_sl_is_faked_ext = true;
return true;
}
return false;
}

View File

@@ -84,6 +84,7 @@ enum SlXvFeatureIndex {
XSLFI_TRAFFIC_LIGHTS, ///< This save game uses road traffic lights
XSLFI_RAIL_AGEING, ///< This save game uses the rail aging patch
XSLFI_SPRINGPP, ///< This is a SpringPP game, use this for loading some settings
XSLFI_JOKERPP, ///< This is a JokerPP game, use this for loading some settings
XSLFI_SIZE, ///< Total count of features, including null feature
};

View File

@@ -16,6 +16,10 @@
#include "../safeguards.h"
static uint32 _jokerpp_separation_mode;
std::vector<OrderList *> _jokerpp_auto_separation;
std::vector<OrderList *> _jokerpp_non_auto_separation;
/**
* Converts this order from an old savegame's version;
* it moves all bits to the new location.
@@ -257,6 +261,8 @@ const SaveLoad *GetOrderListDescription()
SLE_CONDVAR_X(OrderList, scheduled_dispatch_start_full_date_fract, SLE_UINT16, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
SLE_CONDVAR_X(OrderList, scheduled_dispatch_last_dispatch, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
SLE_CONDVAR_X(OrderList, scheduled_dispatch_max_delay, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SCHEDULED_DISPATCH)),
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)),
SLE_END()
};
@@ -275,12 +281,21 @@ static void Save_ORDL()
static void Load_ORDL()
{
_jokerpp_auto_separation.clear();
_jokerpp_non_auto_separation.clear();
int index;
while ((index = SlIterateArray()) != -1) {
/* set num_orders to 0 so it's a valid OrderList */
OrderList *list = new (index) OrderList(0);
SlObject(list, GetOrderListDescription());
if (SlXvIsFeaturePresent(XSLFI_JOKERPP)) {
if (_jokerpp_separation_mode == 0) {
_jokerpp_auto_separation.push_back(list);
} else {
_jokerpp_non_auto_separation.push_back(list);
}
}
}
}

View File

@@ -20,6 +20,7 @@ static const SaveLoad _plan_desc[] = {
SLE_VAR(Plan, visible_by_all, SLE_BOOL),
SLE_VAR(Plan, creation_date, SLE_INT32),
SLE_CONDSTDSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ENH_VIEWPORT_PLANS, 3)),
SLE_CONDSTDSTR_X(Plan, name, 0, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_20)),
SLE_END()
};

View File

@@ -319,6 +319,15 @@ enum SaveLoadVersion : uint16 {
SL_TRACE_RESTRICT_2000 = 2000,
SL_TRACE_RESTRICT_2001 = 2001,
SL_TRACE_RESTRICT_2002 = 2002,
SL_JOKER_1_19 = 278,
SL_JOKER_1_20 = 279,
SL_JOKER_1_21 = 280,
SL_JOKER_1_22 = 281,
SL_JOKER_1_23 = 282,
SL_JOKER_1_24 = 283,
SL_JOKER_1_25 = 284,
SL_JOKER_1_26 = 285,
SL_JOKER_1_27 = 286,
};
/** Save or load result codes. */

View File

@@ -206,6 +206,7 @@ static const SaveLoad _old_station_desc[] = {
SLE_CONDNULL(2, SL_MIN_VERSION, SLV_26), ///< last-vehicle
SLEG_CONDVAR_X(_old_last_vehicle_type, SLE_UINT8, SLV_26, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ST_LAST_VEH_TYPE, 0, 0)),
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_CONDNULL(2, SLV_3, SLV_26), ///< custom station class and id
SLE_CONDVAR(Station, build_date, SLE_FILE_U16 | SLE_VAR_I32, SLV_3, SLV_31),
@@ -292,6 +293,7 @@ const SaveLoad *GetGoodsDesc()
SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION),
SLEG_CONDVAR( _num_flows, SLE_UINT32, SLV_183, SL_MAX_VERSION),
SLE_CONDVAR(GoodsEntry, max_waiting_cargo, SLE_UINT32, SLV_183, SL_MAX_VERSION),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_CONDVAR_X(GoodsEntry, last_vehicle_type, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ST_LAST_VEH_TYPE, 1)),
SLE_END()
};
@@ -457,10 +459,12 @@ static const SaveLoad _station_desc[] = {
SLE_VAR(Station, time_since_load, SLE_UINT8),
SLE_VAR(Station, time_since_unload, SLE_UINT8),
SLEG_CONDVAR_X(_old_last_vehicle_type, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ST_LAST_VEH_TYPE, 0, 0)),
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_VAR(Station, had_vehicle_of_type, SLE_UINT8),
SLE_VEC(Station, loading_vehicles, REF_VEHICLE),
SLE_CONDVAR(Station, always_accepted, SLE_FILE_U32 | SLE_VAR_U64, SLV_127, SLV_EXTEND_CARGOTYPES),
SLE_CONDVAR(Station, always_accepted, SLE_UINT64, SLV_EXTEND_CARGOTYPES, SL_MAX_VERSION),
SLE_CONDNULL_X(32 * 24, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_22)),
SLE_END()
};

View File

@@ -43,6 +43,7 @@ const SaveLoad* GTD() {
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 3)),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 1)),
SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 2, 3)),
SLE_CONDNULL_X(36, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_TEMPLATE_REPLACEMENT, 0, 3)),
SLE_END()

View File

@@ -184,10 +184,13 @@ static const SaveLoad _town_desc[] = {
SLE_CONDVAR(Town, grow_counter, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_54),
SLE_CONDVAR(Town, growth_rate, SLE_FILE_U8 | SLE_VAR_I16, SL_MIN_VERSION, SLV_54),
SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, SLV_54, SL_MAX_VERSION),
SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_26)),
SLE_CONDVAR(Town, grow_counter, SLE_UINT16, SLV_54, SL_MAX_VERSION),
SLE_CONDVAR(Town, growth_rate, SLE_FILE_I16 | SLE_VAR_U16, SLV_54, SLV_165),
SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_26)),
SLE_CONDVAR(Town, growth_rate, SLE_UINT16, SLV_165, SL_MAX_VERSION),
SLE_VAR(Town, fund_buildings_months, SLE_UINT8),

View File

@@ -65,6 +65,15 @@ static void Load_TRRP()
SlObject(&stub, _trace_restrict_program_stub_desc);
prog->items.resize(stub.length);
SlArray(&(prog->items[0]), stub.length, SLE_UINT32);
if (SlXvIsFeaturePresent(XSLFI_JOKERPP)) {
for (size_t i = 0; i < prog->items.size(); i++) {
TraceRestrictItem &item = prog->items[i]; // note this is a reference,
if (GetTraceRestrictType(item) == 19 || GetTraceRestrictType(item) == 20) {
SetTraceRestrictType(item, (TraceRestrictItemType)(GetTraceRestrictType(item) + 2));
}
if (IsTraceRestrictDoubleItem(item)) i++;
}
}
CommandCost validation_result = prog->Validate();
if (validation_result.Failed()) {
char str[4096];

View File

@@ -670,10 +670,10 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_VAR(Vehicle, day_counter, SLE_UINT8),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_CONDVAR_X(Vehicle, running_ticks, SLE_FILE_U8 | SLE_VAR_U16, SLV_88, SL_MAX_VERSION, SlXvFeatureTest([](uint16 version, bool version_in_range) -> bool {
return version_in_range && !(SlXvIsFeaturePresent(XSLFI_SPRINGPP, 3) || SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 2));
return version_in_range && !(SlXvIsFeaturePresent(XSLFI_SPRINGPP, 3) || SlXvIsFeaturePresent(XSLFI_JOKERPP) || SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 2));
})),
SLE_CONDVAR_X(Vehicle, running_ticks, SLE_UINT16, SLV_88, SL_MAX_VERSION, SlXvFeatureTest([](uint16 version, bool version_in_range) -> bool {
return version_in_range && (SlXvIsFeaturePresent(XSLFI_SPRINGPP, 2) || SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 2));
return version_in_range && (SlXvIsFeaturePresent(XSLFI_SPRINGPP, 2) || SlXvIsFeaturePresent(XSLFI_JOKERPP) || SlXvIsFeaturePresent(XSLFI_VARIABLE_DAY_LENGTH, 2));
})),
SLE_VAR(Vehicle, cur_implicit_order_index, SLE_UINT8),
@@ -761,6 +761,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, SLV_67, SL_MAX_VERSION),
SLE_CONDVAR_X(Vehicle, current_loading_time, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUTO_TIMETABLE)),
SLE_CONDVAR_X(Vehicle, current_loading_time, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP, SL_JOKER_1_23)),
SLE_CONDNULL_X(4, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)),
SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, SLV_67, SL_MAX_VERSION),
@@ -772,6 +773,8 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)),
SLE_CONDNULL_X(2, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)),
SLE_CONDNULL_X(160, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_JOKERPP)),
SLE_END()
};