From cebcbe11f8f8fca480b6271b568761c7f03e8036 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 16 Mar 2013 20:32:21 +0100 Subject: [PATCH] Implemented service refusal --- apps/openmw/mwbase/dialoguemanager.hpp | 2 + apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 31 ++++++++++ apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 2 + apps/openmw/mwdialogue/filter.cpp | 13 ++-- apps/openmw/mwdialogue/filter.hpp | 6 +- apps/openmw/mwgui/dialogue.cpp | 60 ++++++++++--------- 6 files changed, 76 insertions(+), 38 deletions(-) diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index a205e78db7..db86385d4e 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -41,6 +41,8 @@ namespace MWBase virtual void goodbyeSelected() = 0; virtual void questionAnswered (const std::string& answer) = 0; + virtual bool checkServiceRefused () = 0; + virtual void persuade (int type) = 0; virtual int getTemporaryDispositionChange () const = 0; virtual void applyTemporaryDispositionChange (int delta) = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 35f0c94937..62ee09bdba 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -518,6 +518,37 @@ namespace MWDialogue mTemporaryDispositionChange += delta; } + bool DialogueManager::checkServiceRefused() + { + Filter filter (mActor, mChoice, mTalkedTo); + + const MWWorld::Store &dialogues = + MWBase::Environment::get().getWorld()->getStore().get(); + + const ESM::Dialogue& dialogue = *dialogues.find ("Service Refusal"); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); + + std::vector infos = filter.list (dialogue, false, false, true); + if (!infos.empty()) + { + const ESM::DialInfo* info = infos[0]; + + parseText (info->mResponse); + + const MWWorld::Store& gmsts = + MWBase::Environment::get().getWorld()->getStore().get(); + + win->addTitle (gmsts.find ("sServiceRefusal")->getString()); + + MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); + win->addText (Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); + + executeScript (info->mResultScript); + return true; + } + return false; + } + std::vector ParseHyperText(const std::string& text) { std::vector result; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index 1ca2ae5ebc..ad537b0ad4 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -65,6 +65,8 @@ namespace MWDialogue virtual MWWorld::Ptr getActor() const; ///< Return the actor the player is currently talking to. + virtual bool checkServiceRefused (); + //calbacks for the GUI virtual void keywordSelected (const std::string& keyword); virtual void goodbyeSelected(); diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 10740794ea..906e30c768 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -121,7 +121,7 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const return true; } -bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info) const +bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info, bool invert) const { bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name()); @@ -129,8 +129,9 @@ bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info) const return true; int actorDisposition = MWBase::Environment::get().getMechanicsManager()->getDerivedDisposition(mActor); - - return actorDisposition >= info.mData.mDisposition; + // For service refusal, the disposition check is inverted. However, a value of 0 still means "always succeed". + return invert ? (info.mData.mDisposition == 0 || actorDisposition < info.mData.mDisposition) + : (actorDisposition >= info.mData.mDisposition); } bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const @@ -570,7 +571,7 @@ const ESM::DialInfo* MWDialogue::Filter::search (const ESM::Dialogue& dialogue, } std::vector MWDialogue::Filter::list (const ESM::Dialogue& dialogue, - bool fallbackToInfoRefusal, bool searchAll) const + bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition) const { std::vector infos; @@ -582,7 +583,7 @@ std::vector MWDialogue::Filter::list (const ESM::Dialogue { if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter)) { - if (testDisposition (*iter)) { + if (testDisposition (*iter, invertDisposition)) { infos.push_back(&*iter); if (!searchAll) break; @@ -604,7 +605,7 @@ std::vector MWDialogue::Filter::list (const ESM::Dialogue for (std::vector::const_iterator iter = infoRefusalDialogue.mInfo.begin(); iter!=infoRefusalDialogue.mInfo.end(); ++iter) - if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter)) { + if (testActor (*iter) && testPlayer (*iter) && testSelectStructs (*iter) && testDisposition(*iter, invertDisposition)) { infos.push_back(&*iter); if (!searchAll) break; diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 069bf6353d..5c6d092ad9 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -30,8 +30,8 @@ namespace MWDialogue 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 testDisposition (const ESM::DialInfo& info, bool invert=false) const; + ///< Is the actor disposition toward the player high enough (or low enough, if \a invert is true)? bool testSelectStruct (const SelectWrapper& select) const; @@ -54,7 +54,7 @@ namespace MWDialogue Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); std::vector list (const ESM::Dialogue& dialogue, - bool fallbackToInfoRefusal, bool searchAll) const; + bool fallbackToInfoRefusal, bool searchAll, bool invertDisposition=false) const; const ESM::DialInfo* search (const ESM::Dialogue& dialogue, const bool fallbackToInfoRefusal) const; ///< Get a matching response for the requested dialogue. diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index cdcbfc4d18..c500cd1747 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -241,40 +241,42 @@ void DialogueWindow::onSelectTopic(const std::string& topic, int id) const MWWorld::Store &gmst = MWBase::Environment::get().getWorld()->getStore().get(); - if (topic == gmst.find("sBarter")->getString()) - { - /// \todo check if the player is allowed to trade with this actor (e.g. faction rank high enough)? - mWindowManager.pushGuiMode(GM_Barter); - mWindowManager.getTradeWindow()->startTrade(mPtr); - } if (topic == gmst.find("sPersuasion")->getString()) { mPersuasionDialog.setVisible(true); } - else if (topic == gmst.find("sSpells")->getString()) + else if (!MWBase::Environment::get().getDialogueManager()->checkServiceRefused()) { - mWindowManager.pushGuiMode(GM_SpellBuying); - mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); - } - else if (topic == gmst.find("sTravel")->getString()) - { - mWindowManager.pushGuiMode(GM_Travel); - mWindowManager.getTravelWindow()->startTravel(mPtr); - } - else if (topic == gmst.find("sSpellMakingMenuTitle")->getString()) - { - mWindowManager.pushGuiMode(GM_SpellCreation); - mWindowManager.startSpellMaking (mPtr); - } - else if (topic == gmst.find("sEnchanting")->getString()) - { - mWindowManager.pushGuiMode(GM_Enchanting); - mWindowManager.startEnchanting (mPtr); - } - else if (topic == gmst.find("sServiceTrainingTitle")->getString()) - { - mWindowManager.pushGuiMode(GM_Training); - mWindowManager.startTraining (mPtr); + if (topic == gmst.find("sBarter")->getString()) + { + mWindowManager.pushGuiMode(GM_Barter); + mWindowManager.getTradeWindow()->startTrade(mPtr); + } + else if (topic == gmst.find("sSpells")->getString()) + { + mWindowManager.pushGuiMode(GM_SpellBuying); + mWindowManager.getSpellBuyingWindow()->startSpellBuying(mPtr); + } + else if (topic == gmst.find("sTravel")->getString()) + { + mWindowManager.pushGuiMode(GM_Travel); + mWindowManager.getTravelWindow()->startTravel(mPtr); + } + else if (topic == gmst.find("sSpellMakingMenuTitle")->getString()) + { + mWindowManager.pushGuiMode(GM_SpellCreation); + mWindowManager.startSpellMaking (mPtr); + } + else if (topic == gmst.find("sEnchanting")->getString()) + { + mWindowManager.pushGuiMode(GM_Enchanting); + mWindowManager.startEnchanting (mPtr); + } + else if (topic == gmst.find("sServiceTrainingTitle")->getString()) + { + mWindowManager.pushGuiMode(GM_Training); + mWindowManager.startTraining (mPtr); + } } } }