From eb48f8724f27147a37faa210c1c3d5b2ff12a424 Mon Sep 17 00:00:00 2001 From: "florent.teppe" Date: Sun, 23 Apr 2023 00:12:24 +0200 Subject: [PATCH] change grid and preload takes the right exterior also fixes some crashes --- apps/openmw/mwworld/scene.cpp | 22 ++++++++++++---------- apps/openmw/mwworld/scene.hpp | 4 +++- apps/openmw/mwworld/worldimp.cpp | 9 +++++---- apps/openmw/mwworld/worldmodel.cpp | 1 - 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index c82c3f95b1..d0f755fece 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -305,7 +305,8 @@ namespace MWWorld if (mChangeCellGridRequest.has_value()) { changeCellGrid(mChangeCellGridRequest->mPosition, mChangeCellGridRequest->mCell.x(), - mChangeCellGridRequest->mCell.y(), mChangeCellGridRequest->mChangeEvent); + mChangeCellGridRequest->mCell.y(), mChangeCellGridRequest->exteriorWorldspace, + mChangeCellGridRequest->mChangeEvent); mChangeCellGridRequest.reset(); } @@ -531,10 +532,11 @@ namespace MWWorld void Scene::requestChangeCellGrid(const osg::Vec3f& position, const osg::Vec2i& cell, bool changeEvent) { - mChangeCellGridRequest = ChangeCellGridRequest{ position, cell, changeEvent }; + mChangeCellGridRequest = ChangeCellGridRequest{ position, cell, ESM::Cell::sDefaultWorldspaceId, changeEvent }; } - void Scene::changeCellGrid(const osg::Vec3f& pos, int playerCellX, int playerCellY, bool changeEvent) + void Scene::changeCellGrid( + const osg::Vec3f& pos, int playerCellX, int playerCellY, ESM::RefId exteriorWorldspace, bool changeEvent) { auto navigatorUpdateGuard = mNavigator.makeUpdateGuard(); @@ -551,10 +553,9 @@ namespace MWWorld else unloadCell(cell, navigatorUpdateGuard.get()); } - ESM::RefId currentWorldSpace = mCurrentCell->getCell()->getWorldSpace(); mNavigator.setWorldspace( Misc::StringUtils::lowerCase(mWorld.getWorldModel() - .getExterior(playerCellX, playerCellY, currentWorldSpace) + .getExterior(playerCellX, playerCellY, exteriorWorldspace) .getCell() ->getWorldSpace() .serializeText()), @@ -581,7 +582,7 @@ namespace MWWorld { if (!isCellInCollection(x, y, collection)) { - refsToLoad += mWorld.getWorldModel().getExterior(x, y, currentWorldSpace).count(); + refsToLoad += mWorld.getWorldModel().getExterior(x, y, exteriorWorldspace).count(); cellsPositionsToLoad.emplace_back(x, y); } } @@ -615,7 +616,7 @@ namespace MWWorld { if (!isCellInCollection(x, y, mActiveCells)) { - CellStore& cell = mWorld.getWorldModel().getExterior(x, y, currentWorldSpace); + CellStore& cell = mWorld.getWorldModel().getExterior(x, y, exteriorWorldspace); loadCell(cell, loadingListener, changeEvent, pos, navigatorUpdateGuard.get()); } } @@ -624,7 +625,7 @@ namespace MWWorld navigatorUpdateGuard.reset(); - CellStore& current = mWorld.getWorldModel().getExterior(playerCellX, playerCellY, currentWorldSpace); + CellStore& current = mWorld.getWorldModel().getExterior(playerCellX, playerCellY, exteriorWorldspace); MWBase::Environment::get().getWindowManager()->changeCell(¤t); if (changeEvent) @@ -934,7 +935,8 @@ namespace MWWorld const osg::Vec2i cellIndex(current.getCell()->getGridX(), current.getCell()->getGridY()); - changeCellGrid(position.asVec3(), cellIndex.x(), cellIndex.y(), changeEvent); + changeCellGrid( + position.asVec3(), cellIndex.x(), cellIndex.y(), current.getCell()->getWorldSpace(), changeEvent); changePlayerCell(current, position, adjustPlayerPos); @@ -1094,7 +1096,7 @@ namespace MWWorld mLastPlayerPos = playerPos; - if (mPreloadEnabled) + if (mPreloadEnabled && mCurrentCell->getCell()->getWorldSpace() == ESM::Cell::sDefaultWorldspaceId) { if (mPreloadDoors) preloadTeleportDoorDestinations(playerPos, predictedPos, exteriorPositions); diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index 06b4221332..2bc0aae145 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -80,6 +80,7 @@ namespace MWWorld { osg::Vec3f mPosition; osg::Vec2i mCell; + ESM::RefId exteriorWorldspace; bool mChangeEvent; }; @@ -117,7 +118,8 @@ namespace MWWorld osg::Vec2i mCurrentGridCenter; // Load and unload cells as necessary to create a cell grid with "X" and "Y" in the center - void changeCellGrid(const osg::Vec3f& pos, int playerCellX, int playerCellY, bool changeEvent = true); + void changeCellGrid(const osg::Vec3f& pos, int playerCellX, int playerCellY, ESM::RefId exteriorWorldspace, + bool changeEvent = true); void requestChangeCellGrid(const osg::Vec3f& position, const osg::Vec2i& cell, bool changeEvent = true); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index b5ab3f2b4b..8f38a9e081 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1268,12 +1268,13 @@ namespace MWWorld CellStore* cell = ptr.getCell(); ESM::RefId worldspaceId = cell->isExterior() ? cell->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId; - CellStore& newCell = mWorldModel.getExterior(index.x(), index.y(), worldspaceId); - bool isCellActive - = getPlayerPtr().isInCell() && getPlayerPtr().getCell()->isExterior() && mWorldScene->isCellActive(newCell); + CellStore* newCell + = cell->isExterior() ? &mWorldModel.getExterior(index.x(), index.y(), worldspaceId) : nullptr; + bool isCellActive = getPlayerPtr().isInCell() && getPlayerPtr().getCell()->isExterior() + && mWorldScene->isCellActive(*newCell); if (cell->isExterior() || (moveToActive && isCellActive && ptr.getClass().isActor())) - cell = &newCell; + cell = newCell; return moveObject(ptr, cell, position, movePhysics); } diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index ecc3a97cd3..90a065d9eb 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -208,7 +208,6 @@ MWWorld::CellStore& MWWorld::WorldModel::getExterior(int x, int y, ESM::RefId ex if (!cell) { ESM4::Cell record; - record.mId = MWBase::Environment::get().getESMStore()->generateId(); record.mParent = exteriorWorldspace; record.mX = x; record.mY = y;