From e1458453f3e04f73f915994134cb353a9a379136 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 18 May 2014 06:49:24 +0200 Subject: [PATCH] Fix "unknown info ID" exceptions when a dialogue response is from the Info Refusal group Could be observed in TG_OverduePayments quest when talking to Trasteve about Dwemer Artifacts. Info Refusal responses are not specific to any particular topic, so they should not be added to the journal. Trying to do so anyway will cause "unknown id" exceptions because MWDialogue::Entry expects the infoId to be from the Dialogue for the supplied topic. --- apps/openmw/mwbase/journal.hpp | 2 +- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 27 +++++++++++++++++-- apps/openmw/mwdialogue/filter.hpp | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwbase/journal.hpp b/apps/openmw/mwbase/journal.hpp index 7f06320aa..a49ebb9bc 100644 --- a/apps/openmw/mwbase/journal.hpp +++ b/apps/openmw/mwbase/journal.hpp @@ -37,7 +37,7 @@ namespace MWBase typedef std::deque TEntryContainer; typedef TEntryContainer::const_iterator TEntryIter; - typedef std::map TQuestContainer; // topc, quest + typedef std::map TQuestContainer; // topic, quest typedef TQuestContainer::const_iterator TQuestIter; typedef std::map TTopicContainer; // topic-id, topic-content typedef TTopicContainer::const_iterator TTopicIter; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 8c425caa0..323b45064 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -286,7 +286,18 @@ namespace MWDialogue MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); win->addResponse (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext), title); - MWBase::Environment::get().getJournal()->addTopic (topic, info->mId, mActor.getClass().getName(mActor)); + + // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, + // in which case it should not be added to the journal. + for (std::vector::const_iterator iter = dialogue.mInfo.begin(); + iter!=dialogue.mInfo.end(); ++iter) + { + if (iter->mId == info->mId) + { + MWBase::Environment::get().getJournal()->addTopic (topic, info->mId, mActor.getClass().getName(mActor)); + break; + } + } executeScript (info->mResultScript); @@ -453,7 +464,19 @@ namespace MWDialogue MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse (Interpreter::fixDefinesDialog(text, interpreterContext)); - MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId, mActor.getClass().getName(mActor)); + + // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, + // in which case it should not be added to the journal. + for (std::vector::const_iterator iter = mDialogueMap[mLastTopic].mInfo.begin(); + iter!=mDialogueMap[mLastTopic].mInfo.end(); ++iter) + { + if (iter->mId == info->mId) + { + MWBase::Environment::get().getJournal()->addTopic (mLastTopic, info->mId, mActor.getClass().getName(mActor)); + break; + } + } + executeScript (info->mResultScript); } } diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 5c6d092ad..7e7f2b6f5 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -55,6 +55,7 @@ namespace MWDialogue std::vector list (const ESM::Dialogue& dialogue, bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const; + ///< \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue. const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; ///< Get a matching response for the requested dialogue.