1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-04 05:45:33 +00:00

Load methods (for ESM records) accept a deleted flag in OpenCS

(cherry picked from commit 13bb6be238)

Conflicts:
	apps/opencs/model/doc/savingstages.cpp
	apps/opencs/model/world/land.cpp
	apps/opencs/model/world/land.hpp
	apps/opencs/model/world/landtexture.cpp
This commit is contained in:
Stanislav Bas 2015-07-21 20:25:43 +03:00 committed by cc9cii
parent 0c002dd6de
commit f4587e48f3
19 changed files with 60 additions and 159 deletions

View file

@ -106,10 +106,8 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
{ {
// if the topic is deleted, we do not need to bother with INFO records. // if the topic is deleted, we do not need to bother with INFO records.
ESM::Dialogue dialogue = topic.get(); ESM::Dialogue dialogue = topic.get();
dialogue.mIsDeleted = true;
writer.startRecord(dialogue.sRecordId); writer.startRecord(dialogue.sRecordId);
dialogue.save(writer); dialogue.save(writer, true);
writer.endRecord(dialogue.sRecordId); writer.endRecord(dialogue.sRecordId);
return; return;
} }
@ -120,7 +118,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter) for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
{ {
if (topic.isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted) if (iter->isModified() || iter->mState == CSMWorld::RecordBase::State_Deleted)
{ {
infoModified = true; infoModified = true;
break; break;
@ -130,7 +128,6 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
if (topic.isModified() || infoModified) if (topic.isModified() || infoModified)
{ {
ESM::Dialogue dialogue = topic.get(); ESM::Dialogue dialogue = topic.get();
if (infoModified && state != CSMWorld::RecordBase::State_Modified if (infoModified && state != CSMWorld::RecordBase::State_Modified
&& state != CSMWorld::RecordBase::State_ModifiedOnly) && state != CSMWorld::RecordBase::State_ModifiedOnly)
{ {
@ -158,7 +155,6 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
{ {
ESM::DialInfo info = iter->get(); ESM::DialInfo info = iter->get();
info.mId = info.mId.substr (info.mId.find_last_of ('#')+1); info.mId = info.mId.substr (info.mId.find_last_of ('#')+1);
info.mIsDeleted = (iter->mState == CSMWorld::RecordBase::State_Deleted);
info.mPrev = ""; info.mPrev = "";
if (iter!=range.first) if (iter!=range.first)
@ -179,7 +175,7 @@ void CSMDoc::WriteDialogueCollectionStage::perform (int stage, Messages& message
} }
writer.startRecord (info.sRecordId); writer.startRecord (info.sRecordId);
info.save (writer); info.save (writer, iter->mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (info.sRecordId); writer.endRecord (info.sRecordId);
} }
} }
@ -228,9 +224,7 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages)
const CSMWorld::Record<CSMWorld::CellRef>& record = const CSMWorld::Record<CSMWorld::CellRef>& record =
mDocument.getData().getReferences().getRecord (i); mDocument.getData().getReferences().getRecord (i);
if (record.mState==CSMWorld::RecordBase::State_Deleted || if (record.isModified() || record.mState == CSMWorld::RecordBase::State_Deleted)
record.mState==CSMWorld::RecordBase::State_Modified ||
record.mState==CSMWorld::RecordBase::State_ModifiedOnly)
{ {
std::string cellId = record.get().mOriginalCell.empty() ? std::string cellId = record.get().mOriginalCell.empty() ?
record.get().mCell : record.get().mOriginalCell; record.get().mCell : record.get().mOriginalCell;
@ -299,8 +293,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
stream >> ignore >> cellRecord.mData.mX >> cellRecord.mData.mY; stream >> ignore >> cellRecord.mData.mX >> cellRecord.mData.mY;
} }
cellRecord.mIsDeleted = (cell.mState == CSMWorld::RecordBase::State_Deleted); cellRecord.save (writer, cell.mState == CSMWorld::RecordBase::State_Deleted);
cellRecord.save (writer);
// write references // write references
if (references!=mState.getSubRecords().end()) if (references!=mState.getSubRecords().end())
@ -341,8 +334,7 @@ void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
writer.writeHNT ("CNDT", moved.mTarget, 8); writer.writeHNT ("CNDT", moved.mTarget, 8);
} }
refRecord.mIsDeleted = (ref.mState == CSMWorld::RecordBase::State_Deleted); refRecord.save (writer, false, false, ref.mState == CSMWorld::RecordBase::State_Deleted);
refRecord.save (writer);
} }
} }
} }
@ -381,9 +373,8 @@ void CSMDoc::WritePathgridCollectionStage::perform (int stage, Messages& message
else else
record.mCell = record.mId; record.mCell = record.mId;
record.mIsDeleted = (pathgrid.mState == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.sRecordId); writer.startRecord (record.sRecordId);
record.save (writer); record.save (writer, pathgrid.mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.sRecordId); writer.endRecord (record.sRecordId);
} }
} }
@ -408,10 +399,8 @@ void CSMDoc::WriteLandCollectionStage::perform (int stage, Messages& messages)
if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted) if (land.isModified() || land.mState == CSMWorld::RecordBase::State_Deleted)
{ {
const CSMWorld::Land& record = land.get(); const CSMWorld::Land& record = land.get();
record.mLand->mIsDeleted = (land.mState == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.mLand->sRecordId); writer.startRecord (record.mLand->sRecordId);
record.mLand->save (writer); record.mLand->save (writer, land.mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.mLand->sRecordId); writer.endRecord (record.mLand->sRecordId);
} }
} }
@ -436,10 +425,8 @@ void CSMDoc::WriteLandTextureCollectionStage::perform (int stage, Messages& mess
if (landTexture.isModified() || landTexture.mState == CSMWorld::RecordBase::State_Deleted) if (landTexture.isModified() || landTexture.mState == CSMWorld::RecordBase::State_Deleted)
{ {
CSMWorld::LandTexture record = landTexture.get(); CSMWorld::LandTexture record = landTexture.get();
record.mIsDeleted = (landTexture.mState == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.sRecordId); writer.startRecord (record.sRecordId);
record.save (writer); record.save (writer, landTexture.mState == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.sRecordId); writer.endRecord (record.sRecordId);
} }
} }

View file

@ -108,9 +108,8 @@ namespace CSMDoc
state == CSMWorld::RecordBase::State_ModifiedOnly || state == CSMWorld::RecordBase::State_ModifiedOnly ||
state == CSMWorld::RecordBase::State_Deleted) state == CSMWorld::RecordBase::State_Deleted)
{ {
CSMWorld::setRecordDeleted (record, state == CSMWorld::RecordBase::State_Deleted);
writer.startRecord (record.sRecordId); writer.startRecord (record.sRecordId);
record.save (writer); record.save (writer, state == CSMWorld::RecordBase::State_Deleted);
writer.endRecord (record.sRecordId); writer.endRecord (record.sRecordId);
} }
} }

View file

@ -2,12 +2,12 @@
#include <sstream> #include <sstream>
void CSMWorld::Cell::load (ESM::ESMReader &esm) void CSMWorld::Cell::load (ESM::ESMReader &esm, bool &isDeleted)
{ {
ESM::Cell::load (esm, false); ESM::Cell::load (esm, isDeleted, false);
mId = mName; mId = mName;
if (!(mData.mFlags & Interior)) if (isExterior())
{ {
std::ostringstream stream; std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY; stream << "#" << mData.mX << " " << mData.mY;

View file

@ -16,7 +16,7 @@ namespace CSMWorld
{ {
std::string mId; std::string mId;
void load (ESM::ESMReader &esm); void load (ESM::ESMReader &esm, bool &isDeleted);
}; };
} }

View file

@ -1109,9 +1109,11 @@ bool CSMWorld::Data::continueLoading (CSMDoc::Messages& messages)
case ESM::REC_DIAL: case ESM::REC_DIAL:
{ {
ESM::Dialogue record; ESM::Dialogue record;
record.load (*mReader); bool isDeleted = false;
if (record.mIsDeleted) record.load (*mReader, isDeleted);
if (isDeleted)
{ {
// record vector can be shuffled around which would make pointer to record invalid // record vector can be shuffled around which would make pointer to record invalid
mDialogue = 0; mDialogue = 0;

View file

@ -1,3 +0,0 @@
#include "idcollection.hpp"

View file

@ -12,7 +12,7 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> > template<typename ESXRecordT, typename IdAccessorT = IdAccessor<ESXRecordT> >
class IdCollection : public Collection<ESXRecordT, IdAccessorT> class IdCollection : public Collection<ESXRecordT, IdAccessorT>
{ {
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader); virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted);
public: public:
@ -34,21 +34,24 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>
void IdCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record, void IdCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record,
ESM::ESMReader& reader) ESM::ESMReader& reader,
bool& isDeleted)
{ {
record.load (reader); record.load (reader, isDeleted);
} }
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>
int IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base) int IdCollection<ESXRecordT, IdAccessorT>::load (ESM::ESMReader& reader, bool base)
{ {
ESXRecordT record; ESXRecordT record;
loadRecord (record, reader); bool isDeleted = false;
loadRecord (record, reader, isDeleted);
std::string id = IdAccessorT().getId (record); std::string id = IdAccessorT().getId (record);
int index = this->searchId (id); int index = this->searchId (id);
if (isRecordDeleted(record)) if (isDeleted)
{ {
if (index==-1) if (index==-1)
{ {

View file

@ -107,10 +107,12 @@ bool CSMWorld::InfoCollection::reorderRows (int baseIndex, const std::vector<int
void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue) void CSMWorld::InfoCollection::load (ESM::ESMReader& reader, bool base, const ESM::Dialogue& dialogue)
{ {
Info info; Info info;
info.load (reader); bool isDeleted = false;
info.load (reader, isDeleted);
std::string id = Misc::StringUtils::lowerCase (dialogue.mId) + "#" + info.mId; std::string id = Misc::StringUtils::lowerCase (dialogue.mId) + "#" + info.mId;
if (info.mIsDeleted) if (isDeleted)
{ {
int index = searchId (id); int index = searchId (id);

View file

@ -4,13 +4,12 @@
namespace CSMWorld namespace CSMWorld
{ {
void Land::load(ESM::ESMReader &esm) void Land::load(ESM::ESMReader &esm, bool &isDeleted)
{ {
ESM::Land::load(esm); mLand->load(esm, isDeleted);
std::ostringstream stream; std::ostringstream stream;
stream << "#" << mX << " " << mY; stream << "#" << mX << " " << mY;
mId = stream.str(); mId = stream.str();
} }
} }

View file

@ -16,7 +16,7 @@ namespace CSMWorld
std::string mId; std::string mId;
/// Loads the metadata and ID /// Loads the metadata and ID
void load (ESM::ESMReader &esm); void load (ESM::ESMReader &esm, bool &isDeleted);
}; };
} }

View file

@ -4,12 +4,14 @@
namespace CSMWorld namespace CSMWorld
{ {
void LandTexture::load(ESM::ESMReader &esm, bool &isDeleted)
void LandTexture::load(ESM::ESMReader &esm)
{ {
ESM::LandTexture::load(esm); ESM::LandTexture::load(esm, isDeleted);
int plugin = esm.getIndex();
mPluginIndex = esm.getIndex(); std::ostringstream stream;
stream << mIndex << "_" << plugin;
mId = stream.str();
} }
} }

View file

@ -12,7 +12,7 @@ namespace CSMWorld
{ {
int mPluginIndex; int mPluginIndex;
void load (ESM::ESMReader &esm); void load (ESM::ESMReader &esm, bool &isDeleted);
}; };
} }

View file

@ -4,33 +4,28 @@
#include <sstream> #include <sstream>
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, const IdCollection<Cell>& cells) void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection<Cell>& cells)
{ {
load (esm); load (esm, isDeleted);
// correct ID // correct ID
if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1) if (!mId.empty() && mId[0]!='#' && cells.searchId (mId)==-1)
{ {
std::ostringstream stream; std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY; stream << "#" << mData.mX << " " << mData.mY;
mId = stream.str(); mId = stream.str();
} }
} }
void CSMWorld::Pathgrid::load (ESM::ESMReader &esm) void CSMWorld::Pathgrid::load (ESM::ESMReader &esm, bool &isDeleted)
{ {
ESM::Pathgrid::load (esm); ESM::Pathgrid::load (esm, isDeleted);
mId = mCell;
if (mCell.empty()) if (mCell.empty())
{ {
std::ostringstream stream; std::ostringstream stream;
stream << "#" << mData.mX << " " << mData.mY; stream << "#" << mData.mX << " " << mData.mY;
mId = stream.str(); mId = stream.str();
} }
else
mId = mCell;
} }

View file

@ -20,9 +20,8 @@ namespace CSMWorld
{ {
std::string mId; std::string mId;
void load (ESM::ESMReader &esm, const IdCollection<Cell>& cells); void load (ESM::ESMReader &esm, bool &isDeleted, const IdCollection<Cell>& cells);
void load (ESM::ESMReader &esm, bool &isDeleted);
void load (ESM::ESMReader &esm);
}; };
} }

View file

@ -18,51 +18,3 @@ bool CSMWorld::RecordBase::isModified() const
{ {
return mState==State_Modified || mState==State_ModifiedOnly; return mState==State_Modified || mState==State_ModifiedOnly;
} }
template<>
bool CSMWorld::isRecordDeleted(const CSMWorld::Land &land)
{
return land.mLand->mIsDeleted;
}
template<>
bool CSMWorld::isRecordDeleted(const ESM::GameSetting &setting)
{
return false;
}
template<>
bool CSMWorld::isRecordDeleted(const ESM::MagicEffect &effect)
{
return false;
}
template<>
bool CSMWorld::isRecordDeleted(const ESM::Skill &skill)
{
return false;
}
template<>
void CSMWorld::setRecordDeleted(CSMWorld::Land &land, bool isDeleted)
{
land.mLand->mIsDeleted = isDeleted;
}
template<>
void CSMWorld::setRecordDeleted(ESM::GameSetting &setting, bool isDeleted)
{
// GameSetting doesn't have a Deleted flag
}
template<>
void CSMWorld::setRecordDeleted(ESM::MagicEffect &effect, bool isDeleted)
{
// MagicEffect doesn't have a Deleted flag
}
template<>
void CSMWorld::setRecordDeleted(ESM::Skill &skill, bool isDeleted)
{
// Skill doesn't have a Deleted flag
}

View file

@ -3,12 +3,6 @@
#include <stdexcept> #include <stdexcept>
#include <components/esm/loadgmst.hpp>
#include <components/esm/loadmgef.hpp>
#include <components/esm/loadskil.hpp>
#include "land.hpp"
namespace CSMWorld namespace CSMWorld
{ {
struct RecordBase struct RecordBase
@ -160,39 +154,6 @@ namespace CSMWorld
mState = State_Erased; mState = State_Erased;
} }
} }
// Not all records can be deleted (may be changed in the future),
// so we need to use a separate method to check whether a record is deleted or not.
template<typename ESXRecordT>
bool isRecordDeleted(const ESXRecordT &record)
{
return record.mIsDeleted;
}
template<>
bool isRecordDeleted(const Land &land);
template<>
bool isRecordDeleted(const ESM::GameSetting &setting);
template<>
bool isRecordDeleted(const ESM::MagicEffect &effect);
template<>
bool isRecordDeleted(const ESM::Skill &skill);
// ... and also a separate method for setting the deleted flag of a record
template<typename ESXRecordT>
void setRecordDeleted(ESXRecordT &record, bool isDeleted = false)
{
record.mIsDeleted = isDeleted;
}
template<>
void setRecordDeleted(Land &land, bool isDeleted);
template<>
void setRecordDeleted(ESM::GameSetting &setting, bool isDeleted);
template<>
void setRecordDeleted(ESM::MagicEffect &effect, bool isDeleted);
template<>
void setRecordDeleted(ESM::Skill &skill, bool isDeleted);
} }
#endif #endif

View file

@ -20,9 +20,10 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
CellRef ref; CellRef ref;
ESM::MovedCellRef mref; ESM::MovedCellRef mref;
bool isDeleted = false;
// hack to initialise mindex // hack to initialise mindex
while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, true, &mref)) while (!(mref.mRefNum.mIndex = 0) && ESM::Cell::getNextRef(reader, ref, isDeleted, true, &mref))
{ {
// Keep mOriginalCell empty when in modified (as an indicator that the // Keep mOriginalCell empty when in modified (as an indicator that the
// original cell will always be equal the current cell). // original cell will always be equal the current cell).
@ -78,7 +79,7 @@ void CSMWorld::RefCollection::load (ESM::ESMReader& reader, int cellIndex, bool
break; break;
} }
if (ref.mIsDeleted) if (isDeleted)
{ {
if (iter==cache.end()) if (iter==cache.end())
{ {

View file

@ -129,7 +129,9 @@ namespace CSMWorld
int RefIdDataContainer<RecordT>::load (ESM::ESMReader& reader, bool base) int RefIdDataContainer<RecordT>::load (ESM::ESMReader& reader, bool base)
{ {
RecordT record; RecordT record;
record.load(reader); bool isDeleted = false;
record.load(reader, isDeleted);
int index = 0; int index = 0;
int numRecords = static_cast<int>(mContainer.size()); int numRecords = static_cast<int>(mContainer.size());
@ -141,7 +143,7 @@ namespace CSMWorld
} }
} }
if (record.mIsDeleted) if (isDeleted)
{ {
if (index == numRecords) if (index == numRecords)
{ {
@ -197,13 +199,12 @@ namespace CSMWorld
void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const void RefIdDataContainer<RecordT>::save (int index, ESM::ESMWriter& writer) const
{ {
Record<RecordT> record = mContainer.at(index); Record<RecordT> record = mContainer.at(index);
RecordT esmRecord = record.get();
if (record.isModified() || record.mState == RecordBase::State_Deleted) if (record.isModified() || record.mState == RecordBase::State_Deleted)
{ {
esmRecord.mIsDeleted = (record.mState == RecordBase::State_Deleted); RecordT esmRecord = record.get();
writer.startRecord(esmRecord.sRecordId); writer.startRecord(esmRecord.sRecordId);
esmRecord.save(writer); esmRecord.save(writer, record.mState == RecordBase::State_Deleted);
writer.endRecord(esmRecord.sRecordId); writer.endRecord(esmRecord.sRecordId);
} }
} }

View file

@ -20,7 +20,7 @@ namespace CSMWorld
{ {
const IdCollection<Cell>& mCells; const IdCollection<Cell>& mCells;
virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader); virtual void loadRecord (ESXRecordT& record, ESM::ESMReader& reader, bool& isDeleted);
public: public:
@ -29,9 +29,10 @@ namespace CSMWorld
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>
void SubCellCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record, void SubCellCollection<ESXRecordT, IdAccessorT>::loadRecord (ESXRecordT& record,
ESM::ESMReader& reader) ESM::ESMReader& reader,
bool& isDeleted)
{ {
record.load (reader, mCells); record.load (reader, isDeleted, mCells);
} }
template<typename ESXRecordT, typename IdAccessorT> template<typename ESXRecordT, typename IdAccessorT>