mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-21 08:53:52 +00:00
save info records
This commit is contained in:
parent
8c4303399f
commit
2fff7fc843
4 changed files with 146 additions and 8 deletions
|
@ -58,12 +58,9 @@ CSMDoc::Saving::Saving (Document& document, const boost::filesystem::path& proje
|
||||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Spell> >
|
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Spell> >
|
||||||
(mDocument.getData().getSpells(), mState));
|
(mDocument.getData().getSpells(), mState));
|
||||||
|
|
||||||
/// \todo deal with info records for topcis and journals
|
appendStage (new WriteDialogueCollectionStage (mDocument, mState, false));
|
||||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Dialogue> >
|
|
||||||
(mDocument.getData().getTopics(), mState));
|
|
||||||
|
|
||||||
appendStage (new WriteCollectionStage<CSMWorld::IdCollection<ESM::Dialogue> >
|
appendStage (new WriteDialogueCollectionStage (mDocument, mState, true));
|
||||||
(mDocument.getData().getJournals(), mState));
|
|
||||||
|
|
||||||
appendStage (new WriteRefIdCollectionStage (mDocument, mState));
|
appendStage (new WriteRefIdCollectionStage (mDocument, mState));
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@
|
||||||
|
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
|
|
||||||
|
#include <components/esm/loaddial.hpp>
|
||||||
|
|
||||||
|
#include "../world/infocollection.hpp"
|
||||||
|
|
||||||
#include "document.hpp"
|
#include "document.hpp"
|
||||||
#include "savingstate.hpp"
|
#include "savingstate.hpp"
|
||||||
|
|
||||||
|
@ -80,6 +84,115 @@ void CSMDoc::WriteHeaderStage::perform (int stage, std::vector<std::string>& mes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CSMDoc::WriteDialogueCollectionStage::WriteDialogueCollectionStage (Document& document,
|
||||||
|
SavingState& state, bool journal)
|
||||||
|
: mDocument (document), mState (state),
|
||||||
|
mTopics (journal ? document.getData().getJournals() : document.getData().getTopics()),
|
||||||
|
mInfos (journal ? document.getData().getJournalInfos() : document.getData().getTopicInfos())
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSMDoc::WriteDialogueCollectionStage::setup()
|
||||||
|
{
|
||||||
|
return mTopics.getSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMDoc::WriteDialogueCollectionStage::perform (int stage, std::vector<std::string>& messages)
|
||||||
|
{
|
||||||
|
const CSMWorld::Record<ESM::Dialogue>& topic = mTopics.getRecord (stage);
|
||||||
|
|
||||||
|
CSMWorld::RecordBase::State state = topic.mState;
|
||||||
|
|
||||||
|
if (state==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
// if the topic is deleted, we do not need to bother with INFO records.
|
||||||
|
|
||||||
|
/// \todo wrote record with delete flag
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test, if we need to save anything associated info records.
|
||||||
|
bool infoModified = false;
|
||||||
|
|
||||||
|
CSMWorld::InfoCollection::Range range = mInfos.getTopicRange (topic.get().mId);
|
||||||
|
|
||||||
|
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second; ++iter)
|
||||||
|
{
|
||||||
|
CSMWorld::RecordBase::State state = iter->mState;
|
||||||
|
|
||||||
|
if (state==CSMWorld::RecordBase::State_Modified ||
|
||||||
|
state==CSMWorld::RecordBase::State_ModifiedOnly ||
|
||||||
|
state==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
infoModified = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state==CSMWorld::RecordBase::State_Modified ||
|
||||||
|
state==CSMWorld::RecordBase::State_ModifiedOnly ||
|
||||||
|
infoModified)
|
||||||
|
{
|
||||||
|
// always write the topic record
|
||||||
|
std::string type;
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
/// \todo make endianess agnostic (change ESMWriter interface?)
|
||||||
|
type += reinterpret_cast<const char *> (&topic.mModified.sRecordId)[i];
|
||||||
|
|
||||||
|
mState.getWriter().startRecord (type);
|
||||||
|
mState.getWriter().writeHNCString ("NAME", topic.mModified.mId);
|
||||||
|
topic.mModified.save (mState.getWriter());
|
||||||
|
mState.getWriter().endRecord (type);
|
||||||
|
|
||||||
|
// write modified selected info records
|
||||||
|
for (CSMWorld::InfoCollection::RecordConstIterator iter (range.first); iter!=range.second;
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
CSMWorld::RecordBase::State state = iter->mState;
|
||||||
|
|
||||||
|
if (state==CSMWorld::RecordBase::State_Deleted)
|
||||||
|
{
|
||||||
|
/// \todo wrote record with delete flag
|
||||||
|
}
|
||||||
|
else if (state==CSMWorld::RecordBase::State_Modified ||
|
||||||
|
state==CSMWorld::RecordBase::State_ModifiedOnly)
|
||||||
|
{
|
||||||
|
ESM::DialInfo info = iter->get();
|
||||||
|
info.mId = info.mId.substr (info.mId.find_last_of ('#')+1);
|
||||||
|
|
||||||
|
if (iter!=range.first)
|
||||||
|
{
|
||||||
|
CSMWorld::InfoCollection::RecordConstIterator prev = iter;
|
||||||
|
--prev;
|
||||||
|
|
||||||
|
info.mPrev =
|
||||||
|
prev->mModified.mId.substr (prev->mModified.mId.find_last_of ('#')+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMWorld::InfoCollection::RecordConstIterator next = iter;
|
||||||
|
++next;
|
||||||
|
|
||||||
|
if (next!=range.second)
|
||||||
|
{
|
||||||
|
info.mNext =
|
||||||
|
next->mModified.mId.substr (next->mModified.mId.find_last_of ('#')+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string type;
|
||||||
|
for (int i=0; i<4; ++i)
|
||||||
|
/// \todo make endianess agnostic (change ESMWriter interface?)
|
||||||
|
type += reinterpret_cast<const char *> (&info.sRecordId)[i];
|
||||||
|
|
||||||
|
mState.getWriter().startRecord (type);
|
||||||
|
mState.getWriter().writeHNCString ("INAM", info.mId);
|
||||||
|
info.save (mState.getWriter());
|
||||||
|
mState.getWriter().endRecord (type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CSMDoc::WriteRefIdCollectionStage::WriteRefIdCollectionStage (Document& document, SavingState& state)
|
CSMDoc::WriteRefIdCollectionStage::WriteRefIdCollectionStage (Document& document, SavingState& state)
|
||||||
: mDocument (document), mState (state)
|
: mDocument (document), mState (state)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -3,13 +3,23 @@
|
||||||
|
|
||||||
#include "stage.hpp"
|
#include "stage.hpp"
|
||||||
|
|
||||||
#include "savingstate.hpp"
|
|
||||||
|
|
||||||
#include "../world/record.hpp"
|
#include "../world/record.hpp"
|
||||||
#include "../world/idcollection.hpp"
|
#include "../world/idcollection.hpp"
|
||||||
|
|
||||||
#include "../filter/filter.hpp"
|
#include "../filter/filter.hpp"
|
||||||
|
|
||||||
|
#include "savingstate.hpp"
|
||||||
|
|
||||||
|
namespace ESM
|
||||||
|
{
|
||||||
|
struct Dialogue;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CSMWorld
|
||||||
|
{
|
||||||
|
class InfoCollection;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CSMDoc
|
namespace CSMDoc
|
||||||
{
|
{
|
||||||
class Document;
|
class Document;
|
||||||
|
@ -106,6 +116,25 @@ namespace CSMDoc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class WriteDialogueCollectionStage : public Stage
|
||||||
|
{
|
||||||
|
Document& mDocument;
|
||||||
|
SavingState& mState;
|
||||||
|
const CSMWorld::IdCollection<ESM::Dialogue>& mTopics;
|
||||||
|
CSMWorld::InfoCollection& mInfos;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
WriteDialogueCollectionStage (Document& document, SavingState& state, bool journal);
|
||||||
|
|
||||||
|
virtual int setup();
|
||||||
|
///< \return number of steps
|
||||||
|
|
||||||
|
virtual void perform (int stage, std::vector<std::string>& messages);
|
||||||
|
///< Messages resulting from this stage will be appended to \a messages.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class WriteRefIdCollectionStage : public Stage
|
class WriteRefIdCollectionStage : public Stage
|
||||||
{
|
{
|
||||||
Document& mDocument;
|
Document& mDocument;
|
||||||
|
|
|
@ -123,7 +123,6 @@ void DialInfo::load(ESMReader &esm)
|
||||||
|
|
||||||
void DialInfo::save(ESMWriter &esm) const
|
void DialInfo::save(ESMWriter &esm) const
|
||||||
{
|
{
|
||||||
esm.writeHNCString("INAM", mId);
|
|
||||||
esm.writeHNCString("PNAM", mPrev);
|
esm.writeHNCString("PNAM", mPrev);
|
||||||
esm.writeHNCString("NNAM", mNext);
|
esm.writeHNCString("NNAM", mNext);
|
||||||
esm.writeHNT("DATA", mData, 12);
|
esm.writeHNT("DATA", mData, 12);
|
||||||
|
|
Loading…
Reference in a new issue