diff --git a/apps/opencs/model/tools/mergeoperation.cpp b/apps/opencs/model/tools/mergeoperation.cpp index 9b595046a..cbd2abe0d 100644 --- a/apps/opencs/model/tools/mergeoperation.cpp +++ b/apps/opencs/model/tools/mergeoperation.cpp @@ -38,9 +38,9 @@ CSMTools::MergeOperation::MergeOperation (CSMDoc::Document& document, ToUTF8::Fr appendStage (new MergeRefIdsStage (mState)); appendStage (new MergeReferencesStage (mState)); appendStage (new MergeReferencesStage (mState)); - appendStage (new ListLandTexturesMergeStage (mState)); - appendStage (new MergeLandTexturesStage (mState)); + appendStage (new PopulateLandTexturesMergeStage (mState)); appendStage (new MergeLandStage (mState)); + appendStage (new FixLandsAndLandTexturesMergeStage (mState)); appendStage (new FinishMergedDocumentStage (mState, encoding)); } diff --git a/apps/opencs/model/tools/mergestages.cpp b/apps/opencs/model/tools/mergestages.cpp index 176d35914..eea0656b7 100644 --- a/apps/opencs/model/tools/mergestages.cpp +++ b/apps/opencs/model/tools/mergestages.cpp @@ -8,7 +8,9 @@ #include "mergestate.hpp" #include "../doc/document.hpp" +#include "../world/commands.hpp" #include "../world/data.hpp" +#include "../world/idtable.hpp" CSMTools::StartMergeStage::StartMergeStage (MergeState& state) @@ -109,102 +111,32 @@ void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messa } -CSMTools::ListLandTexturesMergeStage::ListLandTexturesMergeStage (MergeState& state) -: mState (state) -{} - -int CSMTools::ListLandTexturesMergeStage::setup() +CSMTools::PopulateLandTexturesMergeStage::PopulateLandTexturesMergeStage (MergeState& state) + : mState (state) { - return mState.mSource.getData().getLand().getSize(); -} - -void CSMTools::ListLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages) -{ - const CSMWorld::Record& record = - mState.mSource.getData().getLand().getRecord (stage); - - if (!record.isDeleted()) - { - const CSMWorld::Land& land = record.get(); - - // make sure record is loaded - land.loadData (ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | - ESM::Land::DATA_VCLR | ESM::Land::DATA_VTEX); - - if (const ESM::Land::LandData *data = land.getLandData (ESM::Land::DATA_VTEX)) - { - // list texture indices - std::pair key; - key.second = land.mPlugin; - - for (int i=0; imTextures[i]; - - mState.mTextureIndices[key] = -1; - } - } - } } - -CSMTools::MergeLandTexturesStage::MergeLandTexturesStage (MergeState& state) -: mState (state), mNext (mState.mTextureIndices.end()) -{} - -int CSMTools::MergeLandTexturesStage::setup() +int CSMTools::PopulateLandTexturesMergeStage::setup() { - // Should use the size of mState.mTextureIndices instead, but that is not available at this - // point. Unless there are any errors in the land and land texture records this will not - // make a difference. return mState.mSource.getData().getLandTextures().getSize(); } -void CSMTools::MergeLandTexturesStage::perform (int stage, CSMDoc::Messages& messages) +void CSMTools::PopulateLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages) { - if (stage==0) - mNext = mState.mTextureIndices.begin(); + const CSMWorld::Record& record = + mState.mSource.getData().getLandTextures().getRecord (stage); - bool found = false; - - do + if (!record.isDeleted()) { - if (mNext==mState.mTextureIndices.end()) - return; - - mNext->second = stage+1; - - std::ostringstream stream; - stream << mNext->first.first-1 << "_" << mNext->first.second; - - int index = mState.mSource.getData().getLandTextures().searchId (stream.str()); - - if (index!=-1) - { - CSMWorld::LandTexture texture = - mState.mSource.getData().getLandTextures().getRecord (index).get(); - - stream.clear(); - stream << mNext->second-1 << "_0"; - - texture.mIndex = mNext->second-1; - texture.mId = stream.str(); - - CSMWorld::Record newRecord ( - CSMWorld::RecordBase::State_ModifiedOnly, 0, &texture); - - mState.mTarget->getData().getLandTextures().appendRecord (newRecord); - - found = true; - } - - ++mNext; + mState.mTarget->getData().getLandTextures().appendRecord(record); } - while (!found); } -CSMTools::MergeLandStage::MergeLandStage (MergeState& state) : mState (state) {} +CSMTools::MergeLandStage::MergeLandStage (MergeState& state) + : mState (state) +{ +} int CSMTools::MergeLandStage::setup() { @@ -218,40 +150,35 @@ void CSMTools::MergeLandStage::perform (int stage, CSMDoc::Messages& messages) if (!record.isDeleted()) { - const CSMWorld::Land& land = record.get(); - - land.loadData (ESM::Land::DATA_VCLR | ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML | - ESM::Land::DATA_VTEX); + mState.mTarget->getData().getLand().appendRecord (record); + } +} - CSMWorld::Land newLand (land); - newLand.mPlugin = 0; +CSMTools::FixLandsAndLandTexturesMergeStage::FixLandsAndLandTexturesMergeStage (MergeState& state) + : mState (state) +{ +} - if (land.mDataTypes & ESM::Land::DATA_VTEX) - { - // adjust land texture references - if (ESM::Land::LandData *data = newLand.getLandData()) - { - std::pair key; - key.second = land.mPlugin; +int CSMTools::FixLandsAndLandTexturesMergeStage::setup() +{ + // We will have no more than the source + return mState.mSource.getData().getLand().getSize(); +} - for (int i=0; imTextures[i]; - std::map, int>::const_iterator iter = - mState.mTextureIndices.find (key); +void CSMTools::FixLandsAndLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages) +{ + if (stage < mState.mTarget->getData().getLand().getSize()) + { + CSMWorld::IdTable& landTable = dynamic_cast( + *mState.mTarget->getData().getTableModel(CSMWorld::UniversalId::Type_Lands)); - if (iter!=mState.mTextureIndices.end()) - data->mTextures[i] = iter->second; - else - data->mTextures[i] = 0; - } - } - } + CSMWorld::IdTable& ltexTable = dynamic_cast( + *mState.mTarget->getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures)); - CSMWorld::Record newRecord ( - CSMWorld::RecordBase::State_ModifiedOnly, 0, &newLand); + std::string id = mState.mTarget->getData().getLand().getId(stage); - mState.mTarget->getData().getLand().appendRecord (newRecord); + CSMWorld::TouchLandCommand cmd(landTable, ltexTable, id); + cmd.redo(); } } diff --git a/apps/opencs/model/tools/mergestages.hpp b/apps/opencs/model/tools/mergestages.hpp index f88f5be9f..96339ed4c 100644 --- a/apps/opencs/model/tools/mergestages.hpp +++ b/apps/opencs/model/tools/mergestages.hpp @@ -116,13 +116,14 @@ namespace CSMTools ///< Messages resulting from this stage will be appended to \a messages. }; - class ListLandTexturesMergeStage : public CSMDoc::Stage + /// Adds all land texture records that could potentially be referenced when merging + class PopulateLandTexturesMergeStage : public CSMDoc::Stage { MergeState& mState; public: - ListLandTexturesMergeStage (MergeState& state); + PopulateLandTexturesMergeStage (MergeState& state); virtual int setup(); ///< \return number of steps @@ -131,14 +132,13 @@ namespace CSMTools ///< Messages resulting from this stage will be appended to \a messages. }; - class MergeLandTexturesStage : public CSMDoc::Stage + class MergeLandStage : public CSMDoc::Stage { MergeState& mState; - std::map, int>::iterator mNext; public: - MergeLandTexturesStage (MergeState& state); + MergeLandStage (MergeState& state); virtual int setup(); ///< \return number of steps @@ -147,13 +147,14 @@ namespace CSMTools ///< Messages resulting from this stage will be appended to \a messages. }; - class MergeLandStage : public CSMDoc::Stage + /// Flattens the added land and land texture records. + class FixLandsAndLandTexturesMergeStage : public CSMDoc::Stage { MergeState& mState; public: - MergeLandStage (MergeState& state); + FixLandsAndLandTexturesMergeStage (MergeState& state); virtual int setup(); ///< \return number of steps