Merge branch 'thedreughtookmyenchantmentsandarentgivingthemback' into 'master'

Rebuild ESMStore indices before loading any cell or player state

See merge request OpenMW/openmw!4278
pull/3236/head
psi29a 5 months ago
commit 79a9f8c23c

@ -436,6 +436,7 @@ namespace MWWorld
mLevitationEnabled = true; mLevitationEnabled = true;
mPlayerTraveling = false; mPlayerTraveling = false;
mPlayerInJail = false; mPlayerInJail = false;
mIdsRebuilt = false;
fillGlobalVariables(); fillGlobalVariables();
} }
@ -507,11 +508,11 @@ namespace MWWorld
} }
break; break;
case ESM::REC_PLAY: case ESM::REC_PLAY:
// World::write always puts `ESM::REC_PLAY` between ESMStore (that contains dynamic records) if (reader.getFormatVersion() <= ESM::MaxPlayerBeforeCellDataFormatVersion && !mIdsRebuilt)
// 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 mStore.rebuildIdsIndex();
// WorldModel. mIdsRebuilt = true;
mStore.rebuildIdsIndex(); }
mStore.checkPlayer(); mStore.checkPlayer();
mPlayer->readRecord(reader, type); mPlayer->readRecord(reader, type);
@ -523,10 +524,19 @@ namespace MWWorld
mWorldScene->preloadCellWithSurroundings(*getPlayerPtr().getCell()); mWorldScene->preloadCellWithSurroundings(*getPlayerPtr().getCell());
} }
break; 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: default:
if (!mStore.readRecord(reader, type) && !mGlobalVariables.readRecord(reader, type) if (!mStore.readRecord(reader, type) && !mGlobalVariables.readRecord(reader, type)
&& !mWeatherManager->readRecord(reader, type) && !mWorldModel.readRecord(reader, type) && !mWeatherManager->readRecord(reader, type) && !mProjectileManager->readRecord(reader, type))
&& !mProjectileManager->readRecord(reader, type))
{ {
throw std::runtime_error("unknown record in saved game"); throw std::runtime_error("unknown record in saved game");
} }

@ -134,6 +134,7 @@ namespace MWWorld
///< only holds doors that are currently moving. 1 = opening, 2 = closing ///< only holds doors that are currently moving. 1 = opening, 2 = closing
uint32_t mRandomSeed{}; uint32_t mRandomSeed{};
bool mIdsRebuilt{};
// not implemented // not implemented
World(const World&) = delete; World(const World&) = delete;

@ -27,7 +27,8 @@ namespace ESM
inline constexpr FormatVersion MaxActiveSpellSlotIndexFormatVersion = 27; inline constexpr FormatVersion MaxActiveSpellSlotIndexFormatVersion = 27;
inline constexpr FormatVersion MaxOldCountFormatVersion = 30; inline constexpr FormatVersion MaxOldCountFormatVersion = 30;
inline constexpr FormatVersion MaxActiveSpellTypeVersion = 31; 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 MinSupportedSaveGameFormatVersion = 5;
inline constexpr FormatVersion OpenMW0_48SaveGameFormatVersion = 21; inline constexpr FormatVersion OpenMW0_48SaveGameFormatVersion = 21;

Loading…
Cancel
Save