mirror of
https://github.com/OpenMW/openmw.git
synced 2025-05-10 04:11:25 +00:00
implemented cell and reference saving int OpenCS
This commit is contained in:
parent
e0ba9a4bf2
commit
ae50632774
5 changed files with 121 additions and 3 deletions
|
@ -67,6 +67,7 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
|
||||||
|
|
||||||
appendStage (new CollectionReferencesStage (mDocument, mState));
|
appendStage (new CollectionReferencesStage (mDocument, mState));
|
||||||
|
|
||||||
|
appendStage (new WriteCellCollectionStage (mDocument, mState));
|
||||||
|
|
||||||
// close file and clean up
|
// close file and clean up
|
||||||
appendStage (new CloseSaveStage (mState));
|
appendStage (new CloseSaveStage (mState));
|
||||||
|
|
|
@ -246,12 +246,113 @@ void CSMDoc::CollectionReferencesStage::perform (int stage, Messages& messages)
|
||||||
record.mState==CSMWorld::RecordBase::State_Modified ||
|
record.mState==CSMWorld::RecordBase::State_Modified ||
|
||||||
record.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
record.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||||
{
|
{
|
||||||
mState.getSubRecords()[Misc::StringUtils::lowerCase (record.get().mId)].push_back (i);
|
mState.getSubRecords()[Misc::StringUtils::lowerCase (record.get().mCell)]
|
||||||
|
.push_back (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMDoc::WriteCellCollectionStage::WriteCellCollectionStage (Document& document,
|
||||||
|
SavingState& state)
|
||||||
|
: mDocument (document), mState (state)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMDoc::WriteCellCollectionStage::setup()
|
||||||
|
{
|
||||||
|
return mDocument.getData().getCells().getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::WriteCellCollectionStage::perform (int stage, Messages& messages)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::Cell>& cell =
|
||||||
|
mDocument.getData().getCells().getRecord (stage);
|
||||||
|
|
||||||
|
std::map<std::string, std::vector<int> >::const_iterator references =
|
||||||
|
mState.getSubRecords().find (Misc::StringUtils::lowerCase (cell.get().mId));
|
||||||
|
|
||||||
|
if (cell.mState==CSMWorld::RecordBase::State_Modified ||
|
||||||
|
cell.mState==CSMWorld::RecordBase::State_ModifiedOnly ||
|
||||||
|
references!=mState.getSubRecords().end())
|
||||||
|
{
|
||||||
|
bool interior = cell.get().mId.substr (0, 1)!="#";
|
||||||
|
|
||||||
|
// write cell data
|
||||||
|
mState.getWriter().startRecord (cell.mModified.sRecordId);
|
||||||
|
|
||||||
|
mState.getWriter().writeHNOCString ("NAME", cell.get().mName);
|
||||||
|
|
||||||
|
ESM::Cell cell2 = cell.get();
|
||||||
|
|
||||||
|
if (interior)
|
||||||
|
cell2.mData.mFlags |= ESM::Cell::Interior;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cell2.mData.mFlags &= ~ESM::Cell::Interior;
|
||||||
|
|
||||||
|
std::istringstream stream (cell.get().mId.c_str());
|
||||||
|
char ignore;
|
||||||
|
stream >> ignore >> cell2.mData.mX >> cell2.mData.mY;
|
||||||
|
}
|
||||||
|
cell2.save (mState.getWriter());
|
||||||
|
|
||||||
|
// write references
|
||||||
|
if (references!=mState.getSubRecords().end())
|
||||||
|
{
|
||||||
|
// first pass: find highest RefNum
|
||||||
|
int lastRefNum = -1;
|
||||||
|
|
||||||
|
for (std::vector<int>::const_iterator iter (references->second.begin());
|
||||||
|
iter!=references->second.end(); ++iter)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
||||||
|
mDocument.getData().getReferences().getRecord (*iter);
|
||||||
|
|
||||||
|
if (ref.get().mRefNum.mContentFile==0 && ref.get().mRefNum.mIndex>lastRefNum)
|
||||||
|
lastRefNum = ref.get().mRefNum.mIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// second pass: write
|
||||||
|
for (std::vector<int>::const_iterator iter (references->second.begin());
|
||||||
|
iter!=references->second.end(); ++iter)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<CSMWorld::CellRef>& ref =
|
||||||
|
mDocument.getData().getReferences().getRecord (*iter);
|
||||||
|
|
||||||
|
if (ref.mState==CSMWorld::RecordBase::State_Modified ||
|
||||||
|
ref.mState==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||||
|
{
|
||||||
|
if (ref.get().mRefNum.mContentFile==-2)
|
||||||
|
{
|
||||||
|
if (lastRefNum>=0xffffff)
|
||||||
|
throw std::runtime_error (
|
||||||
|
"RefNums exhausted in cell: " + cell.get().mId);
|
||||||
|
|
||||||
|
ESM::CellRef ref2 = ref.get();
|
||||||
|
ref2.mRefNum.mContentFile = 0;
|
||||||
|
ref2.mRefNum.mIndex = ++lastRefNum;
|
||||||
|
|
||||||
|
ref2.save (mState.getWriter());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ref.get().save (mState.getWriter());
|
||||||
|
}
|
||||||
|
else if (ref.mState==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
/// \todo write record with delete flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mState.getWriter().endRecord (cell.mModified.sRecordId);
|
||||||
|
}
|
||||||
|
else if (cell.mState==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
/// \todo write record with delete flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state)
|
CSMDoc::CloseSaveStage::CloseSaveStage (SavingState& state)
|
||||||
: mState (state)
|
: mState (state)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -182,6 +182,22 @@ namespace CSMDoc
|
||||||
///< Messages resulting from this stage will be appended to \a messages.
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WriteCellCollectionStage : public Stage
|
||||||
|
{
|
||||||
|
Document& mDocument;
|
||||||
|
SavingState& mState;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WriteCellCollectionStage (Document& document, SavingState& state);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, Messages& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
class CloseSaveStage : public Stage
|
class CloseSaveStage : public Stage
|
||||||
{
|
{
|
||||||
SavingState& mState;
|
SavingState& mState;
|
||||||
|
|
|
@ -64,7 +64,7 @@ bool CSMDoc::SavingState::isProjectFile() const
|
||||||
return mProjectFile;
|
return mProjectFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::vector<int> > CSMDoc::SavingState::getSubRecords()
|
std::map<std::string, std::vector<int> >& CSMDoc::SavingState::getSubRecords()
|
||||||
{
|
{
|
||||||
return mSubRecords;
|
return mSubRecords;
|
||||||
}
|
}
|
|
@ -48,7 +48,7 @@ namespace CSMDoc
|
||||||
bool isProjectFile() const;
|
bool isProjectFile() const;
|
||||||
///< Currently saving project file? (instead of content file)
|
///< Currently saving project file? (instead of content file)
|
||||||
|
|
||||||
std::map<std::string, std::vector<int> > getSubRecords();
|
std::map<std::string, std::vector<int> >& getSubRecords();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue