Merge Land/LandTextures

new-script-api
Kyle Cooley 7 years ago
parent 7021d354c6
commit 6d9d98c02c

@ -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));
}

@ -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<CSMWorld::Land>& 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<uint16_t, int> key;
key.second = land.mPlugin;
for (int i=0; i<ESM::Land::LAND_NUM_TEXTURES; ++i)
{
key.first = data->mTextures[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<CSMWorld::LandTexture>& 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<CSMWorld::LandTexture> 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<uint16_t, int> 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; i<ESM::Land::LAND_NUM_TEXTURES; ++i)
{
key.first = data->mTextures[i];
std::map<std::pair<uint16_t, int>, 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<CSMWorld::IdTable&>(
*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<CSMWorld::IdTable&>(
*mState.mTarget->getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures));
CSMWorld::Record<CSMWorld::Land> 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();
}
}

@ -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<std::pair<uint16_t, int>, 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

Loading…
Cancel
Save