forked from mirror/openmw-tes3mp
Merge remote-tracking branch 'aesylwinn/LLmerge'
This commit is contained in:
commit
bdabace7e2
8 changed files with 137 additions and 154 deletions
|
@ -38,9 +38,10 @@ CSMTools::MergeOperation::MergeOperation (CSMDoc::Document& document, ToUTF8::Fr
|
||||||
appendStage (new MergeRefIdsStage (mState));
|
appendStage (new MergeRefIdsStage (mState));
|
||||||
appendStage (new MergeReferencesStage (mState));
|
appendStage (new MergeReferencesStage (mState));
|
||||||
appendStage (new MergeReferencesStage (mState));
|
appendStage (new MergeReferencesStage (mState));
|
||||||
appendStage (new ListLandTexturesMergeStage (mState));
|
appendStage (new PopulateLandTexturesMergeStage (mState));
|
||||||
appendStage (new MergeLandTexturesStage (mState));
|
|
||||||
appendStage (new MergeLandStage (mState));
|
appendStage (new MergeLandStage (mState));
|
||||||
|
appendStage (new FixLandsAndLandTexturesMergeStage (mState));
|
||||||
|
appendStage (new CleanupLandTexturesMergeStage (mState));
|
||||||
|
|
||||||
appendStage (new FinishMergedDocumentStage (mState, encoding));
|
appendStage (new FinishMergedDocumentStage (mState, encoding));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
#include "mergestate.hpp"
|
#include "mergestate.hpp"
|
||||||
|
|
||||||
#include "../doc/document.hpp"
|
#include "../doc/document.hpp"
|
||||||
|
#include "../world/commands.hpp"
|
||||||
#include "../world/data.hpp"
|
#include "../world/data.hpp"
|
||||||
|
#include "../world/idtable.hpp"
|
||||||
|
|
||||||
|
|
||||||
CSMTools::StartMergeStage::StartMergeStage (MergeState& state)
|
CSMTools::StartMergeStage::StartMergeStage (MergeState& state)
|
||||||
|
@ -109,102 +111,32 @@ void CSMTools::MergeReferencesStage::perform (int stage, CSMDoc::Messages& messa
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CSMTools::ListLandTexturesMergeStage::ListLandTexturesMergeStage (MergeState& state)
|
CSMTools::PopulateLandTexturesMergeStage::PopulateLandTexturesMergeStage (MergeState& state)
|
||||||
: mState (state)
|
: mState (state)
|
||||||
{}
|
|
||||||
|
|
||||||
int CSMTools::ListLandTexturesMergeStage::setup()
|
|
||||||
{
|
{
|
||||||
return mState.mSource.getData().getLand().getSize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSMTools::ListLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages)
|
int CSMTools::PopulateLandTexturesMergeStage::setup()
|
||||||
{
|
{
|
||||||
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()
|
|
||||||
{
|
|
||||||
// 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();
|
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)
|
const CSMWorld::Record<CSMWorld::LandTexture>& record =
|
||||||
mNext = mState.mTextureIndices.begin();
|
mState.mSource.getData().getLandTextures().getRecord (stage);
|
||||||
|
|
||||||
bool found = false;
|
if (!record.isDeleted())
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
if (mNext==mState.mTextureIndices.end())
|
mState.mTarget->getData().getLandTextures().appendRecord(record);
|
||||||
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;
|
|
||||||
}
|
|
||||||
while (!found);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CSMTools::MergeLandStage::MergeLandStage (MergeState& state) : mState (state) {}
|
CSMTools::MergeLandStage::MergeLandStage (MergeState& state)
|
||||||
|
: mState (state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int CSMTools::MergeLandStage::setup()
|
int CSMTools::MergeLandStage::setup()
|
||||||
{
|
{
|
||||||
|
@ -218,40 +150,66 @@ void CSMTools::MergeLandStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
|
||||||
if (!record.isDeleted())
|
if (!record.isDeleted())
|
||||||
{
|
{
|
||||||
const CSMWorld::Land& land = record.get();
|
mState.mTarget->getData().getLand().appendRecord (record);
|
||||||
|
}
|
||||||
land.loadData (ESM::Land::DATA_VCLR | ESM::Land::DATA_VHGT | ESM::Land::DATA_VNML |
|
}
|
||||||
ESM::Land::DATA_VTEX);
|
|
||||||
|
|
||||||
CSMWorld::Land newLand (land);
|
CSMTools::FixLandsAndLandTexturesMergeStage::FixLandsAndLandTexturesMergeStage (MergeState& state)
|
||||||
|
: mState (state)
|
||||||
newLand.mPlugin = 0;
|
{
|
||||||
|
}
|
||||||
if (land.mDataTypes & ESM::Land::DATA_VTEX)
|
|
||||||
{
|
int CSMTools::FixLandsAndLandTexturesMergeStage::setup()
|
||||||
// adjust land texture references
|
{
|
||||||
if (ESM::Land::LandData *data = newLand.getLandData())
|
// We will have no more than the source
|
||||||
{
|
return mState.mSource.getData().getLand().getSize();
|
||||||
std::pair<uint16_t, int> key;
|
}
|
||||||
key.second = land.mPlugin;
|
|
||||||
|
void CSMTools::FixLandsAndLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
for (int i=0; i<ESM::Land::LAND_NUM_TEXTURES; ++i)
|
{
|
||||||
{
|
if (stage < mState.mTarget->getData().getLand().getSize())
|
||||||
key.first = data->mTextures[i];
|
{
|
||||||
std::map<std::pair<uint16_t, int>, int>::const_iterator iter =
|
CSMWorld::IdTable& landTable = dynamic_cast<CSMWorld::IdTable&>(
|
||||||
mState.mTextureIndices.find (key);
|
*mState.mTarget->getData().getTableModel(CSMWorld::UniversalId::Type_Lands));
|
||||||
|
|
||||||
if (iter!=mState.mTextureIndices.end())
|
CSMWorld::IdTable& ltexTable = dynamic_cast<CSMWorld::IdTable&>(
|
||||||
data->mTextures[i] = iter->second;
|
*mState.mTarget->getData().getTableModel(CSMWorld::UniversalId::Type_LandTextures));
|
||||||
else
|
|
||||||
data->mTextures[i] = 0;
|
std::string id = mState.mTarget->getData().getLand().getId(stage);
|
||||||
}
|
|
||||||
}
|
CSMWorld::TouchLandCommand cmd(landTable, ltexTable, id);
|
||||||
}
|
cmd.redo();
|
||||||
|
|
||||||
CSMWorld::Record<CSMWorld::Land> newRecord (
|
// Get rid of base data
|
||||||
CSMWorld::RecordBase::State_ModifiedOnly, 0, &newLand);
|
const CSMWorld::Record<CSMWorld::Land>& oldRecord =
|
||||||
|
mState.mTarget->getData().getLand().getRecord (stage);
|
||||||
mState.mTarget->getData().getLand().appendRecord (newRecord);
|
|
||||||
|
CSMWorld::Record<CSMWorld::Land> newRecord(CSMWorld::RecordBase::State_ModifiedOnly,
|
||||||
|
nullptr, &oldRecord.get());
|
||||||
|
|
||||||
|
mState.mTarget->getData().getLand().setRecord(stage, newRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMTools::CleanupLandTexturesMergeStage::CleanupLandTexturesMergeStage (MergeState& state)
|
||||||
|
: mState (state)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMTools::CleanupLandTexturesMergeStage::setup()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMTools::CleanupLandTexturesMergeStage::perform (int stage, CSMDoc::Messages& messages)
|
||||||
|
{
|
||||||
|
auto& landTextures = mState.mTarget->getData().getLandTextures();
|
||||||
|
for (int i = 0; i < landTextures.getSize(); )
|
||||||
|
{
|
||||||
|
if (!landTextures.getRecord(i).isModified())
|
||||||
|
landTextures.removeRows(i, 1);
|
||||||
|
else
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,29 +116,14 @@ namespace CSMTools
|
||||||
///< Messages resulting from this stage will be appended to \a messages.
|
///< 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;
|
MergeState& mState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ListLandTexturesMergeStage (MergeState& state);
|
PopulateLandTexturesMergeStage (MergeState& state);
|
||||||
|
|
||||||
virtual int setup();
|
|
||||||
///< \return number of steps
|
|
||||||
|
|
||||||
virtual void perform (int stage, CSMDoc::Messages& messages);
|
|
||||||
///< Messages resulting from this stage will be appended to \a messages.
|
|
||||||
};
|
|
||||||
|
|
||||||
class MergeLandTexturesStage : public CSMDoc::Stage
|
|
||||||
{
|
|
||||||
MergeState& mState;
|
|
||||||
std::map<std::pair<uint16_t, int>, int>::iterator mNext;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
MergeLandTexturesStage (MergeState& state);
|
|
||||||
|
|
||||||
virtual int setup();
|
virtual int setup();
|
||||||
///< \return number of steps
|
///< \return number of steps
|
||||||
|
@ -161,6 +146,40 @@ namespace CSMTools
|
||||||
virtual void perform (int stage, CSMDoc::Messages& messages);
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
///< Messages resulting from this stage will be appended to \a messages.
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// During this stage, the complex process of combining LandTextures from
|
||||||
|
/// potentially multiple plugins is undertaken.
|
||||||
|
class FixLandsAndLandTexturesMergeStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
FixLandsAndLandTexturesMergeStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Removes base LandTexture records. This gets rid of the base records previously
|
||||||
|
/// needed in FixLandsAndLandTexturesMergeStage.
|
||||||
|
class CleanupLandTexturesMergeStage : public CSMDoc::Stage
|
||||||
|
{
|
||||||
|
MergeState& mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CleanupLandTexturesMergeStage (MergeState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, CSMDoc::Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace CSMWorld
|
||||||
throw std::runtime_error("invalid land map LOD data");
|
throw std::runtime_error("invalid land map LOD data");
|
||||||
|
|
||||||
Land copy = record.get();
|
Land copy = record.get();
|
||||||
copy.setDataLoaded(Land::DATA_WNAM);
|
copy.add(Land::DATA_WNAM);
|
||||||
|
|
||||||
for (int i = 0; i < values.size(); ++i)
|
for (int i = 0; i < values.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -155,7 +155,7 @@ namespace CSMWorld
|
||||||
throw std::runtime_error("invalid land normals data");
|
throw std::runtime_error("invalid land normals data");
|
||||||
|
|
||||||
Land copy = record.get();
|
Land copy = record.get();
|
||||||
copy.setDataLoaded(Land::DATA_VNML);
|
copy.add(Land::DATA_VNML);
|
||||||
|
|
||||||
for (int i = 0; i < values.size(); ++i)
|
for (int i = 0; i < values.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -202,7 +202,7 @@ namespace CSMWorld
|
||||||
throw std::runtime_error("invalid land heights data");
|
throw std::runtime_error("invalid land heights data");
|
||||||
|
|
||||||
Land copy = record.get();
|
Land copy = record.get();
|
||||||
copy.setDataLoaded(Land::DATA_VHGT);
|
copy.add(Land::DATA_VHGT);
|
||||||
|
|
||||||
for (int i = 0; i < values.size(); ++i)
|
for (int i = 0; i < values.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -249,7 +249,7 @@ namespace CSMWorld
|
||||||
throw std::runtime_error("invalid land colours data");
|
throw std::runtime_error("invalid land colours data");
|
||||||
|
|
||||||
Land copy = record.get();
|
Land copy = record.get();
|
||||||
copy.setDataLoaded(Land::DATA_VCLR);
|
copy.add(Land::DATA_VCLR);
|
||||||
|
|
||||||
for (int i = 0; i < values.size(); ++i)
|
for (int i = 0; i < values.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -296,7 +296,7 @@ namespace CSMWorld
|
||||||
throw std::runtime_error("invalid land textures data");
|
throw std::runtime_error("invalid land textures data");
|
||||||
|
|
||||||
Land copy = record.get();
|
Land copy = record.get();
|
||||||
copy.setDataLoaded(Land::DATA_VTEX);
|
copy.add(Land::DATA_VTEX);
|
||||||
|
|
||||||
for (int i = 0; i < values.size(); ++i)
|
for (int i = 0; i < values.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,6 +44,15 @@ namespace CSMWorld
|
||||||
bool mChanged;
|
bool mChanged;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief Adds LandTexture records and modifies texture indices as needed.
|
||||||
|
///
|
||||||
|
/// LandTexture records are different from other types of records, because
|
||||||
|
/// they only effect the current plugin. Thus, when modifying or copying
|
||||||
|
/// a Land record, all of the LandTexture records referenced need to be
|
||||||
|
/// added to the current plugin. Since these newly added LandTextures could
|
||||||
|
/// have indices that conflict with pre-existing LandTextures in the current
|
||||||
|
/// plugin, the indices might have to be changed, both for the newly added
|
||||||
|
/// LandRecord and within the Land record.
|
||||||
class ImportLandTexturesCommand : public QUndoCommand
|
class ImportLandTexturesCommand : public QUndoCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -71,6 +80,9 @@ namespace CSMWorld
|
||||||
std::vector<std::string> mCreatedTextures;
|
std::vector<std::string> mCreatedTextures;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief This command is used to fix LandTexture records and texture
|
||||||
|
/// indices after cloning a Land. See ImportLandTexturesCommand for
|
||||||
|
/// details.
|
||||||
class CopyLandTexturesCommand : public ImportLandTexturesCommand
|
class CopyLandTexturesCommand : public ImportLandTexturesCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -90,6 +102,9 @@ namespace CSMWorld
|
||||||
std::string mDestId;
|
std::string mDestId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// \brief This command brings a land record into the current plugin, adding
|
||||||
|
/// LandTexture records and modifying texture indices as needed.
|
||||||
|
/// \note See ImportLandTextures for more details.
|
||||||
class TouchLandCommand : public ImportLandTexturesCommand
|
class TouchLandCommand : public ImportLandTexturesCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -336,7 +336,7 @@ CSMWorld::LandTextureIdTable::ImportResults CSMWorld::LandTextureIdTable::import
|
||||||
int oldRow = idCollection()->searchId(id);
|
int oldRow = idCollection()->searchId(id);
|
||||||
|
|
||||||
// If it does not exist or it is in the current plugin, it can be skipped.
|
// If it does not exist or it is in the current plugin, it can be skipped.
|
||||||
if (oldRow <= 0 || plugin == 0)
|
if (oldRow < 0 || plugin == 0)
|
||||||
{
|
{
|
||||||
results.recordMapping.push_back(std::make_pair(id, id));
|
results.recordMapping.push_back(std::make_pair(id, id));
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -315,16 +315,7 @@ namespace ESM
|
||||||
|
|
||||||
bool Land::isDataLoaded(int flags) const
|
bool Land::isDataLoaded(int flags) const
|
||||||
{
|
{
|
||||||
return mLandData && (mLandData->mDataLoaded & flags) == (flags & mDataTypes);
|
return mLandData && (mLandData->mDataLoaded & flags) == flags;
|
||||||
}
|
|
||||||
|
|
||||||
void Land::setDataLoaded(int flags)
|
|
||||||
{
|
|
||||||
if (!mLandData)
|
|
||||||
mLandData = new LandData;
|
|
||||||
|
|
||||||
mDataTypes |= flags;
|
|
||||||
mLandData->mDataLoaded |= flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Land::Land (const Land& land)
|
Land::Land (const Land& land)
|
||||||
|
|
|
@ -132,7 +132,6 @@ struct Land
|
||||||
void unloadData() const;
|
void unloadData() const;
|
||||||
|
|
||||||
/// Check if given data type is loaded
|
/// Check if given data type is loaded
|
||||||
/// @note We only check data types that *can* be loaded (present in mDataTypes)
|
|
||||||
bool isDataLoaded(int flags) const;
|
bool isDataLoaded(int flags) const;
|
||||||
|
|
||||||
/// Sets the flags and creates a LandData if needed
|
/// Sets the flags and creates a LandData if needed
|
||||||
|
|
Loading…
Reference in a new issue