From 6575b95448c2daf22bff0ba11d7657562570882d Mon Sep 17 00:00:00 2001 From: cc9cii Date: Wed, 30 Jun 2021 15:34:40 +1000 Subject: [PATCH] Support moved references (i.e. with MVRF sub-records) that do not occur at the beginning of the cell references block. --- apps/openmw/mwworld/store.cpp | 52 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/apps/openmw/mwworld/store.cpp b/apps/openmw/mwworld/store.cpp index 944d311229..26b63d59a9 100644 --- a/apps/openmw/mwworld/store.cpp +++ b/apps/openmw/mwworld/store.cpp @@ -36,16 +36,16 @@ namespace MWWorld : mId(id), mIsDeleted(isDeleted) {} - template + template IndexedStore::IndexedStore() { } - template + template typename IndexedStore::iterator IndexedStore::begin() const { return mStatic.begin(); } - template + template typename IndexedStore::iterator IndexedStore::end() const { return mStatic.end(); @@ -192,7 +192,7 @@ namespace MWWorld template typename Store::iterator Store::begin() const { - return mShared.begin(); + return mShared.begin(); } template typename Store::iterator Store::end() const @@ -407,7 +407,7 @@ namespace MWWorld if (mStatic.size() < num) mStatic.resize(num); } - + // Land //========================================================================= Store::~Store() @@ -496,21 +496,29 @@ namespace MWWorld } return search(cell.mName); } + + // this method *must* be called right after esm.loadCell() void Store::handleMovedCellRefs(ESM::ESMReader& esm, ESM::Cell* cell) { - //Handling MovedCellRefs, there is no way to do it inside loadcell - while (esm.isNextSub("MVRF")) { - ESM::CellRef ref; - ESM::MovedCellRef cMRef; - cell->getNextMVRF(esm, cMRef); + ESM::CellRef ref; + ESM::MovedCellRef cMRef; + cMRef.mRefNum.mIndex = 0; + bool deleted = false; + + ESM::ESM_Context ctx = esm.getContext(); + + // Handling MovedCellRefs, there is no way to do it inside loadcell + // TODO: verify above comment + // + // Get regular moved reference data. Adapted from CellStore::loadRefs. Maybe we can optimize the following + // implementation when the oher implementation works as well. + while (cell->getNextRef(esm, ref, deleted, /*ignoreMoves*/true, &cMRef)) + { + if (!cMRef.mRefNum.mIndex) + continue; // ignore refs that are not moved ESM::Cell *cellAlt = const_cast(searchOrCreate(cMRef.mTarget[0], cMRef.mTarget[1])); - // Get regular moved reference data. Adapted from CellStore::loadRefs. Maybe we can optimize the following - // implementation when the oher implementation works as well. - bool deleted = false; - cell->getNextRef(esm, ref, deleted); - // Add data required to make reference appear in the correct cell. // We should not need to test for duplicates, as this part of the code is pre-cell merge. cell->mMovedRefs.push_back(cMRef); @@ -521,7 +529,11 @@ namespace MWWorld cellAlt->mLeasedRefs.emplace_back(std::move(ref), deleted); else *iter = std::make_pair(std::move(ref), deleted); + + cMRef.mRefNum.mIndex = 0; } + + esm.restoreContext(ctx); } const ESM::Cell *Store::search(const std::string &id) const { @@ -642,7 +654,7 @@ namespace MWWorld ESM::Cell cell; bool isDeleted = false; - // Load the (x,y) coordinates of the cell, if it is an exterior cell, + // Load the (x,y) coordinates of the cell, if it is an exterior cell, // so we can find the cell we need to merge with cell.loadNameAndData(esm, isDeleted); std::string idLower = Misc::StringUtils::lowerCase(cell.mName); @@ -870,7 +882,7 @@ namespace MWWorld return true; } - + // Pathgrid //========================================================================= @@ -972,7 +984,7 @@ namespace MWWorld // Skill //========================================================================= - + Store::Store() { } @@ -1013,7 +1025,7 @@ namespace MWWorld } void Store::setUp() { - for (int i = 0; i < ESM::Attribute::Length; ++i) + for (int i = 0; i < ESM::Attribute::Length; ++i) { ESM::Attribute newAttribute; newAttribute.mId = ESM::Attribute::sAttributeIds[i]; @@ -1035,7 +1047,7 @@ namespace MWWorld return mStatic.end(); } - + // Dialogue //=========================================================================