diff --git a/src/elrail.cpp b/src/elrail.cpp index 334a50042d..a7912abb0f 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -598,7 +598,11 @@ void DrawRailCatenary(const TileInfo *ti) void SettingsDisableElrail(int32_t new_value) { bool disable = (new_value != 0); + UpdateDisableElrailSettingState(disable, true); +} +void UpdateDisableElrailSettingState(bool disable, bool update_vehicles) +{ /* pick appropriate railtype for elrail engines depending on setting */ const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC; @@ -626,10 +630,12 @@ void SettingsDisableElrail(int32_t new_value) } /* Fix the total power and acceleration for trains */ - for (Train *t : Train::Iterate()) { - /* power and acceleration is cached only for front engines */ - if (t->IsFrontEngine()) { - t->ConsistChanged(CCF_TRACK); + if (update_vehicles) { + for (Train *t : Train::Iterate()) { + /* power and acceleration is cached only for front engines */ + if (t->IsFrontEngine()) { + t->ConsistChanged(CCF_TRACK); + } } } diff --git a/src/elrail_func.h b/src/elrail_func.h index 4de7292228..f45ee53904 100644 --- a/src/elrail_func.h +++ b/src/elrail_func.h @@ -37,5 +37,6 @@ void DrawRailCatenaryOnTunnel(const TileInfo *ti); void DrawRailCatenaryOnBridge(const TileInfo *ti); void SettingsDisableElrail(int32_t new_value); ///< _settings_game.disable_elrail callback +void UpdateDisableElrailSettingState(bool disable, bool update_vehicles); #endif /* ELRAIL_FUNC_H */ diff --git a/src/order_base.h b/src/order_base.h index b24fcee817..6352cace68 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -258,7 +258,7 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord); */ struct OrderList : OrderListPool::PoolItem<&_orderlist_pool> { 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. VehicleOrderID num_orders; ///< NOSAVE: How many orders there are in the list. diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index e1d06532bb..0744e1585f 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -828,8 +828,8 @@ bool AfterLoadGame() } } - /* Update all vehicles */ - AfterLoadVehicles(true); + /* Update all vehicles: Phase 1 */ + AfterLoadVehiclesPhase1(true); /* make sure there is a town in the game */ if (_game_mode == GM_NORMAL && Town::GetNumItems() == 0) { @@ -1356,11 +1356,6 @@ bool AfterLoadGame() break; } } - - for (Train *v : Train::Iterate()) { - if (v->IsFrontEngine() || v->IsFreeWagon()) v->ConsistChanged(CCF_TRACK); - } - } /* In version 16.1 of the savegame a company can decide if trains, which get @@ -1493,7 +1488,7 @@ bool AfterLoadGame() * preference of a user, let elrails enabled; it can be disabled manually */ if (IsSavegameVersionBefore(SLV_38)) _settings_game.vehicle.disable_elrails = false; /* 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(); /* From version 53, the map array was changed for house tiles to allow @@ -2815,9 +2810,6 @@ bool AfterLoadGame() } } - /* The center of train vehicles was changed, fix up spacing. */ - if (IsSavegameVersionBefore(SLV_164)) FixupTrainLengths(); - if (IsSavegameVersionBefore(SLV_165)) { for (Town *t : Town::Iterate()) { /* Set the default cargo requirement for town growth */ @@ -2925,6 +2917,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. * This has to be called after all map array updates */ if (IsSavegameVersionBefore(SLV_2, 2)) UpdateOldAircraft(); @@ -3342,7 +3342,8 @@ void ReloadNewGRFData() RecomputePrices(); /* reload vehicles */ ResetVehicleHash(); - AfterLoadVehicles(false); + AfterLoadVehiclesPhase1(false); + AfterLoadVehiclesPhase2(false); StartupEngines(); GroupStatistics::UpdateAfterLoad(); /* update station graphics */ diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h index e311c5c4aa..7e35000c7f 100644 --- a/src/saveload/saveload_internal.h +++ b/src/saveload/saveload_internal.h @@ -24,7 +24,8 @@ void ResetOldWaypoints(); void MoveBuoysToWaypoints(); void MoveWaypointsToBaseStations(); -void AfterLoadVehicles(bool part_of_load); +void AfterLoadVehiclesPhase1(bool part_of_load); +void AfterLoadVehiclesPhase2(bool part_of_load); void FixupTrainLengths(); void AfterLoadStations(); void AfterLoadRoadStops(); diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 4e42de3962..91936f387c 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -251,8 +251,8 @@ static void CheckValidVehicles() extern uint8_t _age_cargo_skip_counter; // From misc_sl.cpp -/** Called after load to update coordinates */ -void AfterLoadVehicles(bool part_of_load) +/** Called after load for phase 1 of vehicle initialisation */ +void AfterLoadVehiclesPhase1(bool part_of_load) { for (Vehicle *v : Vehicle::Iterate()) { /* Reinstate the previous pointer */ @@ -408,9 +408,13 @@ void AfterLoadVehicles(bool part_of_load) } CheckValidVehicles(); +} +/** Called after load for phase 2 of vehicle initialisation */ +void AfterLoadVehiclesPhase2(bool part_of_load) +{ for (Vehicle *v : Vehicle::Iterate()) { - assert(v->first != nullptr); + assert(v->First() != nullptr); v->trip_occupancy = CalcPercentVehicleFilled(v, nullptr); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index ac6392cf32..8243fdbd59 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -254,7 +254,7 @@ private: public: 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 /* So we can use private/protected variables in the saveload code */ friend class SlVehicleCommon;