From 3ae2fc17c6b6cbe5d1ac95d53eb7e65adf22c145 Mon Sep 17 00:00:00 2001 From: Aesylwinn Date: Mon, 29 Aug 2016 18:06:56 -0400 Subject: [PATCH] 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();