From 0de223c637d0820a97417d84796c1bfeb1836fb8 Mon Sep 17 00:00:00 2001 From: cc9cii Date: Fri, 11 Dec 2015 07:18:54 +1100 Subject: [PATCH] Fix bug (#3067) where content file number was being ignored while searching for already loaded cell references. - Introduced by commits 49884f54f7f00e1d4413b77eae3d6091043aa016 and 896ab44d1e919852aae03be9ecb71378f031b6f5. - Also see https://github.com/OpenMW/openmw/pull/557 --- apps/opencs/model/world/data.cpp | 29 +++++++++++++++++++++++ apps/opencs/model/world/data.hpp | 1 + apps/opencs/model/world/refcollection.cpp | 10 ++++---- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index d8916935da..64d317bd41 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -927,6 +927,35 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base mReader->setIndex(mReaderIndex++); mReader->open (path.string()); + mLoadedFiles.push_back(path.filename().string()); + + // at this point mReader->mHeader.mMaster have been populated for the file being loaded + for (size_t f = 0; f < mReader->getGameFiles().size(); ++f) + { + ESM::Header::MasterData& m = const_cast(mReader->getGameFiles().at(f)); + + int index = -1; + for (size_t i = 0; i < mLoadedFiles.size()-1; ++i) // -1 to ignore the current file + { + if (Misc::StringUtils::ciEqual(m.name, mLoadedFiles.at(i))) + { + index = static_cast(i); + break; + } + } + + if (index == -1) + { + // Tried to load a parent file that has not been loaded yet. This is bad, + // the launcher should have taken care of this. + std::string fstring = "File " + mReader->getName() + " asks for parent file " + m.name + + ", but it has not been loaded yet. Please check your load order."; + mReader->fail(fstring); + } + + m.index = index; + } + mBase = base; mProject = project; diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 88a431fb74..d1c0f1f543 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -106,6 +106,7 @@ namespace CSMWorld bool mProject; std::map > mRefLoadCache; int mReaderIndex; + std::vector mLoadedFiles; std::vector > mReaders; diff --git a/apps/opencs/model/world/refcollection.cpp b/apps/opencs/model/world/refcollection.cpp index f811131a19..3542a30bd0 100644 --- a/apps/opencs/model/world/refcollection.cpp +++ b/apps/opencs/model/world/refcollection.cpp @@ -71,7 +71,10 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool else ref.mCell = cell2.mId; - std::map::iterator iter = cache.find (ref.mRefNum.mIndex); + unsigned int refNum = (ref.mRefNum.mIndex & 0x00ffffff) | + (ref.mRefNum.hasContentFile() ? ref.mRefNum.mContentFile : 0xff) << 24; + + std::map::iterator iter = cache.find(refNum); if (isDeleted) { @@ -106,11 +109,10 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool // new reference ref.mId = getNewId(); + cache.insert(std::make_pair(refNum, ref.mId)); + std::unique_ptr > record(new Record); record->mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - - cache.insert (std::make_pair (ref.mRefNum.mIndex, ref.mId)); - (base ? record->mBase : record->mModified) = std::move(ref); appendRecord(std::move(record));