From df6630a15c96e30ecded42106d8de4411fc61329 Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 26 May 2023 19:09:54 +0200 Subject: [PATCH 1/9] Move WorldModel private functions to bottom This is API class. A reader most likely need to know public functions first. --- apps/openmw/mwworld/worldmodel.hpp | 47 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwworld/worldmodel.hpp b/apps/openmw/mwworld/worldmodel.hpp index 300adbe2db..0cba5e526a 100644 --- a/apps/openmw/mwworld/worldmodel.hpp +++ b/apps/openmw/mwworld/worldmodel.hpp @@ -38,29 +38,6 @@ namespace MWWorld /// \brief Cell container class WorldModel { - typedef std::vector> IdCache; - const MWWorld::ESMStore& mStore; - ESM::ReadersCache& mReaders; - mutable std::unordered_map mCells; - mutable std::map mInteriors; - - mutable std::map mExteriors; - IdCache mIdCache; - std::size_t mIdCacheIndex = 0; - std::unordered_map mPtrIndex; - std::size_t mPtrIndexUpdateCounter = 0; - ESM::RefNum mLastGeneratedRefnum; - - CellStore& getOrInsertCellStore(const ESM::Cell& cell); - - CellStore& insertCellStore(const ESM::Cell& cell); - - CellStore* getInteriorOrNull(std::string_view name); - - Ptr getPtrAndCache(const ESM::RefId& name, CellStore& cellStore); - - void writeCell(ESM::ESMWriter& writer, CellStore& cell) const; - public: explicit WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCache& reader); @@ -111,6 +88,30 @@ namespace MWWorld void write(ESM::ESMWriter& writer, Loading::Listener& progress) const; bool readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap); + + private: + using IdCache = std::vector>; + + const MWWorld::ESMStore& mStore; + ESM::ReadersCache& mReaders; + mutable std::unordered_map mCells; + mutable std::map mInteriors; + mutable std::map mExteriors; + IdCache mIdCache; + std::size_t mIdCacheIndex = 0; + std::unordered_map mPtrIndex; + std::size_t mPtrIndexUpdateCounter = 0; + ESM::RefNum mLastGeneratedRefnum; + + CellStore& getOrInsertCellStore(const ESM::Cell& cell); + + CellStore& insertCellStore(const ESM::Cell& cell); + + CellStore* getInteriorOrNull(std::string_view name); + + Ptr getPtrAndCache(const ESM::RefId& name, CellStore& cellStore); + + void writeCell(ESM::ESMWriter& writer, CellStore& cell) const; }; } From a04eb9d26cfe4f253e52cb60117ee2388a6ece82 Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 26 May 2023 19:23:43 +0200 Subject: [PATCH 2/9] Move WorldModel::getPtr(const ESM::RefId&, CellStore&) to CellStore The function does not depend on WorldModel. --- apps/openmw/mwworld/cellstore.cpp | 19 +++++++++++++++++++ apps/openmw/mwworld/cellstore.hpp | 2 ++ apps/openmw/mwworld/worldimp.cpp | 2 +- apps/openmw/mwworld/worldmodel.cpp | 27 ++------------------------- apps/openmw/mwworld/worldmodel.hpp | 1 - 5 files changed, 24 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwworld/cellstore.cpp b/apps/openmw/mwworld/cellstore.cpp index c9be8c0a96..4036c378db 100644 --- a/apps/openmw/mwworld/cellstore.cpp +++ b/apps/openmw/mwworld/cellstore.cpp @@ -1283,4 +1283,23 @@ namespace MWWorld return {}; } + Ptr CellStore::getPtr(ESM::RefId id) + { + if (mState == CellStore::State_Unloaded) + preload(); + + if (mState == CellStore::State_Preloaded) + { + if (!std::binary_search(mIds.begin(), mIds.end(), id)) + return Ptr(); + load(); + } + + Ptr ptr = search(id); + + if (!ptr.isEmpty() && isAccessible(ptr.getRefData(), ptr.getCellRef())) + return ptr; + + return Ptr(); + } } diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 47867a63ff..f0690e13a1 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -322,6 +322,8 @@ namespace MWWorld Ptr getMovedActor(int actorId) const; + Ptr getPtr(ESM::RefId id); + bool operator==(const CellStore& right) const; private: diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 8d8eccf17b..0db747898f 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -695,7 +695,7 @@ namespace MWWorld { // TODO: caching still doesn't work efficiently here (only works for the one CellStore that the reference is // in) - Ptr ptr = mWorldModel.getPtr(name, *cellstore); + Ptr ptr = cellstore->getPtr(name); if (!ptr.isEmpty()) return ptr; diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 6a9d61b9f1..fe2ed4babe 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -116,7 +116,7 @@ MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefNum& refNum) const MWWorld::Ptr MWWorld::WorldModel::getPtrAndCache(const ESM::RefId& name, CellStore& cellStore) { - Ptr ptr = getPtr(name, cellStore); + Ptr ptr = cellStore.getPtr(name); if (!ptr.isEmpty() && ptr.isInCell()) { @@ -332,36 +332,13 @@ MWWorld::CellStore& MWWorld::WorldModel::getCellByPosition( return getExterior(cellIndex); } -MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name, CellStore& cell) -{ - if (cell.getState() == CellStore::State_Unloaded) - cell.preload(); - - if (cell.getState() == CellStore::State_Preloaded) - { - if (cell.hasId(name)) - { - cell.load(); - } - else - return Ptr(); - } - - Ptr ptr = cell.search(name); - - if (!ptr.isEmpty() && MWWorld::CellStore::isAccessible(ptr.getRefData(), ptr.getCellRef())) - return ptr; - - return Ptr(); -} - MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name) { // First check the cache for (IdCache::iterator iter(mIdCache.begin()); iter != mIdCache.end(); ++iter) if (iter->first == name && iter->second) { - Ptr ptr = getPtr(name, *iter->second); + Ptr ptr = iter->second->getPtr(name); if (!ptr.isEmpty()) return ptr; } diff --git a/apps/openmw/mwworld/worldmodel.hpp b/apps/openmw/mwworld/worldmodel.hpp index 0cba5e526a..24e6a8afed 100644 --- a/apps/openmw/mwworld/worldmodel.hpp +++ b/apps/openmw/mwworld/worldmodel.hpp @@ -66,7 +66,6 @@ namespace MWWorld Ptr getPtr(const ESM::RefNum& refNum) const; - Ptr getPtr(const ESM::RefId& name, CellStore& cellStore); Ptr getPtr(const ESM::RefId& name); template From b6cd6402cc862c3eb6871423e738a82d62a3b2a3 Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 26 May 2023 19:26:23 +0200 Subject: [PATCH 3/9] Use ranged for loop --- apps/openmw/mwworld/worldmodel.cpp | 22 +++++++++++----------- apps/openmw/mwworld/worldmodel.hpp | 4 +--- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index fe2ed4babe..10f72ef444 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -334,14 +334,14 @@ MWWorld::CellStore& MWWorld::WorldModel::getCellByPosition( MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name) { - // First check the cache - for (IdCache::iterator iter(mIdCache.begin()); iter != mIdCache.end(); ++iter) - if (iter->first == name && iter->second) - { - Ptr ptr = iter->second->getPtr(name); - if (!ptr.isEmpty()) - return ptr; - } + for (const auto& [cachedId, cellStore] : mIdCache) + { + if (cachedId != name || cellStore == nullptr) + continue; + Ptr ptr = cellStore->getPtr(name); + if (!ptr.isEmpty()) + return ptr; + } // Then check cells that are already listed // Search in reverse, this is a workaround for an ambiguous chargen_plank reference in the vanilla game. @@ -423,10 +423,10 @@ int MWWorld::WorldModel::countSavedGameRecords() const void MWWorld::WorldModel::write(ESM::ESMWriter& writer, Loading::Listener& progress) const { - for (auto iter(mCells.begin()); iter != mCells.end(); ++iter) - if (iter->second.hasState()) + for (auto& [id, cellStore] : mCells) + if (cellStore.hasState()) { - writeCell(writer, iter->second); + writeCell(writer, cellStore); progress.increaseProgress(); } } diff --git a/apps/openmw/mwworld/worldmodel.hpp b/apps/openmw/mwworld/worldmodel.hpp index 24e6a8afed..496537fdf3 100644 --- a/apps/openmw/mwworld/worldmodel.hpp +++ b/apps/openmw/mwworld/worldmodel.hpp @@ -89,14 +89,12 @@ namespace MWWorld bool readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap); private: - using IdCache = std::vector>; - const MWWorld::ESMStore& mStore; ESM::ReadersCache& mReaders; mutable std::unordered_map mCells; mutable std::map mInteriors; mutable std::map mExteriors; - IdCache mIdCache; + std::vector> mIdCache; std::size_t mIdCacheIndex = 0; std::unordered_map mPtrIndex; std::size_t mPtrIndexUpdateCounter = 0; From 98e80d65b02e184de8e0683254746cbe104ad724 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 27 May 2023 00:11:27 +0200 Subject: [PATCH 4/9] Remove unused include --- apps/openmw/mwworld/worldmodel.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 10f72ef444..19110fb31a 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -13,7 +13,6 @@ #include #include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" #include "cellstore.hpp" #include "esmstore.hpp" From 235eb65c972a31d7525ffcb2cdc42ca554ad7d5a Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 27 May 2023 01:18:17 +0200 Subject: [PATCH 5/9] Rename positionToCellIndex to match return type --- apps/openmw/mwgui/mapwindow.cpp | 2 +- apps/openmw/mwgui/travelwindow.cpp | 4 ++-- apps/openmw/mwscript/transformationextensions.cpp | 8 ++++---- apps/openmw/mwworld/cellref.cpp | 2 +- apps/openmw/mwworld/scene.cpp | 5 +++-- apps/openmw/mwworld/store.cpp | 4 ++-- apps/openmw/mwworld/worldimp.cpp | 7 ++++--- apps/openmw/mwworld/worldmodel.cpp | 3 ++- components/esm/util.hpp | 2 +- 9 files changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwgui/mapwindow.cpp b/apps/openmw/mwgui/mapwindow.cpp index 9adc43d315..3714ecef64 100644 --- a/apps/openmw/mwgui/mapwindow.cpp +++ b/apps/openmw/mwgui/mapwindow.cpp @@ -275,7 +275,7 @@ namespace MWGui if (!mInterior) { - ESM::ExteriorCellLocation cellPos = ESM::positionToCellIndex(worldX, worldY); + ESM::ExteriorCellLocation cellPos = ESM::positionToExteriorCellLocation(worldX, worldY); cellIndex.x() = cellPos.mX; cellIndex.y() = cellPos.mY; diff --git a/apps/openmw/mwgui/travelwindow.cpp b/apps/openmw/mwgui/travelwindow.cpp index c83caa0dc5..2c3310b891 100644 --- a/apps/openmw/mwgui/travelwindow.cpp +++ b/apps/openmw/mwgui/travelwindow.cpp @@ -126,7 +126,7 @@ namespace MWGui std::string_view cellname = transport[i].mCellName; bool interior = true; const ESM::ExteriorCellLocation cellIndex - = ESM::positionToCellIndex(transport[i].mPos.pos[0], transport[i].mPos.pos[1]); + = ESM::positionToExteriorCellLocation(transport[i].mPos.pos[0], transport[i].mPos.pos[1]); if (cellname.empty()) { MWWorld::CellStore& cell = MWBase::Environment::get().getWorldModel()->getExterior(cellIndex); @@ -192,7 +192,7 @@ namespace MWGui MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); MWBase::Environment::get().getWindowManager()->fadeScreenOut(1); - const ESM::ExteriorCellLocation posCell = ESM::positionToCellIndex(pos.pos[0], pos.pos[1]); + const ESM::ExteriorCellLocation posCell = ESM::positionToExteriorCellLocation(pos.pos[0], pos.pos[1]); ESM::RefId cellId = ESM::Cell::generateIdForCell(!interior, cellname, posCell.mX, posCell.mY); // Teleports any followers, too. diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index bf9fe14298..879cf85144 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -402,7 +402,7 @@ namespace MWScript if (store->isExterior()) { const ESM::ExteriorCellLocation cellIndex - = ESM::positionToCellIndex(x, y, store->getCell()->getWorldSpace()); + = ESM::positionToExteriorCellLocation(x, y, store->getCell()->getWorldSpace()); store = &worldModel->getExterior(cellIndex); } } @@ -418,7 +418,7 @@ namespace MWScript if (!isPlayer) return; const ESM::ExteriorCellLocation cellIndex - = ESM::positionToCellIndex(x, y, store->getCell()->getWorldSpace()); + = ESM::positionToExteriorCellLocation(x, y, store->getCell()->getWorldSpace()); store = &worldModel->getExterior(cellIndex); } if (store) @@ -469,7 +469,7 @@ namespace MWScript if (isPlayer) world->getPlayer().setTeleported(true); const ESM::ExteriorCellLocation cellIndex - = ESM::positionToCellIndex(x, y, ESM::Cell::sDefaultWorldspaceId); + = ESM::positionToExteriorCellLocation(x, y, ESM::Cell::sDefaultWorldspaceId); // another morrowind oddity: player will be moved to the exterior cell at this location, // non-player actors will move within the cell they are in. @@ -570,7 +570,7 @@ namespace MWScript if (player.getCell()->isExterior()) { const ESM::ExteriorCellLocation cellIndex - = ESM::positionToCellIndex(x, y, player.getCell()->getCell()->getWorldSpace()); + = ESM::positionToExteriorCellLocation(x, y, player.getCell()->getCell()->getWorldSpace()); store = &MWBase::Environment::get().getWorldModel()->getExterior(cellIndex); } else diff --git a/apps/openmw/mwworld/cellref.cpp b/apps/openmw/mwworld/cellref.cpp index 3e81ba1c37..6b9494b24f 100644 --- a/apps/openmw/mwworld/cellref.cpp +++ b/apps/openmw/mwworld/cellref.cpp @@ -88,7 +88,7 @@ namespace MWWorld } else { - const auto cellPos = ESM::positionToCellIndex(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]); + const auto cellPos = ESM::positionToExteriorCellLocation(ref.mDoorDest.pos[0], ref.mDoorDest.pos[1]); return ESM::RefId::esm3ExteriorCell(cellPos.mX, cellPos.mY); } }; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index b116fbe633..5112fad252 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -521,7 +521,7 @@ namespace MWWorld if (distance <= maxDistance) return *currentGridCenter; } - ESM::ExteriorCellLocation cellPos = ESM::positionToCellIndex(pos.x(), pos.y(), worldspace); + ESM::ExteriorCellLocation cellPos = ESM::positionToExteriorCellLocation(pos.x(), pos.y(), worldspace); return { cellPos.mX, cellPos.mY }; } @@ -1283,7 +1283,8 @@ namespace MWWorld else { osg::Vec3f pos = dest.mPos.asVec3(); - const ESM::ExteriorCellLocation cellIndex = ESM::positionToCellIndex(pos.x(), pos.y(), extWorldspace); + const ESM::ExteriorCellLocation cellIndex + = ESM::positionToExteriorCellLocation(pos.x(), pos.y(), extWorldspace); preloadCell(mWorld.getWorldModel().getExterior(cellIndex), true); exteriorPositions.emplace_back(pos, gridCenterToBounds(getNewGridCenter(pos))); } diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index ec984e030d..e2bd7cafb2 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -1166,8 +1166,8 @@ namespace MWWorld const ESM4::Cell* cell = cells.find(ref.mParent); if (cell->isExterior() && (cell->mFlags & ESM4::Rec_Persistent)) { - const ESM4::Cell* actualCell - = cells.searchExterior(positionToCellIndex(ref.mPos.pos[0], ref.mPos.pos[1], cell->mParent)); + const ESM4::Cell* actualCell = cells.searchExterior( + positionToExteriorCellLocation(ref.mPos.pos[0], ref.mPos.pos[1], cell->mParent)); if (actualCell) ref.mParent = actualCell->mId; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 0db747898f..349215460c 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -380,7 +380,7 @@ namespace MWWorld pos.rot[1] = 0; pos.rot[2] = 0; - ESM::ExteriorCellLocation exteriorCellPos = ESM::positionToCellIndex(pos.pos[0], pos.pos[1]); + ESM::ExteriorCellLocation exteriorCellPos = ESM::positionToExteriorCellLocation(pos.pos[0], pos.pos[1]); ESM::RefId cellId = ESM::RefId::esm3ExteriorCell(exteriorCellPos.mX, exteriorCellPos.mY); mWorldScene->changeToExteriorCell(cellId, pos, true); } @@ -1248,7 +1248,8 @@ namespace MWWorld CellStore* cell = ptr.getCell(); ESM::RefId worldspaceId = cell->isExterior() ? cell->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId; - const ESM::ExteriorCellLocation index = ESM::positionToCellIndex(position.x(), position.y(), worldspaceId); + const ESM::ExteriorCellLocation index + = ESM::positionToExteriorCellLocation(position.x(), position.y(), worldspaceId); CellStore* newCell = cell->isExterior() ? &mWorldModel.getExterior(index) : nullptr; bool isCellActive = getPlayerPtr().isInCell() && getPlayerPtr().getCell()->isExterior() @@ -2047,7 +2048,7 @@ namespace MWWorld if (cell->isExterior()) { const ESM::ExteriorCellLocation index - = ESM::positionToCellIndex(pos.pos[0], pos.pos[1], cell->getCell()->getWorldSpace()); + = ESM::positionToExteriorCellLocation(pos.pos[0], pos.pos[1], cell->getCell()->getWorldSpace()); cell = &mWorldModel.getExterior(index); } diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 19110fb31a..3423cf06d1 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -326,7 +326,8 @@ MWWorld::CellStore& MWWorld::WorldModel::getCellByPosition( return *cellInSameWorldSpace; ESM::RefId exteriorWorldspace = cellInSameWorldSpace ? cellInSameWorldSpace->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId; - const ESM::ExteriorCellLocation cellIndex = ESM::positionToCellIndex(pos.x(), pos.y(), exteriorWorldspace); + const ESM::ExteriorCellLocation cellIndex + = ESM::positionToExteriorCellLocation(pos.x(), pos.y(), exteriorWorldspace); return getExterior(cellIndex); } diff --git a/components/esm/util.hpp b/components/esm/util.hpp index 6edf087854..ac687fea4b 100644 --- a/components/esm/util.hpp +++ b/components/esm/util.hpp @@ -83,7 +83,7 @@ namespace ESM return isEsm4Ext(worldspaceId) ? Constants::ESM4CellSizeInUnits : Constants::CellSizeInUnits; } - inline ESM::ExteriorCellLocation positionToCellIndex( + inline ESM::ExteriorCellLocation positionToExteriorCellLocation( float x, float y, ESM::RefId worldspaceId = ESM::Cell::sDefaultWorldspaceId) { const float cellSize = getCellSize(worldspaceId); From 183202cd659e74b9a9885bf2cd75e02565ece6bb Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 27 May 2023 01:25:35 +0200 Subject: [PATCH 6/9] Remove WorldModel::getCellByPosition function It's used in a single place. Move the code there. --- apps/openmw/mwlua/objectbindings.cpp | 6 +++++- apps/openmw/mwworld/worldmodel.cpp | 13 ------------- apps/openmw/mwworld/worldmodel.hpp | 6 ------ 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwlua/objectbindings.cpp b/apps/openmw/mwlua/objectbindings.cpp index 177bdc77b6..5e5c380469 100644 --- a/apps/openmw/mwlua/objectbindings.cpp +++ b/apps/openmw/mwlua/objectbindings.cpp @@ -67,7 +67,11 @@ namespace MWLua else cell = &wm->getCell(name); } - return &wm->getCellByPosition(pos, cell); + if (cell != nullptr && !cell->isExterior()) + return cell; + const ESM::RefId worldspace + = cell == nullptr ? ESM::Cell::sDefaultWorldspaceId : cell->getCell()->getWorldSpace(); + return &wm->getExterior(ESM::positionToExteriorCellLocation(pos.x(), pos.y(), worldspace)); } void teleportPlayer( diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 3423cf06d1..7b8b63c3a0 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -319,19 +319,6 @@ MWWorld::CellStore& MWWorld::WorldModel::getCell(std::string_view name, bool for ESM::ExteriorCellLocation(cell->getGridX(), cell->getGridY(), ESM::Cell::sDefaultWorldspaceId), forceLoad); } -MWWorld::CellStore& MWWorld::WorldModel::getCellByPosition( - const osg::Vec3f& pos, MWWorld::CellStore* cellInSameWorldSpace) -{ - if (cellInSameWorldSpace && !cellInSameWorldSpace->isExterior()) - return *cellInSameWorldSpace; - ESM::RefId exteriorWorldspace - = cellInSameWorldSpace ? cellInSameWorldSpace->getCell()->getWorldSpace() : ESM::Cell::sDefaultWorldspaceId; - const ESM::ExteriorCellLocation cellIndex - = ESM::positionToExteriorCellLocation(pos.x(), pos.y(), exteriorWorldspace); - - return getExterior(cellIndex); -} - MWWorld::Ptr MWWorld::WorldModel::getPtr(const ESM::RefId& name) { for (const auto& [cachedId, cellStore] : mIdCache) diff --git a/apps/openmw/mwworld/worldmodel.hpp b/apps/openmw/mwworld/worldmodel.hpp index 496537fdf3..49ff54ce27 100644 --- a/apps/openmw/mwworld/worldmodel.hpp +++ b/apps/openmw/mwworld/worldmodel.hpp @@ -51,12 +51,6 @@ namespace MWWorld CellStore& getCell(std::string_view name, bool forceLoad = true); // interior or named exterior CellStore& getCell(const ESM::RefId& Id, bool forceLoad = true); - // Returns the cell that is in the same worldspace as `cellInSameWorldSpace` - // (in case of nullptr - default exterior worldspace) and contains given position. - // Interiors are single-cell worldspaces, so in case of an interior it just returns - // the same cell. - CellStore& getCellByPosition(const osg::Vec3f& pos, CellStore* cellInSameWorldSpace = nullptr); - void registerPtr(const MWWorld::Ptr& ptr); void deregisterPtr(const MWWorld::Ptr& ptr); ESM::RefNum getLastGeneratedRefNum() const { return mLastGeneratedRefnum; } From 60139c6bd595ffca61036f8fe01a50b714ed1e88 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 27 May 2023 14:37:57 +0200 Subject: [PATCH 7/9] Use WorldModel::mStore instead of MWBase::Environment::get().getESMStore() --- apps/openmw/mwworld/worldmodel.cpp | 8 +++----- apps/openmw/mwworld/worldmodel.hpp | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 7b8b63c3a0..8f94bc9e83 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -12,8 +12,6 @@ #include #include -#include "../mwbase/environment.hpp" - #include "cellstore.hpp" #include "esmstore.hpp" @@ -146,7 +144,7 @@ void MWWorld::WorldModel::writeCell(ESM::ESMWriter& writer, CellStore& cell) con writer.endRecord(ESM::REC_CSTA); } -MWWorld::WorldModel::WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCache& readers) +MWWorld::WorldModel::WorldModel(MWWorld::ESMStore& store, ESM::ReadersCache& readers) : mStore(store) , mReaders(readers) , mIdCache(Settings::cells().mPointersCacheSize, { ESM::RefId(), nullptr }) @@ -176,7 +174,7 @@ MWWorld::CellStore& MWWorld::WorldModel::getExterior(ESM::ExteriorCellLocation c record.mMapColor = 0; record.updateId(); - cell = MWBase::Environment::get().getESMStore()->insert(record); + cell = mStore.insert(record); } CellStore* cellStore @@ -197,7 +195,7 @@ MWWorld::CellStore& MWWorld::WorldModel::getExterior(ESM::ExteriorCellLocation c record.mX = cellIndex.mX; record.mY = cellIndex.mY; record.mCellFlags = !ESM4::CELL_Interior; - cell = MWBase::Environment::get().getESMStore()->insert(record); + cell = mStore.insert(record); } CellStore* cellStore = &mCells.emplace(cell->mId, CellStore(MWWorld::Cell(*cell), mStore, mReaders)).first->second; diff --git a/apps/openmw/mwworld/worldmodel.hpp b/apps/openmw/mwworld/worldmodel.hpp index 49ff54ce27..a83e29dd83 100644 --- a/apps/openmw/mwworld/worldmodel.hpp +++ b/apps/openmw/mwworld/worldmodel.hpp @@ -39,7 +39,7 @@ namespace MWWorld class WorldModel { public: - explicit WorldModel(const MWWorld::ESMStore& store, ESM::ReadersCache& reader); + explicit WorldModel(ESMStore& store, ESM::ReadersCache& reader); WorldModel(const WorldModel&) = delete; WorldModel& operator=(const WorldModel&) = delete; @@ -83,7 +83,7 @@ namespace MWWorld bool readRecord(ESM::ESMReader& reader, uint32_t type, const std::map& contentFileMap); private: - const MWWorld::ESMStore& mStore; + MWWorld::ESMStore& mStore; ESM::ReadersCache& mReaders; mutable std::unordered_map mCells; mutable std::map mInteriors; From 3a66854c3ceb6e0ba2a3e46b3b9048d1c32e6827 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 27 May 2023 14:39:23 +0200 Subject: [PATCH 8/9] Avoid confusion for generated cell flags --- apps/openmw/mwworld/worldmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 8f94bc9e83..42ad029bdc 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -194,7 +194,7 @@ MWWorld::CellStore& MWWorld::WorldModel::getExterior(ESM::ExteriorCellLocation c record.mParent = cellIndex.mWorldspace; record.mX = cellIndex.mX; record.mY = cellIndex.mY; - record.mCellFlags = !ESM4::CELL_Interior; + record.mCellFlags = 0; cell = mStore.insert(record); } CellStore* cellStore From d98852fdbe05882fa3df8cc68e7d0d1aa27b3ed4 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 27 May 2023 14:56:28 +0200 Subject: [PATCH 9/9] Use std::count_if to implement WorldModel::countSavedGameRecords --- apps/openmw/mwworld/worldmodel.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwworld/worldmodel.cpp b/apps/openmw/mwworld/worldmodel.cpp index 42ad029bdc..ca69a7ff39 100644 --- a/apps/openmw/mwworld/worldmodel.cpp +++ b/apps/openmw/mwworld/worldmodel.cpp @@ -1,5 +1,7 @@ #include "worldmodel.hpp" +#include + #include #include #include @@ -397,13 +399,7 @@ std::vector MWWorld::WorldModel::getAll(const ESM::RefId& id) int MWWorld::WorldModel::countSavedGameRecords() const { - int count = 0; - - for (auto iter(mCells.begin()); iter != mCells.end(); ++iter) - if (iter->second.hasState()) - ++count; - - return count; + return std::count_if(mCells.begin(), mCells.end(), [](const auto& v) { return v.second.hasState(); }); } void MWWorld::WorldModel::write(ESM::ESMWriter& writer, Loading::Listener& progress) const