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.
This commit is contained in:
scrawl 2014-05-18 06:49:24 +02:00
parent b4ed828e21
commit e1458453f3
3 changed files with 27 additions and 3 deletions

View file

@ -37,7 +37,7 @@ namespace MWBase
typedef std::deque<MWDialogue::StampedJournalEntry> TEntryContainer;
typedef TEntryContainer::const_iterator TEntryIter;
typedef std::map<std::string, MWDialogue::Quest> TQuestContainer; // topc, quest
typedef std::map<std::string, MWDialogue::Quest> TQuestContainer; // topic, quest
typedef TQuestContainer::const_iterator TQuestIter;
typedef std::map<std::string, MWDialogue::Topic> TTopicContainer; // topic-id, topic-content
typedef TTopicContainer::const_iterator TTopicIter;

View file

@ -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<ESM::DialInfo>::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<ESM::DialInfo>::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);
}
}

View file

@ -55,6 +55,7 @@ namespace MWDialogue
std::vector<const ESM::DialInfo *> 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.