mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 06:53:53 +00:00
Don't trigger onNewExterior while loading saves
This commit is contained in:
parent
57adb93075
commit
152073a42e
4 changed files with 45 additions and 25 deletions
|
@ -630,6 +630,12 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
void Store<ESM::Cell>::clearDynamic()
|
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();
|
setUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -473,8 +473,8 @@ namespace MWWorld
|
||||||
|
|
||||||
mStore.write(writer, progress); // dynamic Store must be written (and read) before Cells, so that
|
mStore.write(writer, progress); // dynamic Store must be written (and read) before Cells, so that
|
||||||
// references to custom made records will be recognized
|
// 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);
|
mPlayer->write(writer, progress);
|
||||||
mWorldModel.write(writer, progress);
|
|
||||||
mGlobalVariables.write(writer, progress);
|
mGlobalVariables.write(writer, progress);
|
||||||
mWeatherManager->write(writer, progress);
|
mWeatherManager->write(writer, progress);
|
||||||
mProjectileManager->write(writer, progress);
|
mProjectileManager->write(writer, progress);
|
||||||
|
|
|
@ -101,6 +101,24 @@ namespace MWWorld
|
||||||
return Cell(*cell);
|
return Cell(*cell);
|
||||||
return std::nullopt;
|
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
|
CellStore& WorldModel::getExterior(ESM::ExteriorCellLocation location, bool forceLoad) const
|
||||||
{
|
{
|
||||||
const auto it = mExteriors.find(location);
|
CellStore* cellStore = getOrCreateExterior(location, mExteriors, mStore, mReaders, mCells, true);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (forceLoad && cellStore->getState() != CellStore::State_Loaded)
|
if (forceLoad && cellStore->getState() != CellStore::State_Loaded)
|
||||||
cellStore->load();
|
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:
|
public:
|
||||||
GetCellStoreCallback(MWWorld::WorldModel& worldModel)
|
GetCellStoreCallback(WorldModel& worldModel)
|
||||||
: mWorldModel(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)
|
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;
|
ESM::CellState state;
|
||||||
state.mId = reader.getCellId();
|
state.mId = reader.getCellId();
|
||||||
|
|
||||||
CellStore* const cellStore = findCell(state.mId);
|
GetCellStoreCallback callback(*this);
|
||||||
|
|
||||||
|
CellStore* const cellStore = callback.getCellStore(state.mId);
|
||||||
|
|
||||||
if (cellStore == nullptr)
|
if (cellStore == nullptr)
|
||||||
{
|
{
|
||||||
Log(Debug::Warning) << "Dropping state for cell " << state.mId << " (cell no longer exists)";
|
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)
|
if (cellStore->getState() != CellStore::State_Loaded)
|
||||||
cellStore->load();
|
cellStore->load();
|
||||||
|
|
||||||
GetCellStoreCallback callback(*this);
|
|
||||||
|
|
||||||
cellStore->readReferences(reader, &callback);
|
cellStore->readReferences(reader, &callback);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -104,6 +104,8 @@ namespace MWWorld
|
||||||
bool readRecord(ESM::ESMReader& reader, uint32_t type);
|
bool readRecord(ESM::ESMReader& reader, uint32_t type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct GetCellStoreCallback;
|
||||||
|
|
||||||
PtrRegistry mPtrRegistry; // defined before mCells because during destruction it should be the last
|
PtrRegistry mPtrRegistry; // defined before mCells because during destruction it should be the last
|
||||||
|
|
||||||
MWWorld::ESMStore& mStore;
|
MWWorld::ESMStore& mStore;
|
||||||
|
|
Loading…
Reference in a new issue