diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index 971bc3b4e..33bba07e1 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -3,6 +3,14 @@ #include +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; +} + namespace MWWorld { class Ptr; @@ -52,6 +60,12 @@ namespace MWBase virtual void persuade (int type) = 0; virtual int getTemporaryDispositionChange () const = 0; virtual void applyDispositionChange (int delta) = 0; + + virtual int countSavedGameRecords() const = 0; + + virtual void write (ESM::ESMWriter& writer) const = 0; + + virtual void readRecord (ESM::ESMReader& reader, int32_t type) = 0; }; } diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 845c3c07b..c9e8ad955 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -591,6 +592,41 @@ namespace MWDialogue } } + int DialogueManager::countSavedGameRecords() const + { + return 1; // known topics + } + + void DialogueManager::write (ESM::ESMWriter& writer) const + { + ESM::DialogueState state; + + for (std::map::const_iterator iter (mKnownTopics.begin()); + iter!=mKnownTopics.end(); ++iter) + if (iter->second) + state.mKnownTopics.push_back (iter->first); + + writer.startRecord (ESM::REC_DIAS); + state.save (writer); + writer.endRecord (ESM::REC_DIAS); + } + + void DialogueManager::readRecord (ESM::ESMReader& reader, int32_t type) + { + if (type==ESM::REC_DIAS) + { + const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); + + ESM::DialogueState state; + state.load (reader); + + for (std::vector::const_iterator iter (state.mKnownTopics.begin()); + iter!=state.mKnownTopics.end(); ++iter) + if (store.get().search (*iter)) + mKnownTopics.insert (std::make_pair (*iter, true)); + } + } + std::vector ParseHyperText(const std::string& text) { diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index c32a5dbd8..cf8ea1176 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -78,6 +78,12 @@ namespace MWDialogue virtual void persuade (int type); virtual int getTemporaryDispositionChange () const; virtual void applyDispositionChange (int delta); + + virtual int countSavedGameRecords() const; + + virtual void write (ESM::ESMWriter& writer) const; + + virtual void readRecord (ESM::ESMReader& reader, int32_t type); }; diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index f68a01bf4..ba0e1d056 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -193,7 +193,8 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot +MWBase::Environment::get().getJournal()->countSavedGameRecords() +MWBase::Environment::get().getWorld()->countSavedGameRecords() +MWBase::Environment::get().getScriptManager()->getGlobalScripts().countSavedGameRecords() - + 1 // global map + +MWBase::Environment::get().getDialogueManager()->countSavedGameRecords() + +1 // global map ); writer.save (stream); @@ -203,6 +204,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot writer.endRecord (ESM::REC_SAVE); MWBase::Environment::get().getJournal()->write (writer); + MWBase::Environment::get().getDialogueManager()->write (writer); MWBase::Environment::get().getWorld()->write (writer); MWBase::Environment::get().getScriptManager()->getGlobalScripts().write (writer); MWBase::Environment::get().getWindowManager()->write(writer); @@ -245,6 +247,11 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl MWBase::Environment::get().getJournal()->readRecord (reader, n.val); break; + case ESM::REC_DIAS: + + MWBase::Environment::get().getDialogueManager()->readRecord (reader, n.val); + break; + case ESM::REC_ALCH: case ESM::REC_ARMO: case ESM::REC_BOOK: diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 45a91f368..e6b89c08e 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -44,7 +44,7 @@ add_component_dir (esm loadinfo loadingr loadland loadlevlist loadligh loadlock loadprob loadrepa loadltex loadmgef loadmisc loadnpcc loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter - savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate + savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate ) add_component_dir (misc diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index 1b0125e78..c1f167992 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -91,6 +91,7 @@ enum RecNameInts REC_PLAY = 0x59414c50, REC_CSTA = 0x41545343, REC_GMAP = 0x50414d47, + REC_DIAS = 0x53414944, // format 1 REC_FILT = 0x544C4946 diff --git a/components/esm/dialoguestate.cpp b/components/esm/dialoguestate.cpp new file mode 100644 index 000000000..b3544c85c --- /dev/null +++ b/components/esm/dialoguestate.cpp @@ -0,0 +1,21 @@ + +#include "dialoguestate.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" + +void ESM::DialogueState::load (ESMReader &esm) +{ + while (esm.isNextSub ("TOPI")) + mKnownTopics.push_back (esm.getHString()); +} + +void ESM::DialogueState::save (ESMWriter &esm) const +{ + for (std::vector::const_iterator iter (mKnownTopics.begin()); + iter!=mKnownTopics.end(); ++iter) + { + esm.writeHNString ("TOPI", *iter); + + } +} \ No newline at end of file diff --git a/components/esm/dialoguestate.hpp b/components/esm/dialoguestate.hpp new file mode 100644 index 000000000..9aa9eaefd --- /dev/null +++ b/components/esm/dialoguestate.hpp @@ -0,0 +1,23 @@ +#ifndef OPENMW_ESM_DIALOGUESTATE_H +#define OPENMW_ESM_DIALOGUESTATE_H + +#include +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + // format 0, saved games only + + struct DialogueState + { + std::vector mKnownTopics; + + void load (ESMReader &esm); + void save (ESMWriter &esm) const; + }; +} + +#endif \ No newline at end of file