mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 07:21:12 +00:00
Merge branch 'quest_redo' into 'master'
Restart all quests with the same name when a quest is restarted Closes #6606 See merge request OpenMW/openmw!1651
This commit is contained in:
commit
bd8c75daee
@ -274,6 +274,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
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <components/esm3/queststate.hpp>
|
||||
#include <components/esm3/journalentry.hpp>
|
||||
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
#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())
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include "quest.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <components/esm3/queststate.hpp>
|
||||
|
||||
#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<ESM::Dialogue>().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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user