From c382910c1fe6ef0d5bb301708e93a700b66a78ef Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Sat, 12 Feb 2022 13:25:27 +0100 Subject: [PATCH] Restart all quests with the same name when a quest is restarted --- CHANGELOG.md | 1 + apps/openmw/mwdialogue/journalimp.cpp | 13 +++++++++- apps/openmw/mwdialogue/quest.cpp | 37 +++++++++++---------------- apps/openmw/mwdialogue/quest.hpp | 5 ++-- apps/openmw/mwdialogue/topic.cpp | 5 ++-- apps/openmw/mwdialogue/topic.hpp | 2 +- 6 files changed, 35 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b26d758847..2cc4fee33b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -273,6 +273,7 @@ Bug #6142: Groundcover plugins change cells flags Bug #6276: Deleted groundcover instances are not deleted in game Bug #6294: Game crashes with empty pathgrid + Bug #6606: Quests with multiple IDs cannot always be restarted Feature #390: 3rd person look "over the shoulder" Feature #832: OpenMW-CS: Handle deleted references Feature #1536: Show more information about level on menu diff --git a/apps/openmw/mwdialogue/journalimp.cpp b/apps/openmw/mwdialogue/journalimp.cpp index 9f4c8c3689..41b30a95ce 100644 --- a/apps/openmw/mwdialogue/journalimp.cpp +++ b/apps/openmw/mwdialogue/journalimp.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include "../mwworld/esmstore.hpp" #include "../mwworld/class.hpp" @@ -93,7 +95,16 @@ namespace MWDialogue StampedJournalEntry entry = StampedJournalEntry::makeFromQuest (id, index, actor); Quest& quest = getQuest (id); - quest.addEntry (entry); // we are doing slicing on purpose here + if(quest.addEntry(entry)) // we are doing slicing on purpose here + { + // Restart all "other" quests with the same name as well + std::string name = quest.getName(); + for(auto& it : mQuests) + { + if(it.second.isFinished() && Misc::StringUtils::ciEqual(it.second.getName(), name)) + it.second.setFinished(false); + } + } // there is no need to show empty entries in journal if (!entry.getText().empty()) diff --git a/apps/openmw/mwdialogue/quest.cpp b/apps/openmw/mwdialogue/quest.cpp index 16e229ca7f..ce05676965 100644 --- a/apps/openmw/mwdialogue/quest.cpp +++ b/apps/openmw/mwdialogue/quest.cpp @@ -1,5 +1,7 @@ #include "quest.hpp" +#include + #include #include "../mwworld/esmstore.hpp" @@ -50,42 +52,33 @@ namespace MWDialogue return mFinished; } - void Quest::addEntry (const JournalEntry& entry) + void Quest::setFinished(bool finished) { - int index = -1; + mFinished = finished; + } + bool Quest::addEntry (const JournalEntry& entry) + { const ESM::Dialogue *dialogue = MWBase::Environment::get().getWorld()->getStore().get().find (entry.mTopic); - for (ESM::Dialogue::InfoContainer::const_iterator iter (dialogue->mInfo.begin()); - iter!=dialogue->mInfo.end(); ++iter) - if (iter->mId == entry.mInfoId) - { - index = iter->mData.mJournalIndex; - break; - } + auto info = std::find_if(dialogue->mInfo.begin(), dialogue->mInfo.end(), [&](const auto& info) { return info.mId == entry.mInfoId; }); - if (index==-1) + if (info == dialogue->mInfo.end() || info->mData.mJournalIndex == -1) throw std::runtime_error ("unknown journal entry for topic " + mTopic); - for (auto &info : dialogue->mInfo) - { - if (info.mData.mJournalIndex == index - && (info.mQuestStatus == ESM::DialInfo::QS_Finished || info.mQuestStatus == ESM::DialInfo::QS_Restart)) - { - mFinished = (info.mQuestStatus == ESM::DialInfo::QS_Finished); - break; - } - } + if (info->mQuestStatus == ESM::DialInfo::QS_Finished || info->mQuestStatus == ESM::DialInfo::QS_Restart) + mFinished = info->mQuestStatus == ESM::DialInfo::QS_Finished; - if (index > mIndex) - mIndex = index; + if (info->mData.mJournalIndex > mIndex) + mIndex = info->mData.mJournalIndex; for (TEntryIter iter (mEntries.begin()); iter!=mEntries.end(); ++iter) if (iter->mInfoId==entry.mInfoId) - return; + return info->mQuestStatus == ESM::DialInfo::QS_Restart; mEntries.push_back (entry); // we want slicing here + return info->mQuestStatus == ESM::DialInfo::QS_Restart; } void Quest::write (ESM::QuestState& state) const diff --git a/apps/openmw/mwdialogue/quest.hpp b/apps/openmw/mwdialogue/quest.hpp index 712f94fae4..53b4d02f65 100644 --- a/apps/openmw/mwdialogue/quest.hpp +++ b/apps/openmw/mwdialogue/quest.hpp @@ -33,9 +33,10 @@ namespace MWDialogue ///< Calling this function with a non-existent index will throw an exception. bool isFinished() const; + void setFinished(bool finished); - void addEntry (const JournalEntry& entry) override; - ///< Add entry and adjust index accordingly. + bool addEntry (const JournalEntry& entry) override; + ///< Add entry and adjust index accordingly. Returns true if the quest should be restarted. /// /// \note Redundant entries are ignored, but the index is still adjusted. diff --git a/apps/openmw/mwdialogue/topic.cpp b/apps/openmw/mwdialogue/topic.cpp index eb7fbdc1de..9d56028184 100644 --- a/apps/openmw/mwdialogue/topic.cpp +++ b/apps/openmw/mwdialogue/topic.cpp @@ -18,7 +18,7 @@ namespace MWDialogue Topic::~Topic() {} - void Topic::addEntry (const JournalEntry& entry) + bool Topic::addEntry (const JournalEntry& entry) { if (entry.mTopic!=mTopic) throw std::runtime_error ("topic does not match: " + mTopic); @@ -27,10 +27,11 @@ namespace MWDialogue for (Topic::TEntryIter it = mEntries.begin(); it != mEntries.end(); ++it) { if (it->mInfoId == entry.mInfoId) - return; + return false; } mEntries.push_back (entry); // we want slicing here + return false; } void Topic::insertEntry (const ESM::JournalEntry& entry) diff --git a/apps/openmw/mwdialogue/topic.hpp b/apps/openmw/mwdialogue/topic.hpp index 72486ef8af..12df484aa7 100644 --- a/apps/openmw/mwdialogue/topic.hpp +++ b/apps/openmw/mwdialogue/topic.hpp @@ -35,7 +35,7 @@ namespace MWDialogue virtual ~Topic(); - virtual void addEntry (const JournalEntry& entry); + virtual bool addEntry (const JournalEntry& entry); ///< Add entry /// /// \note Redundant entries are ignored.