diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 160af0f772..320a082a54 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -159,12 +159,12 @@ namespace MWDialogue Filter filter(actor, mChoice, mTalkedTo); - for (MWWorld::Store::iterator it = dialogs.begin(); it != dialogs.end(); ++it) + for (const ESM::Dialogue& dialogue : dialogs) { - if (it->mType == ESM::Dialogue::Greeting) + if (dialogue.mType == ESM::Dialogue::Greeting) { // Search a response (we do not accept a fallback to "Info refusal" here) - if (const ESM::DialInfo* info = filter.search(*it, false)) + if (const ESM::DialInfo* info = filter.search(dialogue, false).second) { creatureStats.talkedToPlayer(); @@ -176,7 +176,7 @@ namespace MWDialogue MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(), mActor); callback->addResponse({}, Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); executeScript(info->mResultScript, mActor); - mLastTopic = it->mId; + mLastTopic = dialogue.mId; addTopicsFromText(info->mResponse); @@ -291,11 +291,11 @@ namespace MWDialogue const ESM::Dialogue& dialogue = *dialogues.find(topic); - const ESM::DialInfo* info = filter.search(dialogue, true); + const auto [responseTopic, info] = filter.search(dialogue, true); if (info) { - std::string title; + std::string_view title; if (dialogue.mType == ESM::Dialogue::Persuasion) { // Determine GMST from dialogue topic. GMSTs are: @@ -320,15 +320,8 @@ namespace MWDialogue { // 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 (ESM::Dialogue::InfoContainer::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); - break; - } - } + if (responseTopic == &dialogue) + MWBase::Environment::get().getJournal()->addTopic(topic, info->mId, mActor); } mLastTopic = topic; @@ -363,7 +356,7 @@ namespace MWDialogue { if (dialog.mType == ESM::Dialogue::Topic) { - const auto* answer = filter.search(dialog, true); + const auto* answer = filter.search(dialog, true).second; const auto& topicId = dialog.mId; if (answer != nullptr) @@ -477,9 +470,10 @@ namespace MWDialogue if (dialogue->mType == ESM::Dialogue::Topic || dialogue->mType == ESM::Dialogue::Greeting) { - if (const ESM::DialInfo* info = filter.search(*dialogue, true)) + const auto [responseTopic, info] = filter.search(*dialogue, true); + if (info) { - std::string text = info->mResponse; + const std::string& text = info->mResponse; addTopicsFromText(text); mChoice = -1; @@ -493,15 +487,8 @@ namespace MWDialogue { // 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 (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue->mInfo.begin(); - iter != dialogue->mInfo.end(); ++iter) - { - if (iter->mId == info->mId) - { - MWBase::Environment::get().getJournal()->addTopic(mLastTopic, info->mId, mActor); - break; - } - } + if (responseTopic == dialogue) + MWBase::Environment::get().getJournal()->addTopic(mLastTopic, info->mId, mActor); } executeScript(info->mResultScript, mActor); @@ -609,10 +596,10 @@ namespace MWDialogue const ESM::Dialogue& dialogue = *dialogues.find(ESM::RefId::stringRefId("Service Refusal")); - std::vector infos = filter.list(dialogue, false, false, true); + std::vector infos = filter.list(dialogue, false, false, true); if (!infos.empty()) { - const ESM::DialInfo* info = infos[0]; + const ESM::DialInfo* info = infos[0].second; addTopicsFromText(info->mResponse); @@ -656,7 +643,7 @@ namespace MWDialogue const MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); Filter filter(actor, 0, creatureStats.hasTalkedToPlayer()); - const ESM::DialInfo* info = filter.search(*dial, false); + const ESM::DialInfo* info = filter.search(*dial, false).second; if (info != nullptr) { MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager(); @@ -697,10 +684,9 @@ namespace MWDialogue ESM::DialogueState state; state.load(reader); - for (std::vector::const_iterator iter(state.mKnownTopics.begin()); - iter != state.mKnownTopics.end(); ++iter) - if (store.get().search(*iter)) - mKnownTopics.insert(*iter); + for (const auto& knownTopic : state.mKnownTopics) + if (store.get().search(knownTopic)) + mKnownTopics.insert(knownTopic); mChangedFactionReaction = state.mChangedFactionReaction; } diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index f9f7f37d28..0ad82be488 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -678,12 +678,13 @@ MWDialogue::Filter::Filter(const MWWorld::Ptr& actor, int choice, bool talkedToP { } -const ESM::DialInfo* MWDialogue::Filter::search(const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const +MWDialogue::Filter::Response MWDialogue::Filter::search( + const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const { - std::vector suitableInfos = list(dialogue, fallbackToInfoRefusal, false); + auto suitableInfos = list(dialogue, fallbackToInfoRefusal, false); if (suitableInfos.empty()) - return nullptr; + return {}; else return suitableInfos[0]; } @@ -693,22 +694,21 @@ bool MWDialogue::Filter::couldPotentiallyMatch(const ESM::DialInfo& info) const return testActor(info) && matchesStaticFilters(info, mActor); } -std::vector MWDialogue::Filter::list( +std::vector MWDialogue::Filter::list( const ESM::Dialogue& dialogue, bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const { - std::vector infos; + std::vector infos; bool infoRefusal = false; // Iterate over topic responses to find a matching one - for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue.mInfo.begin(); iter != dialogue.mInfo.end(); - ++iter) + for (const auto& info : dialogue.mInfo) { - if (testActor(*iter) && testPlayer(*iter) && testSelectStructs(*iter)) + if (testActor(info) && testPlayer(info) && testSelectStructs(info)) { - if (testDisposition(*iter, invertDisposition)) + if (testDisposition(info, invertDisposition)) { - infos.push_back(&*iter); + infos.emplace_back(&dialogue, &info); if (!searchAll) break; } @@ -726,12 +726,11 @@ std::vector MWDialogue::Filter::list( const ESM::Dialogue& infoRefusalDialogue = *dialogues.find(ESM::RefId::stringRefId("Info Refusal")); - for (ESM::Dialogue::InfoContainer::const_iterator iter = infoRefusalDialogue.mInfo.begin(); - iter != infoRefusalDialogue.mInfo.end(); ++iter) - if (testActor(*iter) && testPlayer(*iter) && testSelectStructs(*iter) - && testDisposition(*iter, invertDisposition)) + for (const auto& info : infoRefusalDialogue.mInfo) + if (testActor(info) && testPlayer(info) && testSelectStructs(info) + && testDisposition(info, invertDisposition)) { - infos.push_back(&*iter); + infos.emplace_back(&dialogue, &info); if (!searchAll) break; } diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 74afb41425..c44122aa52 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -1,6 +1,7 @@ #ifndef GAME_MWDIALOGUE_FILTER_H #define GAME_MWDIALOGUE_FILTER_H +#include #include #include "../mwworld/ptr.hpp" @@ -52,10 +53,12 @@ namespace MWDialogue const MWWorld::Ptr& actor, const ESM::RefId& factionId, int rank) const; public: + using Response = std::pair; + Filter(const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); - std::vector list(const ESM::Dialogue& dialogue, bool fallbackToInfoRefusal, - bool searchAll, bool invertDisposition = false) const; + std::vector list(const ESM::Dialogue& dialogue, bool fallbackToInfoRefusal, bool searchAll, + bool invertDisposition = false) const; ///< List all infos that could be used on the given actor, using the current runtime state of the actor. /// \note If fallbackToInfoRefusal is used, the returned DialInfo might not be from the supplied ESM::Dialogue. @@ -63,7 +66,7 @@ namespace MWDialogue ///< Check if this INFO could potentially be said by the given actor, ignoring runtime state filters and ///< ignoring player filters. - const ESM::DialInfo* search(const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; + Response search(const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; ///< Get a matching response for the requested dialogue. /// Redirect to "Info Refusal" topic if a response fulfills all conditions but disposition. };