From b0f98687e6a9c2d9e240fd47c8a7b5bd64c5572c Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 Oct 2014 17:45:18 +0200 Subject: [PATCH] Properly handle DialInfo records that were marked as Deleted (Fixes #2035) --- apps/openmw/mwworld/esmstore.cpp | 1 + apps/openmw/mwworld/store.hpp | 19 +++++++++++++++++++ components/esm/loaddial.cpp | 11 +++++++++++ components/esm/loaddial.hpp | 3 +++ 4 files changed, 34 insertions(+) diff --git a/apps/openmw/mwworld/esmstore.cpp b/apps/openmw/mwworld/esmstore.cpp index 1b5d3d1e9..56cb05c64 100644 --- a/apps/openmw/mwworld/esmstore.cpp +++ b/apps/openmw/mwworld/esmstore.cpp @@ -135,6 +135,7 @@ void ESMStore::setUp() mSkills.setUp(); mMagicEffects.setUp(); mAttributes.setUp(); + mDialogs.setUp(); } int ESMStore::countSavedGameRecords() const diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 107db68b1..2611bacbd 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -1174,6 +1174,25 @@ namespace MWWorld mShared.erase(mShared.begin() + mStatic.size(), mShared.end()); } + template<> + inline void Store::setUp() + { + // DialInfos marked as deleted are kept during the loading phase, so that the linked list + // structure is kept intact for inserting further INFOs. Delete them now that loading is done. + for (Static::iterator it = mStatic.begin(); it != mStatic.end(); ++it) + { + ESM::Dialogue& dial = it->second; + dial.clearDeletedInfos(); + } + + mShared.clear(); + mShared.reserve(mStatic.size()); + typename std::map::iterator it = mStatic.begin(); + for (; it != mStatic.end(); ++it) { + mShared.push_back(&(it->second)); + } + } + } //end namespace #endif diff --git a/components/esm/loaddial.cpp b/components/esm/loaddial.cpp index 92077b572..ff0362aa2 100644 --- a/components/esm/loaddial.cpp +++ b/components/esm/loaddial.cpp @@ -110,4 +110,15 @@ void Dialogue::readInfo(ESMReader &esm, bool merge) std::cerr << "Failed to insert info " << id << std::endl; } +void Dialogue::clearDeletedInfos() +{ + for (InfoContainer::iterator it = mInfo.begin(); it != mInfo.end(); ) + { + if (it->mQuestStatus == DialInfo::QS_Deleted) + it = mInfo.erase(it); + else + ++it; + } +} + } diff --git a/components/esm/loaddial.hpp b/components/esm/loaddial.hpp index fd46ad210..d29948c63 100644 --- a/components/esm/loaddial.hpp +++ b/components/esm/loaddial.hpp @@ -47,6 +47,9 @@ struct Dialogue void load(ESMReader &esm); void save(ESMWriter &esm) const; + /// Remove all INFOs marked as QS_Deleted from mInfos. + void clearDeletedInfos(); + /// Read the next info record /// @param merge Merge with existing list, or just push each record to the end of the list? void readInfo (ESM::ESMReader& esm, bool merge);