Merge branch 'themawithungers' into 'master'

Don't trigger onNewExterior while loading saves

See merge request OpenMW/openmw!4206
pull/3236/head
psi29a 6 months ago
commit e9343da7a8

@ -630,6 +630,12 @@ namespace MWWorld
}
void Store<ESM::Cell>::clearDynamic()
{
for (const auto& [_, cell] : mDynamicExt)
mCells.erase(cell->mId);
mDynamicExt.clear();
for (const auto& [_, cell] : mDynamicInt)
mCells.erase(cell->mId);
mDynamicInt.clear();
setUp();
}

@ -473,8 +473,8 @@ namespace MWWorld
mStore.write(writer, progress); // dynamic Store must be written (and read) before Cells, so that
// references to custom made records will be recognized
mWorldModel.write(writer, progress); // the player's cell needs to be loaded before the player
mPlayer->write(writer, progress);
mWorldModel.write(writer, progress);
mGlobalVariables.write(writer, progress);
mWeatherManager->write(writer, progress);
mProjectileManager->write(writer, progress);

@ -101,6 +101,24 @@ namespace MWWorld
return Cell(*cell);
return std::nullopt;
}
CellStore* getOrCreateExterior(const ESM::ExteriorCellLocation& location,
std::map<ESM::ExteriorCellLocation, MWWorld::CellStore*>& exteriors, ESMStore& store,
ESM::ReadersCache& readers, std::unordered_map<ESM::RefId, CellStore>& cells, bool triggerEvent)
{
if (const auto it = exteriors.find(location); it != exteriors.end())
{
assert(it->second != nullptr);
return it->second;
}
auto [cell, created] = createExteriorCell(location, store);
const ESM::RefId id = cell.getId();
CellStore* const cellStore = &emplaceCellStore(id, std::move(cell), store, readers, cells);
exteriors.emplace(location, cellStore);
if (created && triggerEvent)
MWBase::Environment::get().getLuaManager()->exteriorCreated(*cellStore);
return cellStore;
}
}
}
@ -178,23 +196,7 @@ namespace MWWorld
{
CellStore& WorldModel::getExterior(ESM::ExteriorCellLocation location, bool forceLoad) const
{
const auto it = mExteriors.find(location);
CellStore* cellStore = nullptr;
if (it == mExteriors.end())
{
auto [cell, created] = createExteriorCell(location, mStore);
const ESM::RefId id = cell.getId();
cellStore = &emplaceCellStore(id, std::move(cell), mStore, mReaders, mCells);
mExteriors.emplace(location, cellStore);
if (created)
MWBase::Environment::get().getLuaManager()->exteriorCreated(*cellStore);
}
else
{
assert(it->second != nullptr);
cellStore = it->second;
}
CellStore* cellStore = getOrCreateExterior(location, mExteriors, mStore, mReaders, mCells, true);
if (forceLoad && cellStore->getState() != CellStore::State_Loaded)
cellStore->load();
@ -447,17 +449,26 @@ void MWWorld::WorldModel::write(ESM::ESMWriter& writer, Loading::Listener& progr
}
}
struct GetCellStoreCallback : public MWWorld::CellStore::GetCellStoreCallback
struct MWWorld::WorldModel::GetCellStoreCallback : public CellStore::GetCellStoreCallback
{
public:
GetCellStoreCallback(MWWorld::WorldModel& worldModel)
GetCellStoreCallback(WorldModel& worldModel)
: mWorldModel(worldModel)
{
}
MWWorld::WorldModel& mWorldModel;
WorldModel& mWorldModel;
MWWorld::CellStore* getCellStore(const ESM::RefId& cellId) override { return mWorldModel.findCell(cellId); }
CellStore* getCellStore(const ESM::RefId& cellId) override
{
if (const auto* exteriorId = cellId.getIf<ESM::ESM3ExteriorCellRefId>())
{
ESM::ExteriorCellLocation location(exteriorId->getX(), exteriorId->getY(), ESM::Cell::sDefaultWorldspaceId);
return getOrCreateExterior(
location, mWorldModel.mExteriors, mWorldModel.mStore, mWorldModel.mReaders, mWorldModel.mCells, false);
}
return mWorldModel.findCell(cellId);
}
};
bool MWWorld::WorldModel::readRecord(ESM::ESMReader& reader, uint32_t type)
@ -467,7 +478,10 @@ bool MWWorld::WorldModel::readRecord(ESM::ESMReader& reader, uint32_t type)
ESM::CellState state;
state.mId = reader.getCellId();
CellStore* const cellStore = findCell(state.mId);
GetCellStoreCallback callback(*this);
CellStore* const cellStore = callback.getCellStore(state.mId);
if (cellStore == nullptr)
{
Log(Debug::Warning) << "Dropping state for cell " << state.mId << " (cell no longer exists)";
@ -484,8 +498,6 @@ bool MWWorld::WorldModel::readRecord(ESM::ESMReader& reader, uint32_t type)
if (cellStore->getState() != CellStore::State_Loaded)
cellStore->load();
GetCellStoreCallback callback(*this);
cellStore->readReferences(reader, &callback);
return true;

@ -104,6 +104,8 @@ namespace MWWorld
bool readRecord(ESM::ESMReader& reader, uint32_t type);
private:
struct GetCellStoreCallback;
PtrRegistry mPtrRegistry; // defined before mCells because during destruction it should be the last
MWWorld::ESMStore& mStore;

Loading…
Cancel
Save