diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 0bd686ce7f..bbf15312d3 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -436,6 +436,7 @@ namespace MWWorld mLevitationEnabled = true; mPlayerTraveling = false; mPlayerInJail = false; + mIdsRebuilt = false; fillGlobalVariables(); } @@ -507,11 +508,11 @@ namespace MWWorld } break; case ESM::REC_PLAY: - // World::write always puts `ESM::REC_PLAY` between ESMStore (that contains dynamic records) - // and WorldModel (that can contain instances of dynamic records). Here we need to rebuild - // ESMStore index in order to be able to lookup dynamic records while loading the player and - // WorldModel. - mStore.rebuildIdsIndex(); + if (reader.getFormatVersion() <= ESM::MaxPlayerBeforeCellDataFormatVersion && !mIdsRebuilt) + { + mStore.rebuildIdsIndex(); + mIdsRebuilt = true; + } mStore.checkPlayer(); mPlayer->readRecord(reader, type); @@ -523,10 +524,19 @@ namespace MWWorld mWorldScene->preloadCellWithSurroundings(*getPlayerPtr().getCell()); } break; + case ESM::REC_CSTA: + // We need to rebuild the ESMStore index in order to be able to lookup dynamic records while loading the + // WorldModel and, afterwards, the player. + if (!mIdsRebuilt) + { + mStore.rebuildIdsIndex(); + mIdsRebuilt = true; + } + mWorldModel.readRecord(reader, type); + break; default: if (!mStore.readRecord(reader, type) && !mGlobalVariables.readRecord(reader, type) - && !mWeatherManager->readRecord(reader, type) && !mWorldModel.readRecord(reader, type) - && !mProjectileManager->readRecord(reader, type)) + && !mWeatherManager->readRecord(reader, type) && !mProjectileManager->readRecord(reader, type)) { throw std::runtime_error("unknown record in saved game"); } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 20e33ad66c..f4c22e94d3 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -134,6 +134,7 @@ namespace MWWorld ///< only holds doors that are currently moving. 1 = opening, 2 = closing uint32_t mRandomSeed{}; + bool mIdsRebuilt{}; // not implemented World(const World&) = delete; diff --git a/components/esm3/formatversion.hpp b/components/esm3/formatversion.hpp index 36e43728e2..b09a42cae5 100644 --- a/components/esm3/formatversion.hpp +++ b/components/esm3/formatversion.hpp @@ -27,7 +27,8 @@ namespace ESM inline constexpr FormatVersion MaxActiveSpellSlotIndexFormatVersion = 27; inline constexpr FormatVersion MaxOldCountFormatVersion = 30; inline constexpr FormatVersion MaxActiveSpellTypeVersion = 31; - inline constexpr FormatVersion CurrentSaveGameFormatVersion = 32; + inline constexpr FormatVersion MaxPlayerBeforeCellDataFormatVersion = 32; + inline constexpr FormatVersion CurrentSaveGameFormatVersion = 33; inline constexpr FormatVersion MinSupportedSaveGameFormatVersion = 5; inline constexpr FormatVersion OpenMW0_48SaveGameFormatVersion = 21;