Delay vehicle cache init to after map upgrades in load

Split AfterLoadVehicles into two functions.
Vehicle cache init and other functionality requiring an upgraded and
valid map is now performed later in the load process.

Re-order load update for SLV_139, it is no longer required to be
performed before the first phase of vehicle updates
This commit is contained in:
Jonathan G Rennison 2024-07-01 23:40:11 +01:00
parent f5b0874c1c
commit a99e6b5082
8 changed files with 56 additions and 41 deletions

View File

@ -703,7 +703,11 @@ void DrawRailCatenary(const TileInfo *ti)
void SettingsDisableElrail(int32_t new_value) void SettingsDisableElrail(int32_t new_value)
{ {
bool disable = (new_value != 0); bool disable = (new_value != 0);
UpdateDisableElrailSettingState(disable, true);
}
void UpdateDisableElrailSettingState(bool disable, bool update_vehicles)
{
/* pick appropriate railtype for elrail engines depending on setting */ /* pick appropriate railtype for elrail engines depending on setting */
const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC; const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC;
@ -731,12 +735,14 @@ void SettingsDisableElrail(int32_t new_value)
} }
/* Fix the total power and acceleration for trains */ /* Fix the total power and acceleration for trains */
if (update_vehicles) {
for (Train *t : Train::IterateFrontOnly()) { for (Train *t : Train::IterateFrontOnly()) {
/* power and acceleration is cached only for front engines */ /* power and acceleration is cached only for front engines */
if (t->IsFrontEngine()) { if (t->IsFrontEngine()) {
t->ConsistChanged(CCF_TRACK); t->ConsistChanged(CCF_TRACK);
} }
} }
}
for (Company *c : Company::Iterate()) c->avail_railtypes = GetCompanyRailTypes(c->index); for (Company *c : Company::Iterate()) c->avail_railtypes = GetCompanyRailTypes(c->index);

View File

@ -37,5 +37,6 @@ void DrawRailCatenaryOnTunnel(const TileInfo *ti);
void DrawRailCatenaryOnBridge(const TileInfo *ti); void DrawRailCatenaryOnBridge(const TileInfo *ti);
void SettingsDisableElrail(int32_t new_value); ///< _settings_game.disable_elrail callback void SettingsDisableElrail(int32_t new_value); ///< _settings_game.disable_elrail callback
void UpdateDisableElrailSettingState(bool disable, bool update_vehicles);
#endif /* ELRAIL_FUNC_H */ #endif /* ELRAIL_FUNC_H */

View File

@ -890,7 +890,7 @@ static_assert(DispatchSchedule::DEPARTURE_TAG_COUNT == 1 + (DispatchSlot::SDSF_L
*/ */
struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> { struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> {
private: private:
friend void AfterLoadVehicles(bool part_of_load); ///< For instantiating the shared vehicle chain friend void AfterLoadVehiclesPhase1(bool part_of_load); ///< For instantiating the shared vehicle chain
friend SaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists. friend SaveLoadTable GetOrderListDescription(); ///< Saving and loading of order lists.
friend upstream_sl::SaveLoadTable upstream_sl::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. friend void Ptrs_ORDL(); ///< Saving and loading of order lists.

View File

@ -985,17 +985,6 @@ bool AfterLoadGame()
* filled; and that could eventually lead to desyncs. */ * filled; and that could eventually lead to desyncs. */
CargoPacket::AfterLoad(); CargoPacket::AfterLoad();
/* Oilrig was moved from id 15 to 9. We have to do this conversion
* here as AfterLoadVehicles can check it indirectly via the newgrf
* code. */
if (IsSavegameVersionBefore(SLV_139)) {
for (Station *st : Station::Iterate()) {
if (st->airport.tile != INVALID_TILE && st->airport.type == 15) {
st->airport.type = AT_OILRIG;
}
}
}
if (SlXvIsFeaturePresent(XSLFI_SPRINGPP)) { if (SlXvIsFeaturePresent(XSLFI_SPRINGPP)) {
/* /*
* Reject huge airports * Reject huge airports
@ -1061,8 +1050,8 @@ bool AfterLoadGame()
extern void AnalyseHouseSpriteGroups(); extern void AnalyseHouseSpriteGroups();
AnalyseHouseSpriteGroups(); AnalyseHouseSpriteGroups();
/* Update all vehicles */ /* Update all vehicles: Phase 1 */
AfterLoadVehicles(true); AfterLoadVehiclesPhase1(true);
CargoPacket::PostVehiclesAfterLoad(); CargoPacket::PostVehiclesAfterLoad();
@ -1747,11 +1736,6 @@ bool AfterLoadGame()
SetSecondaryRailType(t, GetRailType(t)); SetSecondaryRailType(t, GetRailType(t));
} }
} }
for (Train *v : Train::IterateFrontOnly()) {
if (v->IsFrontEngine() || v->IsFreeWagon()) v->ConsistChanged(CCF_TRACK);
}
} }
/* In version 16.1 of the savegame a company can decide if trains, which get /* In version 16.1 of the savegame a company can decide if trains, which get
@ -1900,7 +1884,7 @@ bool AfterLoadGame()
* preference of a user, let elrails enabled; it can be disabled manually */ * preference of a user, let elrails enabled; it can be disabled manually */
if (IsSavegameVersionBefore(SLV_38)) _settings_game.vehicle.disable_elrails = false; if (IsSavegameVersionBefore(SLV_38)) _settings_game.vehicle.disable_elrails = false;
/* do the same as when elrails were enabled/disabled manually just now */ /* do the same as when elrails were enabled/disabled manually just now */
SettingsDisableElrail(_settings_game.vehicle.disable_elrails); UpdateDisableElrailSettingState(_settings_game.vehicle.disable_elrails, false);
InitializeRailGUI(); InitializeRailGUI();
/* From version 53, the map array was changed for house tiles to allow /* From version 53, the map array was changed for house tiles to allow
@ -2872,6 +2856,14 @@ bool AfterLoadGame()
} }
} }
if (IsSavegameVersionBefore(SLV_139)) {
for (Station *st : Station::Iterate()) {
if (st->airport.tile != INVALID_TILE && st->airport.type == 15) {
st->airport.type = AT_OILRIG;
}
}
}
if (IsSavegameVersionBefore(SLV_140)) { if (IsSavegameVersionBefore(SLV_140)) {
for (Station *st : Station::Iterate()) { for (Station *st : Station::Iterate()) {
if (st->airport.tile != INVALID_TILE) { if (st->airport.tile != INVALID_TILE) {
@ -3469,6 +3461,14 @@ bool AfterLoadGame()
} }
} }
/* Beyond this point, tile types which can be accessed by vehicles must be in a valid state. */
/* Update all vehicles: Phase 2 */
AfterLoadVehiclesPhase2(true);
/* The center of train vehicles was changed, fix up spacing. */
if (IsSavegameVersionBefore(SLV_164)) FixupTrainLengths();
/* In version 2.2 of the savegame, we have new airports, so status of all aircraft is reset. /* In version 2.2 of the savegame, we have new airports, so status of all aircraft is reset.
* This has to be called after all map array updates */ * This has to be called after all map array updates */
if (IsSavegameVersionBefore(SLV_2, 2)) UpdateOldAircraft(); if (IsSavegameVersionBefore(SLV_2, 2)) UpdateOldAircraft();
@ -4580,7 +4580,8 @@ void ReloadNewGRFData()
AnalyseIndustryTileSpriteGroups(); AnalyseIndustryTileSpriteGroups();
extern void AnalyseHouseSpriteGroups(); extern void AnalyseHouseSpriteGroups();
AnalyseHouseSpriteGroups(); AnalyseHouseSpriteGroups();
AfterLoadVehicles(false); AfterLoadVehiclesPhase1(false);
AfterLoadVehiclesPhase2(false);
StartupEngines(); StartupEngines();
GroupStatistics::UpdateAfterLoad(); GroupStatistics::UpdateAfterLoad();
/* update station graphics */ /* update station graphics */

View File

@ -28,7 +28,6 @@
#include "../safeguards.h" #include "../safeguards.h"
void AfterLoadVehicles(bool part_of_load);
bool TrainController(Train *v, Vehicle *nomove, bool reverse = true); // From train_cmd.cpp bool TrainController(Train *v, Vehicle *nomove, bool reverse = true); // From train_cmd.cpp
void ReverseTrainDirection(Train *v); void ReverseTrainDirection(Train *v);
void ReverseTrainSwapVeh(Train *v, int l, int r); void ReverseTrainSwapVeh(Train *v, int l, int r);

View File

@ -25,7 +25,8 @@ void MoveBuoysToWaypoints();
void MoveWaypointsToBaseStations(); void MoveWaypointsToBaseStations();
SaveLoadTable GetBaseStationDescription(); SaveLoadTable GetBaseStationDescription();
void AfterLoadVehicles(bool part_of_load); void AfterLoadVehiclesPhase1(bool part_of_load);
void AfterLoadVehiclesPhase2(bool part_of_load);
void AfterLoadVehiclesRemoveAnyFoundInvalid(); void AfterLoadVehiclesRemoveAnyFoundInvalid();
void AfterLoadEngines(); void AfterLoadEngines();
void FixupTrainLengths(); void FixupTrainLengths();

View File

@ -262,13 +262,13 @@ extern uint8_t _age_cargo_skip_counter; // From misc_sl.cpp
static std::vector<Vehicle *> _load_invalid_vehicles_to_delete; static std::vector<Vehicle *> _load_invalid_vehicles_to_delete;
/** Called after load to update coordinates */ /** Called after load for phase 1 of vehicle initialisation */
void AfterLoadVehicles(bool part_of_load) void AfterLoadVehiclesPhase1(bool part_of_load)
{ {
_load_invalid_vehicles_to_delete.clear(); _load_invalid_vehicles_to_delete.clear();
const Vehicle *si_v = nullptr; const Vehicle *si_v = nullptr;
SCOPE_INFO_FMT([&si_v], "AfterLoadVehicles: %s", scope_dumper().VehicleInfo(si_v)); SCOPE_INFO_FMT([&si_v], "AfterLoadVehiclesPhase1: %s", scope_dumper().VehicleInfo(si_v));
for (Vehicle *v : Vehicle::Iterate()) { for (Vehicle *v : Vehicle::Iterate()) {
si_v = v; si_v = v;
/* Reinstate the previous pointer */ /* Reinstate the previous pointer */
@ -420,15 +420,6 @@ void AfterLoadVehicles(bool part_of_load)
} }
} }
if (SlXvIsFeaturePresent(XSLFI_TEMPLATE_REPLACEMENT) && (_network_server || !_networking)) {
for (Train *t : Train::Iterate()) {
si_v = t;
if (t->IsVirtual() && t->First() == t) {
delete t;
}
}
}
if (IsSavegameVersionBefore(SLV_VEHICLE_ECONOMY_AGE) && SlXvIsFeatureMissing(XSLFI_VEHICLE_ECONOMY_AGE)) { if (IsSavegameVersionBefore(SLV_VEHICLE_ECONOMY_AGE) && SlXvIsFeatureMissing(XSLFI_VEHICLE_ECONOMY_AGE)) {
/* Set vehicle economy age based on calendar age. */ /* Set vehicle economy age based on calendar age. */
for (Vehicle *v : Vehicle::Iterate()) { for (Vehicle *v : Vehicle::Iterate()) {
@ -439,10 +430,16 @@ void AfterLoadVehicles(bool part_of_load)
si_v = nullptr; si_v = nullptr;
CheckValidVehicles(); CheckValidVehicles();
}
/** Called after load for phase 2 of vehicle initialisation */
void AfterLoadVehiclesPhase2(bool part_of_load)
{
const Vehicle *si_v = nullptr;
SCOPE_INFO_FMT([&si_v], "AfterLoadVehiclesPhase2: %s", scope_dumper().VehicleInfo(si_v));
for (Vehicle *v : Vehicle::IterateFrontOnly()) { for (Vehicle *v : Vehicle::IterateFrontOnly()) {
si_v = v; si_v = v;
assert(v->first != nullptr); assert(v->First() != nullptr);
v->trip_occupancy = CalcPercentVehicleFilled(v, nullptr); v->trip_occupancy = CalcPercentVehicleFilled(v, nullptr);
@ -498,6 +495,16 @@ void AfterLoadVehicles(bool part_of_load)
} }
} }
if (part_of_load && SlXvIsFeaturePresent(XSLFI_TEMPLATE_REPLACEMENT) && (_network_server || !_networking)) {
for (Train *t : Train::IterateFrontOnly()) {
si_v = t;
if (t->IsVirtual()) {
t->unitnumber = 0;
delete t;
}
}
}
/* Stop non-front engines */ /* Stop non-front engines */
if (part_of_load && IsSavegameVersionBefore(SLV_112)) { if (part_of_load && IsSavegameVersionBefore(SLV_112)) {
for (Vehicle *v : Vehicle::Iterate()) { for (Vehicle *v : Vehicle::Iterate()) {

View File

@ -323,7 +323,7 @@ private:
public: public:
friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code friend SaveLoadTable GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code
friend void FixOldVehicles(); friend void FixOldVehicles();
friend void AfterLoadVehicles(bool part_of_load); ///< So we can set the #previous and #first pointers while loading friend void AfterLoadVehiclesPhase1(bool part_of_load); ///< So we can set the #previous and #first pointers while loading
friend bool LoadOldVehicle(LoadgameState *ls, int num); ///< So we can set the proper next pointer while loading friend bool LoadOldVehicle(LoadgameState *ls, int num); ///< So we can set the proper next pointer while loading
friend upstream_sl::SlVehicleCommon; friend upstream_sl::SlVehicleCommon;