diff --git a/apps/opencs/model/doc/savingstages.cpp b/apps/opencs/model/doc/savingstages.cpp index ee65248e2f..6a03301806 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 8b0a9b384d..8347cd5bc3 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 f0c3dcd417..8fc68b9f7e 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();