From 3ae2fc17c6b6cbe5d1ac95d53eb7e65adf22c145 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 29 Aug 2016 18:06:56 -0400 Subject: [PATCH 1/2] Fix some issues with content file numbers in the editor. 1. Change content numbers to be relative to the plugin when saving. 2. Initialize the indices in the MasterData part of a plugin header. --- apps/opencs/model/doc/savingstages.cpp | 4 +++ apps/opencs/model/world/data.cpp | 41 ++++++++++++++++++++++++++ apps/opencs/model/world/data.hpp | 7 +++++ 3 files changed, 52 insertions(+) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index ee65248e2..6a0330180 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -321,6 +321,10 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) { CSMWorld::CellRef refRecord = ref.get(); + // Correct content file number to be relative to plugin + refRecord.mRefNum.mContentFile = mDocument.getData().getPluginContentFile( + refRecord.mRefNum.mContentFile); + // recalculate the ref's cell location std::ostringstream stream; if (!interior) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 8b0a9b384..8347cd5bc 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -902,6 +902,8 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base mReader->setIndex(mReaderIndex++); mReader->open (path.string()); + mContentFileNames.insert(std::make_pair(path.filename().string(), mReader->getIndex())); + mBase = base; mProject = project; @@ -914,6 +916,35 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base mMetaData.setRecord (0, Record (RecordBase::State_ModifiedOnly, 0, &metaData)); } + // Fix uninitialized master data index + for (std::vector::const_iterator masterData = mReader->getGameFiles().begin(); + masterData != mReader->getGameFiles().end(); ++masterData) + { + std::map::iterator nameResult = mContentFileNames.find(masterData->name); + if (nameResult != mContentFileNames.end()) + { + ESM::Header::MasterData& hackedMasterData = const_cast(*masterData); + hackedMasterData.index = nameResult->second; + } + } + + // Needed for saving + if (!mBase) + { + mReverseContentFiles.insert(std::make_pair(mReader->getIndex(), 0)); + } + if (mProject) + { + mReverseContentFiles.insert(std::make_pair(mReader->getIndex(), 0)); + + // A new project has no header, so extrapolate the content files from the reader index + // The base/project index of 0 will not be overwritten + for (int i = 0; i < mReader->getIndex(); ++i) + { + mReverseContentFiles.insert(std::make_pair(i, i+1)); + } + } + return mReader->getRecordCount(); } @@ -1171,6 +1202,16 @@ int CSMWorld::Data::count (RecordBase::State state) const count (state, mPathgrids); } +int CSMWorld::Data::getPluginContentFile(int currentContentFile) +{ + std::map::iterator searchResult = mReverseContentFiles.find(currentContentFile); + + if (searchResult != mReverseContentFiles.end()) + return searchResult->second; + else + return 0; // Assume faulty plugin with original content +} + std::vector CSMWorld::Data::getIds (bool listDeleted) const { std::vector ids; diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index f0c3dcd41..8fc68b9f7 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -123,6 +123,10 @@ namespace CSMWorld std::vector > mReaders; + std::map mContentFileNames; + // current index, plugin index + std::map mReverseContentFiles; + // not implemented Data (const Data&); Data& operator= (const Data&); @@ -298,6 +302,9 @@ namespace CSMWorld int count (RecordBase::State state) const; ///< Return number of top-level records with the given \a state. + /// Returns the content file number relative to the plugin being edited, 0 by default + int getPluginContentFile(int currentContentFile); + signals: void idListChanged(); From b2ddd3c2596004d9ee9122c33ce4a57007836a42 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Tue, 30 Aug 2016 16:42:38 -0400 Subject: [PATCH 2/2] Initialize with correct content file number instead of correcting at save stage. --- apps/opencs/model/doc/savingstages.cpp | 6 ++--- apps/opencs/model/world/data.cpp | 33 ++++---------------------- apps/opencs/model/world/data.hpp | 5 ---- 3 files changed, 7 insertions(+), 37 deletions(-) diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index 6a0330180..82a965ae4 100644 --- a/apps/opencs/model/doc/savingstages.cpp +++ b/apps/opencs/model/doc/savingstages.cpp @@ -321,9 +321,9 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages) { CSMWorld::CellRef refRecord = ref.get(); - // Correct content file number to be relative to plugin - refRecord.mRefNum.mContentFile = mDocument.getData().getPluginContentFile( - refRecord.mRefNum.mContentFile); + // Check for uninitialized content file + if (!refRecord.mRefNum.hasContentFile()) + refRecord.mRefNum.mContentFile = 0; // recalculate the ref's cell location std::ostringstream stream; diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 8347cd5bc..1cc4a2cbf 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -64,7 +64,7 @@ int CSMWorld::Data::count (RecordBase::State state, const CollectionBase& collec CSMWorld::Data::Data (ToUTF8::FromType encoding, const ResourcesManager& resourcesManager, const Fallback::Map* fallback, const boost::filesystem::path& resDir) : mEncoder (encoding), mPathgrids (mCells), mRefs (mCells), mResourcesManager (resourcesManager), mFallbackMap(fallback), - mReader (0), mDialogue (0), mReaderIndex(0), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS())) + mReader (0), mDialogue (0), mReaderIndex(1), mResourceSystem(new Resource::ResourceSystem(resourcesManager.getVFS())) { mResourceSystem->getSceneManager()->setShaderPath((resDir / "shaders").string()); @@ -899,7 +899,7 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base mReader = new ESM::ESMReader; mReader->setEncoder (&mEncoder); - mReader->setIndex(mReaderIndex++); + mReader->setIndex((project || !base) ? 0 : mReaderIndex++); mReader->open (path.string()); mContentFileNames.insert(std::make_pair(path.filename().string(), mReader->getIndex())); @@ -924,27 +924,12 @@ int CSMWorld::Data::startLoading (const boost::filesystem::path& path, bool base if (nameResult != mContentFileNames.end()) { ESM::Header::MasterData& hackedMasterData = const_cast(*masterData); + + hackedMasterData.index = nameResult->second; } } - // Needed for saving - if (!mBase) - { - mReverseContentFiles.insert(std::make_pair(mReader->getIndex(), 0)); - } - if (mProject) - { - mReverseContentFiles.insert(std::make_pair(mReader->getIndex(), 0)); - - // A new project has no header, so extrapolate the content files from the reader index - // The base/project index of 0 will not be overwritten - for (int i = 0; i < mReader->getIndex(); ++i) - { - mReverseContentFiles.insert(std::make_pair(i, i+1)); - } - } - return mReader->getRecordCount(); } @@ -1202,16 +1187,6 @@ int CSMWorld::Data::count (RecordBase::State state) const count (state, mPathgrids); } -int CSMWorld::Data::getPluginContentFile(int currentContentFile) -{ - std::map::iterator searchResult = mReverseContentFiles.find(currentContentFile); - - if (searchResult != mReverseContentFiles.end()) - return searchResult->second; - else - return 0; // Assume faulty plugin with original content -} - std::vector CSMWorld::Data::getIds (bool listDeleted) const { std::vector ids; diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 8fc68b9f7..dc00a33d2 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -124,8 +124,6 @@ namespace CSMWorld std::vector > mReaders; std::map mContentFileNames; - // current index, plugin index - std::map mReverseContentFiles; // not implemented Data (const Data&); @@ -302,9 +300,6 @@ namespace CSMWorld int count (RecordBase::State state) const; ///< Return number of top-level records with the given \a state. - /// Returns the content file number relative to the plugin being edited, 0 by default - int getPluginContentFile(int currentContentFile); - signals: void idListChanged();