diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 99be5554a..d515c3ac4 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -121,6 +121,13 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const return true; } +bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info) const +{ + int actorDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor); + + return actorDisposition >= info.mData.mDisposition; +} + bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const { if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name()) @@ -547,17 +554,38 @@ MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedTo : mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer) {} -bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const -{ - return testActor (info) && testPlayer (info) && testSelectStructs (info); -} - const ESM::DialInfo *MWDialogue::Filter::search (const ESM::Dialogue& dialogue) const { + bool infoRefusal = false; + + // Iterate over topic responses to find a matching one for (std::vector::const_iterator iter = dialogue.mInfo.begin(); iter!=dialogue.mInfo.end(); ++iter) - if ((*this) (*iter)) - return &*iter; + { + if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter)) + { + if (testDisposition (*iter)) + return &*iter; + else + infoRefusal = true; + } + } + + if (infoRefusal) + { + // No response is valid because of low NPC disposition, + // search a response in the topic "Info Refusal" + + const MWWorld::Store &dialogues = + MWBase::Environment::get().getWorld()->getStore().get(); + + const ESM::Dialogue& infoRefusalDialogue = *dialogues.find ("Info Refusal"); + + for (std::vector::const_iterator iter = infoRefusalDialogue.mInfo.begin(); + iter!=infoRefusalDialogue.mInfo.end(); ++iter) + if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter)) + return &*iter; + } return 0; } diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 7c8f1116f..aa8934bfc 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -18,39 +18,39 @@ namespace MWDialogue MWWorld::Ptr mActor; int mChoice; bool mTalkedToPlayer; - + bool testActor (const ESM::DialInfo& info) const; ///< Is this the right actor for this \a info? - + bool testPlayer (const ESM::DialInfo& info) const; ///< Do the player and the cell the player is currently in match \a info? - + bool testSelectStructs (const ESM::DialInfo& info) const; ///< Are all select structs matching? - + + bool testDisposition (const ESM::DialInfo& info) const; + ///< Is the actor disposition toward the player high enough? + bool testSelectStruct (const SelectWrapper& select) const; - + bool testSelectStructNumeric (const SelectWrapper& select) const; - + int getSelectStructInteger (const SelectWrapper& select) const; - + bool getSelectStructBoolean (const SelectWrapper& select) const; - + int getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const; - + bool hasFactionRankSkillRequirements (const MWWorld::Ptr& actor, const std::string& factionId, int rank) const; bool hasFactionRankReputationRequirements (const MWWorld::Ptr& actor, const std::string& factionId, int rank) const; - + public: - - Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); - bool operator() (const ESM::DialInfo& info) const; - ///< \return does the dialogue match? - + Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); + const ESM::DialInfo *search (const ESM::Dialogue& dialogue) const; }; }