From aabb1b8f3fa004faf87db6d0597559cb99ae6dda Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 4 Nov 2012 13:26:04 +0100 Subject: [PATCH 01/25] Issue #219: implemented death count filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 62f7df679..52b048b4b 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -14,6 +14,7 @@ #include "../mwbase/scriptmanager.hpp" #include "../mwbase/journal.hpp" #include "../mwbase/windowmanager.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/refdata.hpp" @@ -368,9 +369,12 @@ namespace MWDialogue return true; - - case '6'://dead - if(!selectCompare(comp,0,select.mI)) return false; + case '6': // dead +{ +std::cout<<"### "<countDeaths (toLower (name))< (comp, + MWBase::Environment::get().getMechanicsManager()->countDeaths (toLower (name)), select.mI); case '7':// not ID if(select.mType==ESM::VT_String ||select.mType==ESM::VT_Int)//bug in morrowind here? it's not a short, it's a string From 1502b3f6f8f9ad80ed6b78cdd686c899f2829094 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 14:09:40 +0100 Subject: [PATCH 02/25] Issue #219: Begin of refactoring; added filter class (doesn't do anything yet) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 21 ++++++++++----- apps/openmw/mwdialogue/filter.cpp | 10 +++++++ apps/openmw/mwdialogue/filter.hpp | 26 +++++++++++++++++++ 4 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 apps/openmw/mwdialogue/filter.cpp create mode 100644 apps/openmw/mwdialogue/filter.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index b9ce26a66..29f5f2ccc 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -34,7 +34,7 @@ add_openmw_dir (mwgui ) add_openmw_dir (mwdialogue - dialoguemanagerimp journalimp journalentry quest topic + dialoguemanagerimp journalimp journalentry quest topic filter ) add_openmw_dir (mwscript diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 772a1914d..5838b8c0d 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -39,6 +39,8 @@ #include "../mwclass/npc.hpp" #include "../mwmechanics/npcstats.hpp" +#include "filter.hpp" + namespace { std::string toLower (const std::string& name) @@ -370,9 +372,7 @@ namespace MWDialogue return true; case '6': // dead -{ -std::cout<<"### "<countDeaths (toLower (name))< (comp, MWBase::Environment::get().getMechanicsManager()->countDeaths (toLower (name)), select.mI); @@ -653,6 +653,8 @@ std::cout<<"### "< &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); + Filter filter (actor); + MWWorld::Store::iterator it = dialogs.begin(); for (; it != dialogs.end(); ++it) { @@ -662,7 +664,7 @@ std::cout<<"### "<::const_iterator iter (it->mInfo.begin()); iter!=it->mInfo.end(); ++iter) { - if (isMatching (actor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter) && isMatching (actor, *iter) && functionFilter(mActor,*iter,true)) { if (!iter->mSound.empty()) { @@ -755,6 +757,7 @@ std::cout<<"### "< &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); + Filter filter (mActor); MWWorld::Store::iterator it = dialogs.begin(); for (; it != dialogs.end(); ++it) @@ -764,7 +767,7 @@ std::cout<<"### "<::const_iterator iter (it->mInfo.begin()); iter!=it->mInfo.end(); ++iter) { - if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter) && isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) { mActorKnownTopics.push_back(toLower(it->mId)); //does the player know the topic? @@ -841,10 +844,12 @@ std::cout<<"### "<::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) { - if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter) && isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) { std::string text = iter->mResponse; std::string script = iter->mResultScript; @@ -886,10 +891,12 @@ std::cout<<"### "<::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) { - if (isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter) && isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) { mChoiceMap.clear(); mChoice = -1; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp new file mode 100644 index 000000000..982062e5b --- /dev/null +++ b/apps/openmw/mwdialogue/filter.cpp @@ -0,0 +1,10 @@ + +#include "filter.hpp" + +MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {} + +bool MWDialogue::Filter::operator() (const ESM::DialInfo& dialogue) +{ + + return true; +} diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp new file mode 100644 index 000000000..519393782 --- /dev/null +++ b/apps/openmw/mwdialogue/filter.hpp @@ -0,0 +1,26 @@ +#ifndef GAME_MWDIALOGUE_FILTER_H +#define GAME_MWDIALOGUE_FILTER_H + +#include "../mwworld/ptr.hpp" + +namespace ESM +{ + struct DialInfo; +} + +namespace MWDialogue +{ + class Filter + { + MWWorld::Ptr mActor; + + public: + + Filter (const MWWorld::Ptr& actor); + + bool operator() (const ESM::DialInfo& dialogue); + ///< \return does the dialogue match? + }; +} + +#endif From 662054acf4a2ee13542a4dde9208be2da4597fc8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 14:55:31 +0100 Subject: [PATCH 03/25] Issue #219: moved checks for various dialogue info fields from DialogueManager to Filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 96 +-------------- apps/openmw/mwdialogue/filter.cpp | 111 +++++++++++++++++- apps/openmw/mwdialogue/filter.hpp | 8 +- components/esm/loadinfo.hpp | 8 +- 4 files changed, 121 insertions(+), 102 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 5838b8c0d..37f3260c6 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -482,101 +482,7 @@ namespace MWDialogue bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const { - bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name()); - - // actor id - if (!info.mActor.empty()) - if (toLower (info.mActor)!=MWWorld::Class::get (actor).getId (actor)) - return false; - - //NPC race - if (!info.mRace.empty()) - { - if (isCreature) - return false; - - MWWorld::LiveCellRef *cellRef = actor.get(); - - if (!cellRef) - return false; - - if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace)) - return false; - } - - //NPC class - if (!info.mClass.empty()) - { - if (isCreature) - return false; - - MWWorld::LiveCellRef *cellRef = actor.get(); - - if (!cellRef) - return false; - - if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass)) - return false; - } - - //NPC faction - if (!info.mNpcFaction.empty()) - { - if (isCreature) - return false; - - //MWWorld::Class npcClass = MWWorld::Class::get(actor); - MWMechanics::NpcStats stats = MWWorld::Class::get(actor).getNpcStats(actor); - std::map::iterator it = stats.getFactionRanks().find(toLower(info.mNpcFaction)); - if(it!=stats.getFactionRanks().end()) - { - //check rank - if(it->second < (int)info.mData.mRank) return false; - } - else - { - //not in the faction - return false; - } - } - - // TODO check player faction - if(!info.mPcFaction.empty()) - { - MWMechanics::NpcStats stats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); - std::map::iterator it = stats.getFactionRanks().find(toLower(info.mPcFaction)); - if(it!=stats.getFactionRanks().end()) - { - //check rank - if(it->second < (int)info.mData.mPCrank) return false; - } - else - { - //not in the faction - return false; - } - } - - //check gender - if (!isCreature) - { - MWWorld::LiveCellRef* npc = actor.get(); - if(npc->mBase->mFlags & npc->mBase->Female) - { - if(static_cast (info.mData.mGender)==0) return false; - } - else - { - if(static_cast (info.mData.mGender)==1) return false; - } - } - - // check cell - if (!info.mCell.empty()) - if (MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mName != info.mCell) - return false; - - // TODO check DATAstruct + // check DATAstruct for (std::vector::const_iterator iter (info.mSelects.begin()); iter != info.mSelects.end(); ++iter) if (!isMatching (actor, *iter)) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 982062e5b..b69a6d727 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -1,10 +1,117 @@ #include "filter.hpp" -MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {} +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" -bool MWDialogue::Filter::operator() (const ESM::DialInfo& dialogue) +#include "../mwworld/class.hpp" +#include "../mwworld/player.hpp" + +#include "../mwmechanics/npcstats.hpp" + +namespace { + std::string toLower (const std::string& name) + { + std::string lowerCase; + + std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), + (int(*)(int)) std::tolower); + + return lowerCase; + } +} + +bool MWDialogue::Filter::testActor (const ESM::DialInfo& info) const +{ + // actor id + if (!info.mActor.empty()) + if (toLower (info.mActor)!=MWWorld::Class::get (mActor).getId (mActor)) + return false; + + bool isCreature = (mActor.getTypeName() != typeid (ESM::NPC).name()); + + // NPC race + if (!info.mRace.empty()) + { + if (isCreature) + return false; + + MWWorld::LiveCellRef *cellRef = mActor.get(); + + if (toLower (info.mRace)!=toLower (cellRef->mBase->mRace)) + return false; + } + + // NPC class + if (!info.mClass.empty()) + { + if (isCreature) + return false; + + MWWorld::LiveCellRef *cellRef = mActor.get(); + + if (toLower (info.mClass)!=toLower (cellRef->mBase->mClass)) + return false; + } + + // NPC faction + if (!info.mNpcFaction.empty()) + { + if (isCreature) + return false; + + MWMechanics::NpcStats& stats = MWWorld::Class::get (mActor).getNpcStats (mActor); + std::map::iterator iter = stats.getFactionRanks().find (toLower (info.mNpcFaction)); + + if (iter==stats.getFactionRanks().end()) + return false; + + // check rank + if (iter->second < info.mData.mRank) + return false; + } + + // Gender + if (!isCreature) + { + MWWorld::LiveCellRef* npc = mActor.get(); + if (info.mData.mGender==(npc->mBase->mFlags & npc->mBase->Female ? 0 : 1)) + return false; + } + + return true; +} + +bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const +{ + const MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + // check player faction + if (!info.mPcFaction.empty()) + { + MWMechanics::NpcStats& stats = MWWorld::Class::get (player).getNpcStats (player); + std::map::iterator iter = stats.getFactionRanks().find (toLower (info.mPcFaction)); + + if(iter==stats.getFactionRanks().end()) + return false; + + // check rank + if (iter->second < info.mData.mPCrank) + return false; + } + + // check cell + if (!info.mCell.empty()) + if (toLower (player.getCell()->mCell->mName) != toLower (info.mCell)) + return false; return true; } + +MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {} + +bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const +{ + return testActor (info) && testPlayer (info); +} diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 519393782..3ca4153b3 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -14,11 +14,17 @@ namespace MWDialogue { MWWorld::Ptr mActor; + 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? + public: Filter (const MWWorld::Ptr& actor); - bool operator() (const ESM::DialInfo& dialogue); + bool operator() (const ESM::DialInfo& info) const; ///< \return does the dialogue match? }; } diff --git a/components/esm/loadinfo.hpp b/components/esm/loadinfo.hpp index f04fe862e..f1decb9c6 100644 --- a/components/esm/loadinfo.hpp +++ b/components/esm/loadinfo.hpp @@ -32,10 +32,10 @@ struct DialInfo { int mUnknown1; int mDisposition; - char mRank; // Rank of NPC - char mGender; // See Gender enum - char mPCrank; // Player rank - char mUnknown2; + signed char mRank; // Rank of NPC + signed char mGender; // See Gender enum + signed char mPCrank; // Player rank + signed char mUnknown2; }; // 12 bytes DATAstruct mData; From 4614d2bc8ed0d804db910b1545901810be94f0c5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 16:49:38 +0100 Subject: [PATCH 04/25] Issue #219: added basic select struct analysis and type checking --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 5 -- apps/openmw/mwdialogue/filter.cpp | 46 +++++++++++++- apps/openmw/mwdialogue/filter.hpp | 11 ++++ apps/openmw/mwdialogue/selectwrapper.cpp | 62 +++++++++++++++++++ apps/openmw/mwdialogue/selectwrapper.hpp | 40 ++++++++++++ 6 files changed, 159 insertions(+), 7 deletions(-) create mode 100644 apps/openmw/mwdialogue/selectwrapper.cpp create mode 100644 apps/openmw/mwdialogue/selectwrapper.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 29f5f2ccc..57a417722 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -34,7 +34,7 @@ add_openmw_dir (mwgui ) add_openmw_dir (mwdialogue - dialoguemanagerimp journalimp journalentry quest topic filter + dialoguemanagerimp journalimp journalentry quest topic filter selectwrapper ) add_openmw_dir (mwscript diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 37f3260c6..37de30c96 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -469,11 +469,6 @@ namespace MWDialogue throw std::runtime_error ( "unsupported variable type in dialogue info select"); return true; - - - default: - - std::cout << "unchecked select: " << type << " " << comp << " " << name << std::endl; } } diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index b69a6d727..5161ea5ed 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -9,6 +9,8 @@ #include "../mwmechanics/npcstats.hpp" +#include "selectwrapper.hpp" + namespace { std::string toLower (const std::string& name) @@ -109,9 +111,51 @@ bool MWDialogue::Filter::testPlayer (const ESM::DialInfo& info) const return true; } +bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const +{ + for (std::vector::const_iterator iter (info.mSelects.begin()); + iter != info.mSelects.end(); ++iter) + if (!testSelectStruct (*iter)) + return false; + + return true; +} + +bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const +{ + switch (select.getType()) + { + case SelectWrapper::Type_None: return true; + case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select)); + case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select); + } + + return true; +} + +bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) const +{ + switch (select.getFunction()) + { + default: + + throw std::runtime_error ("unknown numeric select function"); + } +} + +int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const +{ + switch (select.getFunction()) + { + default: + + throw std::runtime_error ("unknown integer select function"); + } +} + MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {} bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const { - return testActor (info) && testPlayer (info); + return testActor (info) && testPlayer (info) && testSelectStructs (info); } diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 3ca4153b3..2b8410941 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -10,6 +10,8 @@ namespace ESM namespace MWDialogue { + class SelectWrapper; + class Filter { MWWorld::Ptr mActor; @@ -20,6 +22,15 @@ namespace MWDialogue 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 testSelectStruct (const SelectWrapper& select) const; + + bool testSelectStructNumeric (const SelectWrapper& select) const; + + int getSelectStructInteger (const SelectWrapper& select) const; + public: Filter (const MWWorld::Ptr& actor); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp new file mode 100644 index 000000000..a45c0adc0 --- /dev/null +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -0,0 +1,62 @@ + +#include "selectwrapper.hpp" + +#include + +namespace +{ + template + bool selectCompareImp (char comp, T1 value1, T2 value2) + { + switch (comp) + { + case '0': return value1==value2; + case '1': return value1!=value2; + case '2': return value1>value2; + case '3': return value1>=value2; + case '4': return value1 + bool selectCompareImp (const ESM::DialInfo::SelectStruct& select, T value1) + { + if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int || + select.mType==ESM::VT_Long) + { + return selectCompareImp (select.mSelectRule[4], value1, select.mI); + } + else if (select.mType==ESM::VT_Float) + { + return selectCompareImp (select.mSelectRule[4], value1, select.mF); + } + else + throw std::runtime_error ( + "unsupported variable type in dialogue info select"); + } +} + +MWDialogue::SelectWrapper::SelectWrapper (const ESM::DialInfo::SelectStruct& select) : mSelect (select) {} + +MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() const +{ + return Function_None; +} + +MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const +{ + return Type_None; +} + +bool MWDialogue::SelectWrapper::selectCompare (int value) const +{ + return selectCompareImp (mSelect, value); +} + +bool MWDialogue::SelectWrapper::selectCompare (float value) const +{ + return selectCompareImp (mSelect, value); +} diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp new file mode 100644 index 000000000..acc3e9cc4 --- /dev/null +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -0,0 +1,40 @@ +#ifndef GAME_MWDIALOGUE_SELECTWRAPPER_H +#define GAME_MWDIALOGUE_SELECTWRAPPER_H + +#include + +namespace MWDialogue +{ + class SelectWrapper + { + const ESM::DialInfo::SelectStruct& mSelect; + + public: + + enum Function + { + Function_None + }; + + enum Type + { + Type_None, + Type_Integer, + Type_Numeric + }; + + public: + + SelectWrapper (const ESM::DialInfo::SelectStruct& select); + + Function getFunction() const; + + Type getType() const; + + bool selectCompare (int value) const; + + bool selectCompare (float value) const; + }; +} + +#endif From b412ebd0af9c33585566c60dde59a928f720e891 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 17:01:26 +0100 Subject: [PATCH 05/25] Issue #219: Supoort for inverted select structs --- apps/openmw/mwdialogue/selectwrapper.cpp | 9 +++++++-- apps/openmw/mwdialogue/selectwrapper.hpp | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index a45c0adc0..704c4c7ef 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -51,12 +51,17 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const return Type_None; } +bool MWDialogue::SelectWrapper::IsInverted() const +{ + return false; +} + bool MWDialogue::SelectWrapper::selectCompare (int value) const { - return selectCompareImp (mSelect, value); + return selectCompareImp (mSelect, value)!=IsInverted(); // logic XOR } bool MWDialogue::SelectWrapper::selectCompare (float value) const { - return selectCompareImp (mSelect, value); + return selectCompareImp (mSelect, value)!=IsInverted(); // logic XOR } diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index acc3e9cc4..c4d954d53 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -31,6 +31,8 @@ namespace MWDialogue Type getType() const; + bool IsInverted() const; + bool selectCompare (int value) const; bool selectCompare (float value) const; From f5972a3080965a25438b938067d61b5a4f44168b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 17:04:44 +0100 Subject: [PATCH 06/25] Issue #219: Support for boolean select structs --- apps/openmw/mwdialogue/filter.cpp | 11 +++++++++++ apps/openmw/mwdialogue/filter.hpp | 2 ++ apps/openmw/mwdialogue/selectwrapper.cpp | 5 +++++ apps/openmw/mwdialogue/selectwrapper.hpp | 5 ++++- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 5161ea5ed..bded2aaec 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -128,6 +128,7 @@ bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const case SelectWrapper::Type_None: return true; case SelectWrapper::Type_Integer: return select.selectCompare (getSelectStructInteger (select)); case SelectWrapper::Type_Numeric: return testSelectStructNumeric (select); + case SelectWrapper::Type_Boolean: return select.selectCompare (getSelectStructBoolean (select)); } return true; @@ -153,6 +154,16 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con } } +bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const +{ + switch (select.getFunction()) + { + default: + + throw std::runtime_error ("unknown boolean select function"); + } +} + MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {} bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 2b8410941..4263920cb 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -30,6 +30,8 @@ namespace MWDialogue bool testSelectStructNumeric (const SelectWrapper& select) const; int getSelectStructInteger (const SelectWrapper& select) const; + + bool getSelectStructBoolean (const SelectWrapper& select) const; public: diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 704c4c7ef..4e740c62f 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -65,3 +65,8 @@ bool MWDialogue::SelectWrapper::selectCompare (float value) const { return selectCompareImp (mSelect, value)!=IsInverted(); // logic XOR } + +bool MWDialogue::SelectWrapper::selectCompare (bool value) const +{ + return selectCompareImp (mSelect, static_cast (value))!=IsInverted(); // logic XOR +} diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index c4d954d53..f1ac25209 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -20,7 +20,8 @@ namespace MWDialogue { Type_None, Type_Integer, - Type_Numeric + Type_Numeric, + Type_Boolean }; public: @@ -36,6 +37,8 @@ namespace MWDialogue bool selectCompare (int value) const; bool selectCompare (float value) const; + + bool selectCompare (bool value) const; }; } From 235397dde8c3d2cd2864256997362e42976b6708 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 17:29:10 +0100 Subject: [PATCH 07/25] Issue #219: added missing implemented for isInverted function --- apps/openmw/mwdialogue/selectwrapper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 4e740c62f..5efb93ed5 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -53,7 +53,9 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const bool MWDialogue::SelectWrapper::IsInverted() const { - return false; + char type = mSelect.mSelectRule[1]; + + return type=='7' || type=='8' || type=='9' || type=='A' || type=='B' || type=='C'; } bool MWDialogue::SelectWrapper::selectCompare (int value) const From 91afef140ba8705b15a32c5cc8629799e4b32204 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 21:16:49 +0100 Subject: [PATCH 08/25] Issue #219: moved first batch of integer type functions from DialogueManager to Filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 26 -------- apps/openmw/mwdialogue/filter.cpp | 22 +++++++ apps/openmw/mwdialogue/selectwrapper.cpp | 61 ++++++++++++++++++- apps/openmw/mwdialogue/selectwrapper.hpp | 7 ++- 4 files changed, 88 insertions(+), 28 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 37de30c96..3f7f954f6 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -345,32 +345,6 @@ namespace MWDialogue return true; - case '4'://journal - if(select.mType==ESM::VT_Int) - { - if(!selectCompare(comp,MWBase::Environment::get().getJournal()->getJournalIndex(toLower(name)),select.mI)) return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case '5'://item - { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player); - - int sum = 0; - - for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) - if (toLower(iter->getCellRef().mRefID) == toLower(name)) - sum += iter->getRefData().getCount(); - if(!selectCompare(comp,sum,select.mI)) return false; - } - - return true; - case '6': // dead return selectCompare (comp, diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index bded2aaec..eca7752e6 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -3,9 +3,11 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/journal.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" +#include "../mwworld/containerstore.hpp" #include "../mwmechanics/npcstats.hpp" @@ -148,6 +150,26 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con { switch (select.getFunction()) { + case SelectWrapper::Function_Journal: + + return MWBase::Environment::get().getJournal()->getJournalIndex (select.getName()); + + case SelectWrapper::Function_Item: + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player); + + int sum = 0; + + std::string name = select.getName(); + + for (MWWorld::ContainerStoreIterator iter (store.begin()); iter!=store.end(); ++iter) + if (toLower(iter->getCellRef().mRefID) == name) + sum += iter->getRefData().getCount(); + + return sum; + } + default: throw std::runtime_error ("unknown integer select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 5efb93ed5..8cd739d6a 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -1,10 +1,23 @@ #include "selectwrapper.hpp" +#include + #include +#include namespace { + std::string toLower (const std::string& name) + { + std::string lowerCase; + + std::transform (name.begin(), name.end(), std::back_inserter (lowerCase), + (int(*)(int)) std::tolower); + + return lowerCase; + } + template bool selectCompareImp (char comp, T1 value1, T2 value2) { @@ -43,12 +56,53 @@ MWDialogue::SelectWrapper::SelectWrapper (const ESM::DialInfo::SelectStruct& sel MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() const { + char type = mSelect.mSelectRule[1]; + + switch (type) + { + case '4': return Function_Journal; + case '5': return Function_Item; + } + return Function_None; } MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const { - return Type_None; + static const Function integerFunctions[] = + { + Function_Journal, Function_Item, + Function_None // end marker + }; + + static const Function numericFunctions[] = + { + Function_None // end marker + }; + + static const Function booleanFunctions[] = + { + Function_None // end marker + }; + + Function function = getFunction(); + + if (function==Function_None) + return Type_None; + + for (int i=0; integerFunctions[i]!=Function_None; ++i) + if (integerFunctions[i]==function) + return Type_Integer; + + for (int i=0; numericFunctions[i]!=Function_None; ++i) + if (numericFunctions[i]==function) + return Type_Numeric; + + for (int i=0; booleanFunctions[i]!=Function_None; ++i) + if (booleanFunctions[i]==function) + return Type_Boolean; + + throw std::runtime_error ("failed to determine type of select function"); } bool MWDialogue::SelectWrapper::IsInverted() const @@ -72,3 +126,8 @@ bool MWDialogue::SelectWrapper::selectCompare (bool value) const { return selectCompareImp (mSelect, static_cast (value))!=IsInverted(); // logic XOR } + +std::string MWDialogue::SelectWrapper::getName() const +{ + return toLower (mSelect.mSelectRule.substr (5)); +} diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index f1ac25209..1ba39128e 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -13,7 +13,9 @@ namespace MWDialogue enum Function { - Function_None + Function_None, + Function_Journal, + Function_Item }; enum Type @@ -39,6 +41,9 @@ namespace MWDialogue bool selectCompare (float value) const; bool selectCompare (bool value) const; + + std::string getName() const; + ///< Return case-smashed name. }; } From e68bb3481e3150bc3b3f70ecaeadb9b3ea32860a Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 21:48:17 +0100 Subject: [PATCH 09/25] Issue #219: moved over the second batch of functions (boolean and one integer I forgot last time) --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 82 ------------------- apps/openmw/mwdialogue/filter.cpp | 28 +++++++ apps/openmw/mwdialogue/selectwrapper.cpp | 41 +++++++--- apps/openmw/mwdialogue/selectwrapper.hpp | 13 ++- 4 files changed, 70 insertions(+), 94 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 3f7f954f6..5d3bebbc0 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -289,8 +289,6 @@ namespace MWDialogue bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const { - bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name()); - char type = select.mSelectRule[1]; if (type!='0') @@ -345,86 +343,6 @@ namespace MWDialogue return true; - case '6': // dead - - return selectCompare (comp, - MWBase::Environment::get().getMechanicsManager()->countDeaths (toLower (name)), select.mI); - - case '7':// not ID - if(select.mType==ESM::VT_String ||select.mType==ESM::VT_Int)//bug in morrowind here? it's not a short, it's a string - { - int isID = int(toLower(name)==toLower(MWWorld::Class::get (actor).getId (actor))); - if (selectCompare(comp,!isID,select.mI)) return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case '8':// not faction - if (isCreature) - return false; - - if(select.mType==ESM::VT_Int) - { - MWWorld::LiveCellRef* npc = actor.get(); - int isFaction = int(toLower(npc->mBase->mFaction) == toLower(name)); - if(selectCompare(comp,!isFaction,select.mI)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case '9':// not class - if (isCreature) - return false; - - if(select.mType==ESM::VT_Int) - { - MWWorld::LiveCellRef* npc = actor.get(); - int isClass = int(toLower(npc->mBase->mClass) == toLower(name)); - if(selectCompare(comp,!isClass,select.mI)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case 'A'://not Race - if (isCreature) - return false; - - if(select.mType==ESM::VT_Int) - { - MWWorld::LiveCellRef* npc = actor.get(); - int isRace = int(toLower(npc->mBase->mRace) == toLower(name)); - if(selectCompare(comp,!isRace,select.mI)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case 'B'://not Cell - if(select.mType==ESM::VT_Int) - { - int isCell = int(toLower(actor.getCell()->mCell->mName) == toLower(name)); - if(selectCompare(comp,!isCell,select.mI)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - return true; - case 'C'://not local if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int || select.mType==ESM::VT_Long) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index eca7752e6..9d14dbafc 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -4,6 +4,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/journal.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" @@ -125,6 +126,9 @@ bool MWDialogue::Filter::testSelectStructs (const ESM::DialInfo& info) const bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const { + if (select.isNpcOnly() && mActor.getTypeName()!=typeid (ESM::NPC).name()) + return select.isInverted(); + switch (select.getType()) { case SelectWrapper::Type_None: return true; @@ -169,6 +173,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return sum; } + + case SelectWrapper::Function_Dead: + + return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); default: @@ -180,6 +188,26 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co { switch (select.getFunction()) { + case SelectWrapper::Function_Id: + + return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor)); + + case SelectWrapper::Function_Faction: + + return toLower (mActor.get()->mBase->mFaction)==select.getName(); + + case SelectWrapper::Function_Class: + + return toLower (mActor.get()->mBase->mClass)==select.getName(); + + case SelectWrapper::Function_Race: + + return toLower (mActor.get()->mBase->mRace)==select.getName(); + + case SelectWrapper::Function_Cell: + + return toLower (mActor.getCell()->mCell->mName)==select.getName(); + default: throw std::runtime_error ("unknown boolean select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 8cd739d6a..90aa77f94 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -62,6 +62,12 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con { case '4': return Function_Journal; case '5': return Function_Item; + case '6': return Function_Dead; + case '7': return Function_Id; + case '8': return Function_Faction; + case '9': return Function_Class; + case 'A': return Function_Race; + case 'B': return Function_Cell; } return Function_None; @@ -71,7 +77,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const { static const Function integerFunctions[] = { - Function_Journal, Function_Item, + Function_Journal, Function_Item, Function_Dead, Function_None // end marker }; @@ -82,14 +88,12 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const static const Function booleanFunctions[] = { + Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell, Function_None // end marker }; Function function = getFunction(); - - if (function==Function_None) - return Type_None; - + for (int i=0; integerFunctions[i]!=Function_None; ++i) if (integerFunctions[i]==function) return Type_Integer; @@ -102,29 +106,46 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const if (booleanFunctions[i]==function) return Type_Boolean; - throw std::runtime_error ("failed to determine type of select function"); + return Type_None; } -bool MWDialogue::SelectWrapper::IsInverted() const +bool MWDialogue::SelectWrapper::isInverted() const { char type = mSelect.mSelectRule[1]; return type=='7' || type=='8' || type=='9' || type=='A' || type=='B' || type=='C'; } +bool MWDialogue::SelectWrapper::isNpcOnly() const +{ + static const Function functions[] = + { + Function_Faction, SelectWrapper::Function_Class, SelectWrapper::Function_Race, + Function_None // end marker + }; + + Function function = getFunction(); + + for (int i=0; functions[i]!=Function_None; ++i) + if (functions[i]==function) + return true; + + return false; +} + bool MWDialogue::SelectWrapper::selectCompare (int value) const { - return selectCompareImp (mSelect, value)!=IsInverted(); // logic XOR + return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR } bool MWDialogue::SelectWrapper::selectCompare (float value) const { - return selectCompareImp (mSelect, value)!=IsInverted(); // logic XOR + return selectCompareImp (mSelect, value)!=isInverted(); // logic XOR } bool MWDialogue::SelectWrapper::selectCompare (bool value) const { - return selectCompareImp (mSelect, static_cast (value))!=IsInverted(); // logic XOR + return selectCompareImp (mSelect, static_cast (value))!=isInverted(); // logic XOR } std::string MWDialogue::SelectWrapper::getName() const diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 1ba39128e..10a20ef74 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -15,7 +15,13 @@ namespace MWDialogue { Function_None, Function_Journal, - Function_Item + Function_Item, + Function_Dead, + Function_Id, + Function_Faction, + Function_Class, + Function_Race, + Function_Cell }; enum Type @@ -34,7 +40,10 @@ namespace MWDialogue Type getType() const; - bool IsInverted() const; + bool isInverted() const; + + bool isNpcOnly() const; + ///< \attention Do not call any of the select functions for this select struct! bool selectCompare (int value) const; From e6021a3fe3982acb7f35416aba5a4b43027359b8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 22:11:50 +0100 Subject: [PATCH 10/25] Issue #219: moved checks for local and global variables from DialogueManager to Filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 140 ------------------ apps/openmw/mwdialogue/filter.cpp | 42 ++++++ apps/openmw/mwdialogue/selectwrapper.cpp | 4 + apps/openmw/mwdialogue/selectwrapper.hpp | 4 +- 4 files changed, 49 insertions(+), 141 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 5d3bebbc0..e12a22247 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -84,71 +84,6 @@ namespace throw std::runtime_error ("unknown compare type in dialogue info select"); } - template - bool checkLocal (char comp, const std::string& name, T value, const MWWorld::Ptr& actor, - const MWWorld::ESMStore& store) - { - std::string scriptName = MWWorld::Class::get (actor).getScript (actor); - - if (scriptName.empty()) - return false; // no script - - const ESM::Script *script = - store.get().find (scriptName); - - int i = 0; - - for (; i (script->mVarNames.size()); ++i) - if (script->mVarNames[i]==name) - break; - - if (i>=static_cast (script->mVarNames.size())) - return false; // script does not have a variable of this name - - const MWScript::Locals& locals = actor.getRefData().getLocals(); - - if (imData.mNumShorts) - return selectCompare (comp, locals.mShorts[i], value); - else - i -= script->mData.mNumShorts; - - if (imData.mNumLongs) - return selectCompare (comp, locals.mLongs[i], value); - else - i -= script->mData.mNumShorts; - - return selectCompare (comp, locals.mFloats.at (i), value); - } - - template - bool checkGlobal (char comp, const std::string& name, T value) - { - switch (MWBase::Environment::get().getWorld()->getGlobalVariableType (name)) - { - case 's': - return selectCompare (comp, MWBase::Environment::get().getWorld()->getGlobalVariable (name).mShort, value); - - case 'l': - - return selectCompare (comp, MWBase::Environment::get().getWorld()->getGlobalVariable (name).mLong, value); - - case 'f': - - return selectCompare (comp, MWBase::Environment::get().getWorld()->getGlobalVariable (name).mFloat, value); - - case ' ': - - MWBase::Environment::get().getWorld()->getGlobalVariable (name); // trigger exception - break; - - default: - - throw std::runtime_error ("unsupported gobal variable type"); - } - - return false; - } - //helper function std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos) { @@ -289,81 +224,6 @@ namespace MWDialogue bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const { - char type = select.mSelectRule[1]; - - if (type!='0') - { - char comp = select.mSelectRule[4]; - std::string name = select.mSelectRule.substr (5); - std::string function = select.mSelectRule.substr(1,2); - - switch (type) - { - case '1': // function - - return true; // Done elsewhere. - - case '2': // global - - if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int || - select.mType==ESM::VT_Long) - { - if (!checkGlobal (comp, toLower (name), select.mI)) - return false; - } - else if (select.mType==ESM::VT_Float) - { - if (!checkGlobal (comp, toLower (name), select.mF)) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case '3': // local - - if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int || - select.mType==ESM::VT_Long) - { - if (!checkLocal (comp, toLower (name), select.mI, actor, - MWBase::Environment::get().getWorld()->getStore())) - return false; - } - else if (select.mType==ESM::VT_Float) - { - if (!checkLocal (comp, toLower (name), select.mF, actor, - MWBase::Environment::get().getWorld()->getStore())) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - - return true; - - case 'C'://not local - if (select.mType==ESM::VT_Short || select.mType==ESM::VT_Int || - select.mType==ESM::VT_Long) - { - if (checkLocal (comp, toLower (name), select.mI, actor, - MWBase::Environment::get().getWorld()->getStore())) - return false; - } - else if (select.mType==ESM::VT_Float) - { - if (checkLocal (comp, toLower (name), select.mF, actor, - MWBase::Environment::get().getWorld()->getStore())) - return false; - } - else - throw std::runtime_error ( - "unsupported variable type in dialogue info select"); - return true; - } - } - return true; } diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 9d14dbafc..4ad7bc157 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -144,6 +144,48 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c { switch (select.getFunction()) { + case SelectWrapper::Function_Global: + + // internally all globals are float :( + return select.selectCompare ( + MWBase::Environment::get().getWorld()->getGlobalVariable (select.getName()).mFloat); + + case SelectWrapper::Function_Local: + { + std::string scriptName = MWWorld::Class::get (mActor).getScript (mActor); + + if (scriptName.empty()) + return false; // no script + + const ESM::Script *script = + MWBase::Environment::get().getWorld()->getStore().get().find (scriptName); + + std::string name = select.getName(); + + int i = 0; + + for (; i (script->mVarNames.size()); ++i) + if (script->mVarNames[i]==name) + break; + + if (i>=static_cast (script->mVarNames.size())) + return false; // script does not have a variable of this name + + const MWScript::Locals& locals = mActor.getRefData().getLocals(); + + if (imData.mNumShorts) + return select.selectCompare (static_cast (locals.mShorts[i])); + + i -= script->mData.mNumShorts; + + if (imData.mNumLongs) + return select.selectCompare (locals.mLongs[i]); + + i -= script->mData.mNumShorts; + + return select.selectCompare (locals.mFloats.at (i)); + } + default: throw std::runtime_error ("unknown numeric select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 90aa77f94..effb43110 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -60,6 +60,8 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con switch (type) { + case '2': return Function_Global; + case '3': return Function_Local; case '4': return Function_Journal; case '5': return Function_Item; case '6': return Function_Dead; @@ -68,6 +70,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con case '9': return Function_Class; case 'A': return Function_Race; case 'B': return Function_Cell; + case 'C': return Function_Local; } return Function_None; @@ -83,6 +86,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const static const Function numericFunctions[] = { + Function_Global, Function_Local, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 10a20ef74..1bd528be0 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -21,7 +21,9 @@ namespace MWDialogue Function_Faction, Function_Class, Function_Race, - Function_Cell + Function_Cell, + Function_Local, + Function_Global }; enum Type From a752536ceac31dbb72352f058ee2119867f5fc2b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 09:35:50 +0100 Subject: [PATCH 11/25] Issue #219: added function decoding and moved same faction function from DialogueManager to Filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 19 ------------------- apps/openmw/mwdialogue/filter.cpp | 8 ++++++++ apps/openmw/mwdialogue/selectwrapper.cpp | 13 +++++++++++++ apps/openmw/mwdialogue/selectwrapper.hpp | 9 +++++++-- apps/openmw/mwmechanics/npcstats.cpp | 10 ++++++++++ apps/openmw/mwmechanics/npcstats.hpp | 3 +++ 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 15852198f..74ee44aa9 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -97,8 +97,6 @@ namespace MWDialogue bool DialogueManager::functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice) { - bool isCreature = (actor.getTypeName() != typeid(ESM::NPC).name()); - for (std::vector::const_iterator iter (info.mSelects.begin()); iter != info.mSelects.end(); ++iter) { @@ -131,23 +129,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 46://Same faction - { - if (isCreature) - return false; - - MWMechanics::NpcStats PCstats = MWWorld::Class::get(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()).getNpcStats(MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); - MWMechanics::NpcStats NPCstats = MWWorld::Class::get(actor).getNpcStats(actor); - int sameFaction = 0; - if(!NPCstats.getFactionRanks().empty()) - { - std::string NPCFaction = NPCstats.getFactionRanks().begin()->first; - if(PCstats.getFactionRanks().find(toLower(NPCFaction)) != PCstats.getFactionRanks().end()) sameFaction = 1; - } - if(!selectCompare(comp,sameFaction,select.mI)) return false; - } - break; - case 48://Detected if(!selectCompare(comp,1,select.mI)) return false; break; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 4ad7bc157..1e03864ba 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -250,6 +250,14 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return toLower (mActor.getCell()->mCell->mName)==select.getName(); + case SelectWrapper::Function_SameFaction: + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction ( + MWWorld::Class::get (player).getNpcStats (player)); + } + default: throw std::runtime_error ("unknown boolean select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index effb43110..1ffdd208c 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -5,6 +5,7 @@ #include #include +#include namespace { @@ -52,6 +53,15 @@ namespace } } +MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() const +{ + int index = 0; + + std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; + + return static_cast (index); +} + MWDialogue::SelectWrapper::SelectWrapper (const ESM::DialInfo::SelectStruct& select) : mSelect (select) {} MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() const @@ -60,6 +70,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con switch (type) { + case '1': return decodeFunction(); case '2': return Function_Global; case '3': return Function_Local; case '4': return Function_Journal; @@ -93,6 +104,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const static const Function booleanFunctions[] = { Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell, + Function_SameFaction, Function_None // end marker }; @@ -125,6 +137,7 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const static const Function functions[] = { Function_Faction, SelectWrapper::Function_Class, SelectWrapper::Function_Race, + Function_SameFaction, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 1bd528be0..052f73837 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -13,7 +13,7 @@ namespace MWDialogue enum Function { - Function_None, + Function_None = 0, Function_Journal, Function_Item, Function_Dead, @@ -23,7 +23,8 @@ namespace MWDialogue Function_Race, Function_Cell, Function_Local, - Function_Global + Function_Global, + Function_SameFaction }; enum Type @@ -33,6 +34,10 @@ namespace MWDialogue Type_Numeric, Type_Boolean }; + + private: + + Function decodeFunction() const; public: diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 5b2ce739f..cc054c1dc 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -86,6 +86,16 @@ const std::map& MWMechanics::NpcStats::getFactionRanks() const return mFactionRank; } +bool MWMechanics::NpcStats::isSameFaction (const NpcStats& npcStats) const +{ + for (std::map::const_iterator iter (mFactionRank.begin()); iter!=mFactionRank.end(); + ++iter) + if (npcStats.mFactionRank.find (iter->first)!=npcStats.mFactionRank.end()) + return true; + + return false; +} + float MWMechanics::NpcStats::getSkillGain (int skillIndex, const ESM::Class& class_, int usageType, int level) const { diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 35af4afa0..a6f7adaf1 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -76,6 +76,9 @@ namespace MWMechanics std::map& getFactionRanks(); + bool isSameFaction (const NpcStats& npcStats) const; + ///< Do *this and \a npcStats share a faction? + const std::map& getFactionRanks() const; float getSkillGain (int skillIndex, const ESM::Class& class_, int usageType = -1, From c425b3f4a35494017b74b981c0755ec41b5120fa Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 09:48:20 +0100 Subject: [PATCH 12/25] Issue #219: fixed function decoding and moved choice function from DialogueManager to Filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 15 ++++----------- apps/openmw/mwdialogue/filter.cpp | 6 +++++- apps/openmw/mwdialogue/filter.hpp | 3 ++- apps/openmw/mwdialogue/selectwrapper.cpp | 9 ++++++++- apps/openmw/mwdialogue/selectwrapper.hpp | 5 +++-- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 74ee44aa9..d5af28964 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -137,13 +137,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 50://choice - if(choice) - { - if(!selectCompare(comp,mChoice,select.mI)) return false; - } - break; - case 60://PC Vampire if(!selectCompare(comp,0,select.mI)) return false; break; @@ -287,7 +280,7 @@ namespace MWDialogue const MWWorld::Store &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); - Filter filter (actor); + Filter filter (actor, mChoice); MWWorld::Store::iterator it = dialogs.begin(); for (; it != dialogs.end(); ++it) @@ -391,7 +384,7 @@ namespace MWDialogue const MWWorld::Store &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); - Filter filter (mActor); + Filter filter (mActor, mChoice); MWWorld::Store::iterator it = dialogs.begin(); for (; it != dialogs.end(); ++it) @@ -478,7 +471,7 @@ namespace MWDialogue ESM::Dialogue ndialogue = mDialogueMap[keyword]; if(ndialogue.mType == ESM::Dialogue::Topic) { - Filter filter (mActor); + Filter filter (mActor, mChoice); for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) @@ -525,7 +518,7 @@ namespace MWDialogue ESM::Dialogue ndialogue = mDialogueMap[mLastTopic]; if(ndialogue.mType == ESM::Dialogue::Topic) { - Filter filter (mActor); + Filter filter (mActor, mChoice); for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 1e03864ba..59027617f 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -220,6 +220,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return MWBase::Environment::get().getMechanicsManager()->countDeaths (select.getName()); + case SelectWrapper::Function_Choice: + + return mChoice; + default: throw std::runtime_error ("unknown integer select function"); @@ -264,7 +268,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co } } -MWDialogue::Filter::Filter (const MWWorld::Ptr& actor) : mActor (actor) {} +MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice) : mActor (actor), mChoice (choice) {} bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const { diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 4263920cb..a849dc016 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -15,6 +15,7 @@ namespace MWDialogue class Filter { MWWorld::Ptr mActor; + int mChoice; bool testActor (const ESM::DialInfo& info) const; ///< Is this the right actor for this \a info? @@ -35,7 +36,7 @@ namespace MWDialogue public: - Filter (const MWWorld::Ptr& actor); + Filter (const MWWorld::Ptr& actor, int choice); bool operator() (const ESM::DialInfo& info) const; ///< \return does the dialogue match? diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 1ffdd208c..bfd7f8cf8 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -59,7 +59,13 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; - return static_cast (index); + switch (index) + { + case 46: return Function_SameFaction; + case 50: return Function_Choice; + } + + return Function_None; } MWDialogue::SelectWrapper::SelectWrapper (const ESM::DialInfo::SelectStruct& select) : mSelect (select) {} @@ -92,6 +98,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const static const Function integerFunctions[] = { Function_Journal, Function_Item, Function_Dead, + Function_Choice, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 052f73837..4f105aa5a 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -13,7 +13,7 @@ namespace MWDialogue enum Function { - Function_None = 0, + Function_None, Function_Journal, Function_Item, Function_Dead, @@ -24,7 +24,8 @@ namespace MWDialogue Function_Cell, Function_Local, Function_Global, - Function_SameFaction + Function_SameFaction, + Function_Choice }; enum Type From eb4e72aaa7b626b3310f0741b32a435affeea488 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 11:08:36 +0100 Subject: [PATCH 13/25] Issue #219: implemented disease filters --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 8 ------- apps/openmw/mwdialogue/filter.cpp | 22 +++++++++++++++---- apps/openmw/mwdialogue/selectwrapper.cpp | 4 ++++ apps/openmw/mwdialogue/selectwrapper.hpp | 3 ++- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index d5af28964..dcba11c17 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -117,14 +117,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 40://PC Common Disease - if(!selectCompare(comp,0,select.mI)) return false; - break; - - case 41://PC Blight Disease - if(!selectCompare(comp,0,select.mI)) return false; - break; - case 43://PC Crime level if(!selectCompare(comp,0,select.mI)) return false; break; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 59027617f..5a1ec2d84 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -11,6 +11,8 @@ #include "../mwworld/containerstore.hpp" #include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/creaturestats.hpp" +#include "../mwmechanics/magiceffects.hpp" #include "selectwrapper.hpp" @@ -232,6 +234,8 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + switch (select.getFunction()) { case SelectWrapper::Function_Id: @@ -255,12 +259,22 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return toLower (mActor.getCell()->mCell->mName)==select.getName(); case SelectWrapper::Function_SameFaction: - { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction ( MWWorld::Class::get (player).getNpcStats (player)); - } + + case SelectWrapper::Function_PcCommonDisease: + + return MWWorld::Class::get (player).getCreatureStats (player).hasCommonDisease(); + + case SelectWrapper::Function_PcBlightDisease: + + return MWWorld::Class::get (player).getCreatureStats (player).hasBlightDisease(); + + case SelectWrapper::Function_PcCorprus: + + return MWWorld::Class::get (player).getCreatureStats (player). + getMagicEffects().get (132).mMagnitude!=0; default: diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index bfd7f8cf8..d49d73a8d 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -61,8 +61,11 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() switch (index) { + case 40: return Function_PcCommonDisease; + case 41: return Function_PcBlightDisease; case 46: return Function_SameFaction; case 50: return Function_Choice; + case 58: return Function_PcCorprus; } return Function_None; @@ -112,6 +115,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const { Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell, Function_SameFaction, + Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 4f105aa5a..d0e2dbb6a 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -25,7 +25,8 @@ namespace MWDialogue Function_Local, Function_Global, Function_SameFaction, - Function_Choice + Function_Choice, + Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus }; enum Type From ceaf1677ce3738af74d42d99f7c38d9f487a3f9e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 11:38:37 +0100 Subject: [PATCH 14/25] Issue #219: rewrote AI settings and implemented AI settings filters --- apps/openmw/mwclass/creature.cpp | 8 +-- apps/openmw/mwclass/npc.cpp | 8 +-- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 18 +------ apps/openmw/mwdialogue/filter.cpp | 9 +++- apps/openmw/mwdialogue/selectwrapper.cpp | 23 +++++++++ apps/openmw/mwdialogue/selectwrapper.hpp | 5 +- apps/openmw/mwmechanics/creaturestats.cpp | 50 +++++-------------- apps/openmw/mwmechanics/creaturestats.hpp | 25 +++------- apps/openmw/mwscript/aiextensions.cpp | 8 +-- 9 files changed, 65 insertions(+), 89 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 910838e12..edf5dd25d 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -62,10 +62,10 @@ namespace MWClass data->mCreatureStats.setLevel(ref->mBase->mData.mLevel); - data->mCreatureStats.setHello(ref->mBase->mAiData.mHello); - data->mCreatureStats.setFight(ref->mBase->mAiData.mFight); - data->mCreatureStats.setFlee(ref->mBase->mAiData.mFlee); - data->mCreatureStats.setAlarm(ref->mBase->mAiData.mAlarm); + data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello); + data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight); + data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee); + data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm); // spells for (std::vector::const_iterator iter (ref->mBase->mSpells.mList.begin()); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 6a516bcc8..f95fbd116 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -109,10 +109,10 @@ namespace MWClass data->mCreatureStats.setLevel (1); } - data->mCreatureStats.setHello(ref->mBase->mAiData.mHello); - data->mCreatureStats.setFight(ref->mBase->mAiData.mFight); - data->mCreatureStats.setFlee(ref->mBase->mAiData.mFlee); - data->mCreatureStats.setAlarm(ref->mBase->mAiData.mAlarm); + data->mCreatureStats.setAiSetting (0, ref->mBase->mAiData.mHello); + data->mCreatureStats.setAiSetting (1, ref->mBase->mAiData.mFight); + data->mCreatureStats.setAiSetting (2, ref->mBase->mAiData.mFlee); + data->mCreatureStats.setAiSetting (3, ref->mBase->mAiData.mAlarm); // spells for (std::vector::const_iterator iter (ref->mBase->mSpells.mList.begin()); diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index dcba11c17..4cc3daf3f 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -157,22 +157,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 67://Fight - if(!selectCompare(comp,0,select.mI)) return false; - break; - - case 68://Hello???? - if(!selectCompare(comp,0,select.mI)) return false; - break; - - case 69://Alarm - if(!selectCompare(comp,0,select.mI)) return false; - break; - - case 70://Flee - if(!selectCompare(comp,0,select.mI)) return false; - break; - case 71://Should Attack if(!selectCompare(comp,0,select.mI)) return false; break; @@ -184,7 +168,7 @@ namespace MWDialogue } } - return true; + return false; } bool DialogueManager::isMatching (const MWWorld::Ptr& actor, diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 5a1ec2d84..6ef13a9fa 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -196,6 +196,8 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) const { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + switch (select.getFunction()) { case SelectWrapper::Function_Journal: @@ -204,7 +206,6 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_Item: { - MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); MWWorld::ContainerStore& store = MWWorld::Class::get (player).getContainerStore (player); int sum = 0; @@ -226,6 +227,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return mChoice; + case SelectWrapper::Function_AiSetting: + + return MWWorld::Class::get (player).getCreatureStats (player).getAiSetting (select.getArgument()); + default: throw std::runtime_error ("unknown integer select function"); @@ -235,7 +240,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) const { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); - + switch (select.getFunction()) { case SelectWrapper::Function_Id: diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index d49d73a8d..42626fd49 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -66,6 +66,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 46: return Function_SameFaction; case 50: return Function_Choice; case 58: return Function_PcCorprus; + case 67: case 68: case 69: case 70: return Function_AiSetting; } return Function_None; @@ -96,12 +97,34 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con return Function_None; } +int MWDialogue::SelectWrapper::getArgument() const +{ + if (mSelect.mSelectRule[1]!='1') + return 0; + + int index = 0; + + std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; + + switch (index) + { + // AI settings + case 67: return 1; + case 68: return 0; + case 69: return 3; + case 70: return 2; + } + + return 0; +} + MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const { static const Function integerFunctions[] = { Function_Journal, Function_Item, Function_Dead, Function_Choice, + Function_AiSetting, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index d0e2dbb6a..ee5d29cca 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -26,7 +26,8 @@ namespace MWDialogue Function_Global, Function_SameFaction, Function_Choice, - Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus + Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, + Function_AiSetting }; enum Type @@ -47,6 +48,8 @@ namespace MWDialogue Function getFunction() const; + int getArgument() const; + Type getType() const; bool isInverted() const; diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index e94adf458..10b9b2f7e 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -10,8 +10,10 @@ namespace MWMechanics { CreatureStats::CreatureStats() - : mLevel (0), mHello (0), mFight (0), mFlee (0), mAlarm (0), mLevelHealthBonus(0.f), mDead (false) + : mLevel (0), mLevelHealthBonus(0.f), mDead (false) { + for (int i=0; i<4; ++i) + mAiSettings[i] = 0; } void CreatureStats::increaseLevelHealthBonus (float value) @@ -90,27 +92,13 @@ namespace MWMechanics { return mLevel; } + + int CreatureStats::getAiSetting (int index) const + { + assert (index>=0 && index<4); + return mAiSettings[index]; + } - int CreatureStats::getHello() const - { - return mHello; - } - - int CreatureStats::getFight() const - { - return mFight; - } - - int CreatureStats::getFlee() const - { - return mFlee; - } - - int CreatureStats::getAlarm() const - { - return mAlarm; - } - Stat &CreatureStats::getAttribute(int index) { if (index < 0 || index > 7) { @@ -196,25 +184,11 @@ namespace MWMechanics mMagicEffects = effects; } - void CreatureStats::setHello(int value) + void CreatureStats::setAiSetting (int index, int value) { - mHello = value; + assert (index>=0 && index<4); + mAiSettings[index] = value; } - - void CreatureStats::setFight(int value) - { - mFight = value; - } - - void CreatureStats::setFlee(int value) - { - mFlee = value; - } - - void CreatureStats::setAlarm(int value) - { - mAlarm = value; - } bool CreatureStats::isDead() const { diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index cdeee6853..bbb8b8b30 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -24,10 +24,7 @@ namespace MWMechanics Spells mSpells; ActiveSpells mActiveSpells; MagicEffects mMagicEffects; - int mHello; - int mFight; - int mFlee; - int mAlarm; + int mAiSettings[4]; AiSequence mAiSequence; float mLevelHealthBonus; bool mDead; @@ -53,13 +50,8 @@ namespace MWMechanics int getLevel() const; - int getHello() const; - - int getFight() const; - - int getFlee() const; - - int getAlarm() const; + int getAiSetting (int index) const; + ///< 0: hello, 1 fight, 2 flee, 3 alarm Stat & getAttribute(int index); @@ -87,14 +79,9 @@ namespace MWMechanics void setLevel(int level); - void setHello(int value); - - void setFight(int value); - - void setFlee(int value); - - void setAlarm(int value); - + void setAiSetting (int index, int value); + ///< 0: hello, 1 fight, 2 flee, 3 alarm + const AiSequence& getAiSequence() const; AiSequence& getAiSequence(); diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 9d70c28bd..787962ad1 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -130,7 +130,7 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Class::get (ptr).getCreatureStats (ptr).setHello(value); + MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (0, value); } }; @@ -146,7 +146,7 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Class::get (ptr).getCreatureStats (ptr).setFight(value); + MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (1, value); } }; @@ -162,7 +162,7 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Class::get (ptr).getCreatureStats (ptr).setFlee(value); + MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (2, value); } }; @@ -178,7 +178,7 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); - MWWorld::Class::get (ptr).getCreatureStats (ptr).setAlarm(value); + MWWorld::Class::get (ptr).getCreatureStats (ptr).setAiSetting (3, value); } }; From d6961c024628c5d9c706e0842306a27846dc754f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 11:42:03 +0100 Subject: [PATCH 15/25] Issue #219: made all unimplemented filters return false --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 2 +- apps/openmw/mwdialogue/filter.cpp | 4 ++++ apps/openmw/mwdialogue/selectwrapper.cpp | 3 ++- apps/openmw/mwdialogue/selectwrapper.hpp | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 4cc3daf3f..a9e564078 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -168,7 +168,7 @@ namespace MWDialogue } } - return false; + return true; } bool DialogueManager::isMatching (const MWWorld::Ptr& actor, diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 6ef13a9fa..10bcfd8aa 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -243,6 +243,10 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co switch (select.getFunction()) { + case SelectWrapper::Function_False: + + return false; + case SelectWrapper::Function_Id: return select.getName()==toLower (MWWorld::Class::get (mActor).getId (mActor)); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 42626fd49..d70e88e8b 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -69,7 +69,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 67: case 68: case 69: case 70: return Function_AiSetting; } - return Function_None; + return Function_False; } MWDialogue::SelectWrapper::SelectWrapper (const ESM::DialInfo::SelectStruct& select) : mSelect (select) {} @@ -136,6 +136,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const static const Function booleanFunctions[] = { + Function_False, Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell, Function_SameFaction, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index ee5d29cca..3ff55eb61 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -13,7 +13,7 @@ namespace MWDialogue enum Function { - Function_None, + Function_None, Function_False, Function_Journal, Function_Item, Function_Dead, From bd2c772daefa29d879a3d665ed878b4ad0edd9fe Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 12:08:04 +0100 Subject: [PATCH 16/25] Issue #219: implemented player skill and attribute filter --- apps/openmw/mwdialogue/filter.cpp | 10 +++++ apps/openmw/mwdialogue/selectwrapper.cpp | 53 +++++++++++++++++++++++- apps/openmw/mwdialogue/selectwrapper.hpp | 3 +- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 10bcfd8aa..4000d3150 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -231,6 +231,16 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return MWWorld::Class::get (player).getCreatureStats (player).getAiSetting (select.getArgument()); + case SelectWrapper::Function_PcAttribute: + + return MWWorld::Class::get (player).getCreatureStats (player). + getAttribute (select.getArgument()).getModified(); + + case SelectWrapper::Function_PcSkill: + + return static_cast (MWWorld::Class::get (player). + getNpcStats (player).getSkill (select.getArgument()).getModified()); + default: throw std::runtime_error ("unknown integer select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index d70e88e8b..6b604c1aa 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -58,15 +58,26 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() int index = 0; std::istringstream (mSelect.mSelectRule.substr(2,2)) >> index; - + switch (index) { + // 0-9 + case 10: return Function_PcAttribute; + case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: + case 31: case 32: case 33: case 34: case 35: case 36: case 37: return Function_PcSkill; + // 38, 39 case 40: return Function_PcCommonDisease; case 41: return Function_PcBlightDisease; + // 42-45 case 46: return Function_SameFaction; + // 47-49 case 50: return Function_Choice; + case 51: case 52: case 53: case 54: case 55: case 56: case 57: return Function_PcAttribute; case 58: return Function_PcCorprus; + // 59-66 case 67: case 68: case 69: case 70: return Function_AiSetting; + // 71-77 } return Function_False; @@ -113,6 +124,45 @@ int MWDialogue::SelectWrapper::getArgument() const case 68: return 0; case 69: return 3; case 70: return 2; + + // attributes + case 10: return 0; + case 51: return 1; + case 52: return 2; + case 53: return 3; + case 54: return 4; + case 55: return 5; + case 56: return 6; + case 57: return 7; + + // skills + case 11: return 0; + case 12: return 1; + case 13: return 2; + case 14: return 3; + case 15: return 4; + case 16: return 5; + case 17: return 6; + case 18: return 7; + case 19: return 8; + case 20: return 9; + case 21: return 10; + case 22: return 11; + case 23: return 12; + case 24: return 13; + case 25: return 14; + case 26: return 15; + case 27: return 16; + case 28: return 17; + case 29: return 18; + case 30: return 19; + case 31: return 20; + case 32: return 21; + case 33: return 22; + case 34: return 23; + case 35: return 24; + case 36: return 25; + case 37: return 26; } return 0; @@ -125,6 +175,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_Journal, Function_Item, Function_Dead, Function_Choice, Function_AiSetting, + Function_PcAttribute, Function_PcSkill, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 3ff55eb61..515574927 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -27,7 +27,8 @@ namespace MWDialogue Function_SameFaction, Function_Choice, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, - Function_AiSetting + Function_AiSetting, + Function_PcAttribute, Function_PcSkill }; enum Type From e97f3003ab9fcd3d599dc1dac4eaabc766a2d17d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 12:28:40 +0100 Subject: [PATCH 17/25] Issue #219: added expelled status tracking; implemented expelled filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 4 ---- apps/openmw/mwdialogue/filter.cpp | 13 +++++++++++++ apps/openmw/mwdialogue/selectwrapper.cpp | 4 +++- apps/openmw/mwdialogue/selectwrapper.hpp | 3 ++- apps/openmw/mwmechanics/npcstats.cpp | 5 +++++ apps/openmw/mwmechanics/npcstats.hpp | 3 +++ 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index a9e564078..b5ce4c536 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -113,10 +113,6 @@ namespace MWDialogue iss >> ifunction; switch(ifunction) { - case 39://PC Expelled - if(!selectCompare(comp,0,select.mI)) return false; - break; - case 43://PC Crime level if(!selectCompare(comp,0,select.mI)) return false; break; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 4000d3150..a901fc8e0 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -295,6 +295,19 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return MWWorld::Class::get (player).getCreatureStats (player). getMagicEffects().get (132).mMagnitude!=0; + case SelectWrapper::Function_PcExpelled: + { + if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) + return false; + + std::string faction = + MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; + + std::set& expelled = MWWorld::Class::get (player).getNpcStats (player).getExpelled(); + + return expelled.find (faction)!=expelled.end(); + } + default: throw std::runtime_error ("unknown boolean select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 6b604c1aa..96bf932a1 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -66,7 +66,8 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: return Function_PcSkill; - // 38, 39 + // 38 + case 39: return Function_PcExpelled; case 40: return Function_PcCommonDisease; case 41: return Function_PcBlightDisease; // 42-45 @@ -191,6 +192,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell, Function_SameFaction, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, + Function_PcExpelled, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 515574927..2c8c9f24e 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -28,7 +28,8 @@ namespace MWDialogue Function_Choice, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_AiSetting, - Function_PcAttribute, Function_PcSkill + Function_PcAttribute, Function_PcSkill, + Function_PcExpelled }; enum Type diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index cc054c1dc..0116b6a96 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -81,6 +81,11 @@ std::map& MWMechanics::NpcStats::getFactionRanks() return mFactionRank; } +std::set& MWMechanics::NpcStats::getExpelled() +{ + return mExpelled; +} + const std::map& MWMechanics::NpcStats::getFactionRanks() const { return mFactionRank; diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index a6f7adaf1..ca0ed07df 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -47,6 +47,7 @@ namespace MWMechanics unsigned int mMovementFlags; Stat mSkill[27]; int mBounty; + std::set mExpelled; int mLevelProgress; // 0-10 @@ -75,6 +76,8 @@ namespace MWMechanics Stat& getSkill (int index); std::map& getFactionRanks(); + + std::set& getExpelled(); bool isSameFaction (const NpcStats& npcStats) const; ///< Do *this and \a npcStats share a faction? From 7e8d4bb3c928fd2c1047e9111b894ebe83ef7d1f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 13:20:41 +0100 Subject: [PATCH 18/25] Issue #219: added various creature and NPC stats; implemented respective filters --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 12 -------- apps/openmw/mwdialogue/filter.cpp | 15 ++++++++++ apps/openmw/mwdialogue/selectwrapper.cpp | 9 +++++- apps/openmw/mwdialogue/selectwrapper.hpp | 5 +++- apps/openmw/mwmechanics/creaturestats.cpp | 22 ++++++++++++++- apps/openmw/mwmechanics/creaturestats.hpp | 17 +++++++++-- apps/openmw/mwmechanics/npcstats.cpp | 28 ++++++++++++++++++- apps/openmw/mwmechanics/npcstats.hpp | 10 +++++++ 8 files changed, 100 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index b5ce4c536..ff5ad40c2 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -125,10 +125,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 60://PC Vampire - if(!selectCompare(comp,0,select.mI)) return false; - break; - case 61://Level if(!selectCompare(comp,1,select.mI)) return false; break; @@ -137,10 +133,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 63://Talked to PC - if(!selectCompare(comp,0,select.mI)) return false; - break; - case 64://PC Health if(!selectCompare(comp,50,select.mI)) return false; break; @@ -149,10 +141,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 66://Friend hit - if(!selectCompare(comp,0,select.mI)) return false; - break; - case 71://Should Attack if(!selectCompare(comp,0,select.mI)) return false; break; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index a901fc8e0..3dac9a07a 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -241,6 +241,13 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return static_cast (MWWorld::Class::get (player). getNpcStats (player).getSkill (select.getArgument()).getModified()); + case SelectWrapper::Function_FriendlyHit: + { + int hits = MWWorld::Class::get (mActor).getCreatureStats (mActor).getFriendlyHits(); + + return hits>4 ? 4 : hits; + } + default: throw std::runtime_error ("unknown integer select function"); @@ -307,6 +314,14 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return expelled.find (faction)!=expelled.end(); } + + case SelectWrapper::Function_PcVampire: + + return MWWorld::Class::get (player).getNpcStats (player).isVampire(); + + case SelectWrapper::Function_TalkedToPc: + + return MWWorld::Class::get (mActor).getCreatureStats (mActor).hasTalkedToPlayer(); default: diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 96bf932a1..5211edba5 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -76,7 +76,12 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 50: return Function_Choice; case 51: case 52: case 53: case 54: case 55: case 56: case 57: return Function_PcAttribute; case 58: return Function_PcCorprus; - // 59-66 + // 59 + case 60: return Function_PcVampire; + // 61, 62 + case 63: return Function_TalkedToPc; + // 64, 65 + case 66: return Function_FriendlyHit; case 67: case 68: case 69: case 70: return Function_AiSetting; // 71-77 } @@ -177,6 +182,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_Choice, Function_AiSetting, Function_PcAttribute, Function_PcSkill, + Function_FriendlyHit, Function_None // end marker }; @@ -193,6 +199,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_SameFaction, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_PcExpelled, + Function_PcVampire, Function_TalkedToPc, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 2c8c9f24e..14f292632 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -29,7 +29,10 @@ namespace MWDialogue Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_AiSetting, Function_PcAttribute, Function_PcSkill, - Function_PcExpelled + Function_PcExpelled, + Function_PcVampire, + Function_FriendlyHit, + Function_TalkedToPc }; enum Type diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 10b9b2f7e..9ee7ca7c2 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -10,7 +10,7 @@ namespace MWMechanics { CreatureStats::CreatureStats() - : mLevel (0), mLevelHealthBonus(0.f), mDead (false) + : mLevel (0), mLevelHealthBonus(0.f), mDead (false), mFriendlyHits (0), mTalkedTo (false) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -216,4 +216,24 @@ namespace MWMechanics { return mSpells.hasBlightDisease(); } + + int CreatureStats::getFriendlyHits() const + { + return mFriendlyHits; + } + + void CreatureStats::friendlyHit() + { + ++mFriendlyHits; + } + + bool CreatureStats::hasTalkedToPlayer() const + { + return mTalkedTo; + } + + void CreatureStats::talkedToPlayer() + { + mTalkedTo = true; + } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index bbb8b8b30..937cb61cc 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -27,7 +27,9 @@ namespace MWMechanics int mAiSettings[4]; AiSequence mAiSequence; float mLevelHealthBonus; - bool mDead; + bool mDead; + int mFriendlyHits; + bool mTalkedTo; public: CreatureStats(); @@ -99,7 +101,18 @@ namespace MWMechanics bool hasCommonDisease() const; - bool hasBlightDisease() const; + bool hasBlightDisease() const; + + int getFriendlyHits() const; + ///< Number of friendly hits received. + + void friendlyHit(); + ///< Increase number of friendly hits by one. + + bool hasTalkedToPlayer() const; + ///< Has this creature talked with the player before? + + void talkedToPlayer(); }; } diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 0116b6a96..3402779d4 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -19,7 +19,7 @@ MWMechanics::NpcStats::NpcStats() : mMovementFlags (0), mDrawState (DrawState_Nothing), mBounty (0) -, mLevelProgress(0), mDisposition(0) +, mLevelProgress(0), mDisposition(0), mVampire (0) { mSkillIncreases.resize (ESM::Attribute::Length); @@ -274,3 +274,29 @@ void MWMechanics::NpcStats::setBounty (int bounty) { mBounty = bounty; } + +int MWMechanics::NpcStats::getFactionReputation (const std::string& faction) const +{ + std::map::const_iterator iter = mFactionReputation.find (faction); + + if (iter==mFactionReputation.end()) + return 0; + + return iter->second; +} + +void MWMechanics::NpcStats::setFactionReputation (const std::string& faction, int value) +{ + mFactionReputation[faction] = value; +} + +bool MWMechanics::NpcStats::isVampire() const +{ + return mVampire; +} + +void MWMechanics::NpcStats::setVampire (bool set) +{ + mVampire = set; +} + diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index ca0ed07df..1ffc06cdf 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -48,6 +48,8 @@ namespace MWMechanics Stat mSkill[27]; int mBounty; std::set mExpelled; + std::map mFactionReputation; + bool mVampire; int mLevelProgress; // 0-10 @@ -108,6 +110,14 @@ namespace MWMechanics int getBounty() const; void setBounty (int bounty); + + int getFactionReputation (const std::string& faction) const; + + void setFactionReputation (const std::string& faction, int value); + + bool isVampire() const; + + void setVampire (bool set); }; } From f8fcca64b682c321e6144aac2990bd3471ac249b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 13:31:10 +0100 Subject: [PATCH 19/25] Issue #219: Proper implementation of talked to PC filter --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 13 +++++++++---- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 1 + apps/openmw/mwdialogue/filter.cpp | 6 ++++-- apps/openmw/mwdialogue/filter.hpp | 3 ++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index ff5ad40c2..005997a94 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -38,6 +38,7 @@ #include "../mwclass/npc.hpp" #include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/creaturestats.hpp" #include "filter.hpp" @@ -224,6 +225,10 @@ namespace MWDialogue mIsInChoice = false; mActor = actor; + + MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor); + mTalkedTo = creatureStats.hasTalkedToPlayer(); + creatureStats.talkedToPlayer(); mActorKnownTopics.clear(); @@ -240,7 +245,7 @@ namespace MWDialogue const MWWorld::Store &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); - Filter filter (actor, mChoice); + Filter filter (actor, mChoice, mTalkedTo); MWWorld::Store::iterator it = dialogs.begin(); for (; it != dialogs.end(); ++it) @@ -344,7 +349,7 @@ namespace MWDialogue const MWWorld::Store &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); - Filter filter (mActor, mChoice); + Filter filter (mActor, mChoice, mTalkedTo); MWWorld::Store::iterator it = dialogs.begin(); for (; it != dialogs.end(); ++it) @@ -431,7 +436,7 @@ namespace MWDialogue ESM::Dialogue ndialogue = mDialogueMap[keyword]; if(ndialogue.mType == ESM::Dialogue::Topic) { - Filter filter (mActor, mChoice); + Filter filter (mActor, mChoice, mTalkedTo); for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) @@ -478,7 +483,7 @@ namespace MWDialogue ESM::Dialogue ndialogue = mDialogueMap[mLastTopic]; if(ndialogue.mType == ESM::Dialogue::Topic) { - Filter filter (mActor, mChoice); + Filter filter (mActor, mChoice, mTalkedTo); for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index e3e9fd752..d6f8250fc 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -40,6 +40,7 @@ namespace MWDialogue bool compile (const std::string& cmd,std::vector& code); void executeScript(std::string script); MWWorld::Ptr mActor; + bool mTalkedTo; void printError(std::string error); diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 3dac9a07a..9be8f4150 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -321,7 +321,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_TalkedToPc: - return MWWorld::Class::get (mActor).getCreatureStats (mActor).hasTalkedToPlayer(); + return mTalkedToPlayer; default: @@ -329,7 +329,9 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co } } -MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice) : mActor (actor), mChoice (choice) {} +MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer) +: mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer) +{} bool MWDialogue::Filter::operator() (const ESM::DialInfo& info) const { diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index a849dc016..6e0b96a0f 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -16,6 +16,7 @@ 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? @@ -36,7 +37,7 @@ namespace MWDialogue public: - Filter (const MWWorld::Ptr& actor, int choice); + Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer); bool operator() (const ESM::DialInfo& info) const; ///< \return does the dialogue match? From d24e3eec9f4dcf17e5352eda162fbafe48def835 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 14:02:52 +0100 Subject: [PATCH 20/25] Issue #219: added filters for various player stats --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 8 --- apps/openmw/mwdialogue/filter.cpp | 55 ++++++++++++++++++- apps/openmw/mwdialogue/selectwrapper.cpp | 26 +++++++-- apps/openmw/mwdialogue/selectwrapper.hpp | 4 +- 4 files changed, 79 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 005997a94..e94ded242 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -114,10 +114,6 @@ namespace MWDialogue iss >> ifunction; switch(ifunction) { - case 43://PC Crime level - if(!selectCompare(comp,0,select.mI)) return false; - break; - case 48://Detected if(!selectCompare(comp,1,select.mI)) return false; break; @@ -134,10 +130,6 @@ namespace MWDialogue if(!selectCompare(comp,0,select.mI)) return false; break; - case 64://PC Health - if(!selectCompare(comp,50,select.mI)) return false; - break; - case 65://Creature target if(!selectCompare(comp,0,select.mI)) return false; break; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 9be8f4150..f5ea20b7b 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -9,6 +9,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" #include "../mwworld/containerstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/creaturestats.hpp" @@ -188,6 +189,26 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c return select.selectCompare (locals.mFloats.at (i)); } + case SelectWrapper::Function_PcHealthPercent: + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + float ratio = MWWorld::Class::get (player).getCreatureStats (player).getHealth().getCurrent() / + MWWorld::Class::get (player).getCreatureStats (player).getHealth().getModified(); + + return select.selectCompare (ratio); + } + + case SelectWrapper::Function_PcDynamicStat: + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + + float value = MWWorld::Class::get (player).getCreatureStats (player). + getDynamic (select.getArgument()).getCurrent(); + + return select.selectCompare (value); + } + default: throw std::runtime_error ("unknown numeric select function"); @@ -247,7 +268,39 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return hits>4 ? 4 : hits; } + + case SelectWrapper::Function_PcLevel: + + return MWWorld::Class::get (player).getCreatureStats (player).getLevel(); + + case SelectWrapper::Function_PcGender: + { + MWWorld::LiveCellRef *cellRef = player.get(); + return cellRef->mBase->Female ? 0 : 1; + } + + case SelectWrapper::Function_PcClothingModifier: + { + MWWorld::InventoryStore& store = MWWorld::Class::get (player).getInventoryStore (player); + + int value = 0; + + for (int i=0; i<=15; ++i) // everything except thigns held in hands and amunition + { + MWWorld::ContainerStoreIterator slot = store.getSlot (i); + + if (slot!=store.end()) + value += MWWorld::Class::get (*slot).getValue (*slot); + } + + return value; + } + + case SelectWrapper::Function_PcCrimeLevel: + + return MWWorld::Class::get (player).getNpcStats (player).getBounty(); + default: throw std::runtime_error ("unknown integer select function"); @@ -322,7 +375,7 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co case SelectWrapper::Function_TalkedToPc: return mTalkedToPlayer; - + default: throw std::runtime_error ("unknown boolean select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 5211edba5..c143e9697 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -61,16 +61,21 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() switch (index) { - // 0-9 + // 0-5 + case 6: return Function_PcLevel; + case 7: return Function_PcHealthPercent; + case 8: case 9: return Function_PcDynamicStat; case 10: return Function_PcAttribute; case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: return Function_PcSkill; - // 38 + case 38: return Function_PcGender; case 39: return Function_PcExpelled; case 40: return Function_PcCommonDisease; case 41: return Function_PcBlightDisease; - // 42-45 + // 42 + case 42: return Function_PcClothingModifier; + case 43: return Function_PcCrimeLevel; case 46: return Function_SameFaction; // 47-49 case 50: return Function_Choice; @@ -80,7 +85,8 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 60: return Function_PcVampire; // 61, 62 case 63: return Function_TalkedToPc; - // 64, 65 + case 64: return Function_PcDynamicStat; + // 65 case 66: return Function_FriendlyHit; case 67: case 68: case 69: case 70: return Function_AiSetting; // 71-77 @@ -169,6 +175,11 @@ int MWDialogue::SelectWrapper::getArgument() const case 35: return 24; case 36: return 25; case 37: return 26; + + // dynamic stats + case 8: return 1; + case 9: return 2; + case 64: return 0; } return 0; @@ -183,12 +194,15 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_AiSetting, Function_PcAttribute, Function_PcSkill, Function_FriendlyHit, + Function_PcLevel, Function_PcGender, Function_PcClothingModifier, + Function_PcCrimeLevel, Function_None // end marker }; static const Function numericFunctions[] = { Function_Global, Function_Local, + Function_PcDynamicStat, Function_PcHealthPercent, Function_None // end marker }; @@ -233,6 +247,10 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const { Function_Faction, SelectWrapper::Function_Class, SelectWrapper::Function_Race, Function_SameFaction, + Function_PcSkill, + Function_PcExpelled, + Function_PcVampire, + Function_PcCrimeLevel, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 14f292632..fd51101d8 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -32,7 +32,9 @@ namespace MWDialogue Function_PcExpelled, Function_PcVampire, Function_FriendlyHit, - Function_TalkedToPc + Function_TalkedToPc, + Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat, + Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel }; enum Type From 79706bf60fe87805511c7b40fa132380e3be74d8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 14:31:58 +0100 Subject: [PATCH 21/25] Issue #219: dialogue manager cleanup --- apps/openmw/engine.cpp | 1 + apps/openmw/mwbase/dialoguemanager.hpp | 4 +- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 150 +++--------------- apps/openmw/mwdialogue/dialoguemanagerimp.hpp | 44 +++-- apps/openmw/mwscript/statsextensions.cpp | 21 ++- 5 files changed, 61 insertions(+), 159 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a75a60223..d646d5aca 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -20,6 +20,7 @@ #include "mwscript/scriptmanagerimp.hpp" #include "mwscript/extensions.hpp" +#include "mwscript/interpretercontext.hpp" #include "mwsound/soundmanagerimp.hpp" diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp index ccffc6b21..9ea3c810a 100644 --- a/apps/openmw/mwbase/dialoguemanager.hpp +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -33,8 +33,8 @@ namespace MWBase virtual void goodbye() = 0; - ///get the faction of the actor you are talking with - virtual std::string getFaction() const = 0; + virtual MWWorld::Ptr getActor() const = 0; + ///< Return the actor the player is currently talking to. //calbacks for the GUI virtual void keywordSelected (const std::string& keyword) = 0; diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index e94ded242..fece9dc26 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -6,23 +6,7 @@ #include #include - -#include "../mwbase/environment.hpp" -#include "../mwbase/world.hpp" -#include "../mwbase/scriptmanager.hpp" -#include "../mwbase/journal.hpp" -#include "../mwbase/windowmanager.hpp" -#include "../mwbase/mechanicsmanager.hpp" - -#include "../mwworld/class.hpp" -#include "../mwworld/refdata.hpp" -#include "../mwworld/player.hpp" -#include "../mwworld/containerstore.hpp" -#include "../mwworld/esmstore.hpp" - -#include "../mwgui/dialogue.hpp" - -#include +#include #include #include @@ -30,14 +14,24 @@ #include #include #include + #include +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwbase/scriptmanager.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "../mwworld/class.hpp" +#include "../mwworld/containerstore.hpp" +#include "../mwworld/esmstore.hpp" + +#include "../mwgui/dialogue.hpp" + #include "../mwscript/compilercontext.hpp" #include "../mwscript/interpretercontext.hpp" #include "../mwscript/extensions.hpp" -#include "../mwclass/npc.hpp" -#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/creaturestats.hpp" #include "filter.hpp" @@ -69,22 +63,6 @@ namespace return false; } - template - bool selectCompare (char comp, T1 value1, T2 value2) - { - switch (comp) - { - case '0': return value1==value2; - case '1': return value1!=value2; - case '2': return value1>value2; - case '3': return value1>=value2; - case '4': return value1::const_iterator iter (info.mSelects.begin()); - iter != info.mSelects.end(); ++iter) - { - ESM::DialInfo::SelectStruct select = *iter; - char type = select.mSelectRule[1]; - if(type == '1') - { - char comp = select.mSelectRule[4]; - std::string name = select.mSelectRule.substr (5); - std::string function = select.mSelectRule.substr(2,2); - - int ifunction; - std::istringstream iss(function); - iss >> ifunction; - switch(ifunction) - { - case 48://Detected - if(!selectCompare(comp,1,select.mI)) return false; - break; - - case 49://Alarmed - if(!selectCompare(comp,0,select.mI)) return false; - break; - - case 61://Level - if(!selectCompare(comp,1,select.mI)) return false; - break; - - case 62://Attacked - if(!selectCompare(comp,0,select.mI)) return false; - break; - - case 65://Creature target - if(!selectCompare(comp,0,select.mI)) return false; - break; - - case 71://Should Attack - if(!selectCompare(comp,0,select.mI)) return false; - break; - - default: - break; - - } - } - } - - return true; - } - - bool DialogueManager::isMatching (const MWWorld::Ptr& actor, - const ESM::DialInfo::SelectStruct& select) const - { - return true; - } - - bool DialogueManager::isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const - { - // check DATAstruct - for (std::vector::const_iterator iter (info.mSelects.begin()); - iter != info.mSelects.end(); ++iter) - if (!isMatching (actor, *iter)) - return false; - - return true; - } - DialogueManager::DialogueManager (const Compiler::Extensions& extensions) : mCompilerContext (MWScript::CompilerContext::Type_Dialgoue), mErrorStream(std::cout.rdbuf()),mErrorHandler(mErrorStream) @@ -190,7 +97,7 @@ namespace MWDialogue mKnownTopics[toLower(topic)] = true; } - void DialogueManager::parseText (std::string text) + void DialogueManager::parseText (const std::string& text) { std::list::iterator it; for(it = mActorKnownTopics.begin();it != mActorKnownTopics.end();++it) @@ -248,7 +155,7 @@ namespace MWDialogue for (std::vector::const_iterator iter (it->mInfo.begin()); iter!=it->mInfo.end(); ++iter) { - if (filter (*iter) && isMatching (actor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter)) { if (!iter->mSound.empty()) { @@ -311,7 +218,7 @@ namespace MWDialogue return false; } - void DialogueManager::executeScript(std::string script) + void DialogueManager::executeScript (const std::string& script) { std::vector code; if(compile(script,code)) @@ -351,7 +258,7 @@ namespace MWDialogue for (std::vector::const_iterator iter (it->mInfo.begin()); iter!=it->mInfo.end(); ++iter) { - if (filter (*iter) && isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter)) { mActorKnownTopics.push_back(toLower(it->mId)); //does the player know the topic? @@ -433,7 +340,7 @@ namespace MWDialogue for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) { - if (filter (*iter) && isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter)) { std::string text = iter->mResponse; std::string script = iter->mResultScript; @@ -480,7 +387,7 @@ namespace MWDialogue for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); iter!=ndialogue.mInfo.end(); ++iter) { - if (filter (*iter) && isMatching (mActor, *iter) && functionFilter(mActor,*iter,true)) + if (filter (*iter)) { mChoiceMap.clear(); mChoice = -1; @@ -501,7 +408,7 @@ namespace MWDialogue } } - void DialogueManager::printError (std::string error) + void DialogueManager::printError (const std::string& error) { MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->addText(error); @@ -515,22 +422,9 @@ namespace MWDialogue mIsInChoice = true; } - std::string DialogueManager::getFaction() const + MWWorld::Ptr DialogueManager::getActor() const { - if (mActor.getTypeName() != typeid(ESM::NPC).name()) - return ""; - - std::string factionID(""); - MWMechanics::NpcStats stats = MWWorld::Class::get(mActor).getNpcStats(mActor); - if(stats.getFactionRanks().empty()) - { - std::cout << "No faction for this actor!"; - } - else - { - factionID = stats.getFactionRanks().begin()->first; - } - return factionID; + return mActor; } void DialogueManager::goodbye() diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp index d6f8250fc..bc497c399 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -3,53 +3,45 @@ #include "../mwbase/dialoguemanager.hpp" -#include +#include +#include #include -#include "../mwscript/compilercontext.hpp" -#include "../mwscript/interpretercontext.hpp" -#include #include "../mwworld/ptr.hpp" -#include +#include "../mwscript/compilercontext.hpp" namespace MWDialogue { class DialogueManager : public MWBase::DialogueManager { - bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const; - - bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo& info) const; - - bool functionFilter(const MWWorld::Ptr& actor, const ESM::DialInfo& info,bool choice); - - void parseText(std::string text); - - void updateTopics(); - - std::map mDialogueMap; - std::map mKnownTopics;// Those are the topics the player knows. + std::map mDialogueMap; + std::map mKnownTopics;// Those are the topics the player knows. std::list mActorKnownTopics; MWScript::CompilerContext mCompilerContext; std::ostream mErrorStream; Compiler::StreamErrorHandler mErrorHandler; - - - bool compile (const std::string& cmd,std::vector& code); - void executeScript(std::string script); + MWWorld::Ptr mActor; bool mTalkedTo; - void printError(std::string error); - int mChoice; - std::map mChoiceMap; + std::map mChoiceMap; std::string mLastTopic; ESM::DialInfo mLastDialogue; bool mIsInChoice; + void parseText (const std::string& text); + + void updateTopics(); + + bool compile (const std::string& cmd,std::vector& code); + void executeScript (const std::string& script); + + void printError (const std::string& error); + public: DialogueManager (const Compiler::Extensions& extensions); @@ -62,8 +54,8 @@ namespace MWDialogue virtual void goodbye(); - ///get the faction of the actor you are talking with - virtual std::string getFaction() const; + virtual MWWorld::Ptr getActor() const; + ///< Return the actor the player is currently talking to. //calbacks for the GUI virtual void keywordSelected (const std::string& keyword); diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 0c4c6d144..4fbb81b37 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -28,6 +28,21 @@ #include "interpretercontext.hpp" #include "ref.hpp" +namespace +{ + std::string getDialogueActorFaction() + { + MWWorld::Ptr actor = MWBase::Environment::get().getDialogueManager()->getActor(); + + MWMechanics::NpcStats stats = MWWorld::Class::get (actor).getNpcStats (actor); + + if (stats.getFactionRanks().empty()) + throw std::runtime_error ( + "failed to determine dialogue actors faction (because actor is factionless)"); + + return stats.getFactionRanks().begin()->first; + } +} namespace MWScript { @@ -450,7 +465,7 @@ namespace MWScript if(arg0==0) { - factionID = MWBase::Environment::get().getDialogueManager()->getFaction(); + factionID = getDialogueActorFaction(); } else { @@ -479,7 +494,7 @@ namespace MWScript if(arg0==0) { - factionID = MWBase::Environment::get().getDialogueManager()->getFaction(); + factionID = getDialogueActorFaction(); } else { @@ -512,7 +527,7 @@ namespace MWScript if(arg0==0) { - factionID = MWBase::Environment::get().getDialogueManager()->getFaction(); + factionID = getDialogueActorFaction(); } else { From 6dc2214502bef63c8314764aa313e919c09306b3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Nov 2012 14:52:44 +0100 Subject: [PATCH 22/25] Issue #219: more DialogueManager refactoring --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 117 +++++++----------- apps/openmw/mwdialogue/filter.cpp | 11 ++ apps/openmw/mwdialogue/filter.hpp | 3 + 3 files changed, 60 insertions(+), 71 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index fece9dc26..ee376fcf0 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -140,37 +140,28 @@ namespace MWDialogue updateTopics(); //greeting - bool greetingFound = false; const MWWorld::Store &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); Filter filter (actor, mChoice, mTalkedTo); - MWWorld::Store::iterator it = dialogs.begin(); - for (; it != dialogs.end(); ++it) + for (MWWorld::Store::iterator it = dialogs.begin(); it != dialogs.end(); ++it) { if(it->mType == ESM::Dialogue::Greeting) { - if (greetingFound) break; - for (std::vector::const_iterator iter (it->mInfo.begin()); - iter!=it->mInfo.end(); ++iter) + if (const ESM::DialInfo *info = filter.search (*it)) { - if (filter (*iter)) + if (!info->mSound.empty()) { - if (!iter->mSound.empty()) - { - // TODO play sound - } - - std::string text = iter->mResponse; - parseText(text); - win->addText(iter->mResponse); - executeScript(iter->mResultScript); - greetingFound = true; - mLastTopic = it->mId; - mLastDialogue = *iter; - break; + // TODO play sound } + + parseText (info->mResponse); + win->addText (info->mResponse); + executeScript (info->mResultScript); + mLastTopic = it->mId; + mLastDialogue = *info; + break; } } } @@ -243,30 +234,24 @@ namespace MWDialogue int choice = mChoice; mChoice = -1; mActorKnownTopics.clear(); - MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); const MWWorld::Store &dialogs = MWBase::Environment::get().getWorld()->getStore().get(); Filter filter (mActor, mChoice, mTalkedTo); - MWWorld::Store::iterator it = dialogs.begin(); - for (; it != dialogs.end(); ++it) + for (MWWorld::Store::iterator iter = dialogs.begin(); iter != dialogs.end(); ++iter) { - if(it->mType == ESM::Dialogue::Topic) + if (iter->mType == ESM::Dialogue::Topic) { - for (std::vector::const_iterator iter (it->mInfo.begin()); - iter!=it->mInfo.end(); ++iter) + if (filter.search (*iter)) { - if (filter (*iter)) + mActorKnownTopics.push_back (toLower (iter->mId)); + + //does the player know the topic? + if (mKnownTopics.find (toLower (iter->mId)) != mKnownTopics.end()) { - mActorKnownTopics.push_back(toLower(it->mId)); - //does the player know the topic? - if(mKnownTopics.find(toLower(it->mId)) != mKnownTopics.end()) - { - keywordList.push_back(it->mId); - break; - } + keywordList.push_back (iter->mId); } } } @@ -317,6 +302,8 @@ namespace MWDialogue if (services & ESM::NPC::Enchanting) windowServices |= MWGui::DialogueWindow::Service_Enchant; + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); + win->setServices (windowServices); // sort again, because the previous sort was case-sensitive @@ -333,30 +320,25 @@ namespace MWDialogue if(mDialogueMap.find(keyword) != mDialogueMap.end()) { ESM::Dialogue ndialogue = mDialogueMap[keyword]; - if(ndialogue.mType == ESM::Dialogue::Topic) + if (mDialogueMap[keyword].mType == ESM::Dialogue::Topic) { Filter filter (mActor, mChoice, mTalkedTo); - for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); - iter!=ndialogue.mInfo.end(); ++iter) + if (const ESM::DialInfo *info = filter.search (mDialogueMap[keyword])) { - if (filter (*iter)) - { - std::string text = iter->mResponse; - std::string script = iter->mResultScript; + std::string text = info->mResponse; + std::string script = info->mResultScript; - parseText(text); + parseText (text); - MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); - win->addTitle(keyword); - win->addText(iter->mResponse); + MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); + win->addTitle (keyword); + win->addText (info->mResponse); - executeScript(script); + executeScript (script); - mLastTopic = keyword; - mLastDialogue = *iter; - break; - } + mLastTopic = keyword; + mLastDialogue = *info; } } } @@ -372,38 +354,31 @@ namespace MWDialogue void DialogueManager::questionAnswered (const std::string& answer) { - if(mChoiceMap.find(answer) != mChoiceMap.end()) + if (mChoiceMap.find(answer) != mChoiceMap.end()) { mChoice = mChoiceMap[answer]; - std::vector::const_iterator iter; - if(mDialogueMap.find(mLastTopic) != mDialogueMap.end()) + if (mDialogueMap.find(mLastTopic) != mDialogueMap.end()) { - ESM::Dialogue ndialogue = mDialogueMap[mLastTopic]; - if(ndialogue.mType == ESM::Dialogue::Topic) + if (mDialogueMap[mLastTopic].mType == ESM::Dialogue::Topic) { Filter filter (mActor, mChoice, mTalkedTo); - for (std::vector::const_iterator iter = ndialogue.mInfo.begin(); - iter!=ndialogue.mInfo.end(); ++iter) + if (const ESM::DialInfo *info = filter.search (mDialogueMap[mLastTopic])) { - if (filter (*iter)) - { - mChoiceMap.clear(); - mChoice = -1; - mIsInChoice = false; - MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); - std::string text = iter->mResponse; - parseText(text); - win->addText(text); - executeScript(iter->mResultScript); - mLastTopic = mLastTopic; - mLastDialogue = *iter; - break; - } + mChoiceMap.clear(); + mChoice = -1; + mIsInChoice = false; + std::string text = info->mResponse; + parseText (text); + MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addText (text); + executeScript (info->mResultScript); + mLastTopic = mLastTopic; + mLastDialogue = *info; } } } + updateTopics(); } } diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index f5ea20b7b..c1f2a808f 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -390,3 +390,14 @@ 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 +{ + for (std::vector::const_iterator iter = dialogue.mInfo.begin(); + iter!=dialogue.mInfo.end(); ++iter) + if ((*this) (*iter)) + return &*iter; + + return 0; +} + diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 6e0b96a0f..2a252edc3 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -6,6 +6,7 @@ namespace ESM { struct DialInfo; + struct Dialogue; } namespace MWDialogue @@ -41,6 +42,8 @@ namespace MWDialogue bool operator() (const ESM::DialInfo& info) const; ///< \return does the dialogue match? + + const ESM::DialInfo *search (const ESM::Dialogue& dialogue) const; }; } From 77ba8c5117120f226642777c3d15f8e1870ea319 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 12 Nov 2012 13:23:25 +0100 Subject: [PATCH 23/25] Issue #219: implemented rank requirement filter --- apps/openmw/mwdialogue/filter.cpp | 68 ++++++++++++++++++++++++ apps/openmw/mwdialogue/filter.hpp | 8 +++ apps/openmw/mwdialogue/selectwrapper.cpp | 9 +++- apps/openmw/mwdialogue/selectwrapper.hpp | 3 +- apps/openmw/mwmechanics/npcstats.cpp | 28 ++++++++++ apps/openmw/mwmechanics/npcstats.hpp | 2 + 6 files changed, 115 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index c1f2a808f..c51a418bf 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -300,6 +300,30 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_PcCrimeLevel: return MWWorld::Class::get (player).getNpcStats (player).getBounty(); + + case SelectWrapper::Function_RankRequirement: + { + if (MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().empty()) + return 0; + + std::string faction = + MWWorld::Class::get (mActor).getNpcStats (mActor).getFactionRanks().begin()->first; + + int rank = getFactionRank (player, faction); + + if (rank>=9) + return 0; // max rank + + int result = 0; + + if (hasFactionRankSkillRequirements (player, faction, rank+1)) + result += 1; + + if (hasFactionRankReputationRequirements (player, faction, rank+1)) + result += 2; + + return result; + } default: @@ -382,6 +406,50 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co } } +int MWDialogue::Filter::getFactionRank (const MWWorld::Ptr& actor, const std::string& factionId) const +{ + MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor); + + std::map::const_iterator iter = stats.getFactionRanks().find (factionId); + + if (iter==stats.getFactionRanks().end()) + return -1; + + return iter->second; +} + +bool MWDialogue::Filter::hasFactionRankSkillRequirements (const MWWorld::Ptr& actor, + const std::string& factionId, int rank) const +{ + if (rank<0 || rank>=10) + throw std::runtime_error ("rank index out of range"); + + if (!MWWorld::Class::get (actor).getNpcStats (actor).hasSkillsForRank (factionId, rank)) + return false; + + const ESM::Faction& faction = + *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); + + MWMechanics::CreatureStats& stats = MWWorld::Class::get (actor).getCreatureStats (actor); + + return stats.getAttribute (faction.mData.mAttribute1).getBase()>=faction.mData.mRankData[rank].mAttribute1 && + stats.getAttribute (faction.mData.mAttribute2).getBase()>=faction.mData.mRankData[rank].mAttribute2; +} + +bool MWDialogue::Filter::hasFactionRankReputationRequirements (const MWWorld::Ptr& actor, + const std::string& factionId, int rank) const +{ + if (rank<0 || rank>=10) + throw std::runtime_error ("rank index out of range"); + + MWMechanics::NpcStats& stats = MWWorld::Class::get (actor).getNpcStats (actor); + + const ESM::Faction& faction = + *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); + + return stats.getFactionReputation (factionId)>=faction.mData.mRankData[rank].mFactReaction; +} + MWDialogue::Filter::Filter (const MWWorld::Ptr& actor, int choice, bool talkedToPlayer) : mActor (actor), mChoice (choice), mTalkedToPlayer (talkedToPlayer) {} diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index 2a252edc3..7c8f1116f 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -36,6 +36,14 @@ namespace MWDialogue 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); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index c143e9697..11f25741f 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -61,7 +61,9 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() switch (index) { - // 0-5 + // 0, 1 + case 2: return Function_RankRequirement; + // 3-5 case 6: return Function_PcLevel; case 7: return Function_PcHealthPercent; case 8: case 9: return Function_PcDynamicStat; @@ -76,6 +78,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() // 42 case 42: return Function_PcClothingModifier; case 43: return Function_PcCrimeLevel; + // 44-45 case 46: return Function_SameFaction; // 47-49 case 50: return Function_Choice; @@ -196,6 +199,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_FriendlyHit, Function_PcLevel, Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, + Function_RankRequirement, Function_None // end marker }; @@ -250,7 +254,8 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const Function_PcSkill, Function_PcExpelled, Function_PcVampire, - Function_PcCrimeLevel, + Function_PcCrimeLevel, + Function_RankRequirement, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index fd51101d8..c12b39436 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -34,7 +34,8 @@ namespace MWDialogue Function_FriendlyHit, Function_TalkedToPc, Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat, - Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel + Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, + Function_RankRequirement }; enum Type diff --git a/apps/openmw/mwmechanics/npcstats.cpp b/apps/openmw/mwmechanics/npcstats.cpp index 23e5cf54b..26415b631 100644 --- a/apps/openmw/mwmechanics/npcstats.cpp +++ b/apps/openmw/mwmechanics/npcstats.cpp @@ -3,12 +3,15 @@ #include #include +#include +#include #include #include #include #include +#include #include "../mwworld/esmstore.hpp" @@ -309,3 +312,28 @@ void MWMechanics::NpcStats::setReputation(int reputation) mReputation = reputation; } +bool MWMechanics::NpcStats::hasSkillsForRank (const std::string& factionId, int rank) const +{ + if (rank<0 || rank>=10) + throw std::runtime_error ("rank index out of range"); + + const ESM::Faction& faction = + *MWBase::Environment::get().getWorld()->getStore().get().find (factionId); + + std::vector skills; + + for (int i=0; i<6; ++i) + skills.push_back (static_cast (getSkill (faction.mData.mSkillID[i]).getModified())); + + std::sort (skills.begin(), skills.end()); + + std::vector::const_reverse_iterator iter = skills.rbegin(); + + const ESM::RankData& rankData = faction.mData.mRankData[rank]; + + if (*iter=rankData.mSkill2; +} + diff --git a/apps/openmw/mwmechanics/npcstats.hpp b/apps/openmw/mwmechanics/npcstats.hpp index 190c9a475..46af216d9 100644 --- a/apps/openmw/mwmechanics/npcstats.hpp +++ b/apps/openmw/mwmechanics/npcstats.hpp @@ -123,6 +123,8 @@ namespace MWMechanics bool isVampire() const; void setVampire (bool set); + + bool hasSkillsForRank (const std::string& factionId, int rank) const; }; } From 586ac3f5c60e9e1c60ffbf830c680a64c308d8aa Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 12 Nov 2012 13:56:51 +0100 Subject: [PATCH 24/25] Issue #219: added some more stats filters; fixed two filters --- apps/openmw/mwdialogue/filter.cpp | 33 +++++++++++++++++++----- apps/openmw/mwdialogue/selectwrapper.cpp | 21 +++++++++------ apps/openmw/mwdialogue/selectwrapper.hpp | 7 ++--- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index c51a418bf..7a98eed7b 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -208,6 +208,14 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c return select.selectCompare (value); } + + case SelectWrapper::Function_HealthPercent: + { + float ratio = MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getCurrent() / + MWWorld::Class::get (mActor).getCreatureStats (mActor).getHealth().getModified(); + + return select.selectCompare (ratio); + } default: @@ -250,7 +258,7 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con case SelectWrapper::Function_AiSetting: - return MWWorld::Class::get (player).getCreatureStats (player).getAiSetting (select.getArgument()); + return MWWorld::Class::get (mActor).getCreatureStats (mActor).getAiSetting (select.getArgument()); case SelectWrapper::Function_PcAttribute: @@ -274,11 +282,8 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return MWWorld::Class::get (player).getCreatureStats (player).getLevel(); case SelectWrapper::Function_PcGender: - { - MWWorld::LiveCellRef *cellRef = player.get(); - - return cellRef->mBase->Female ? 0 : 1; - } + + return player.get()->mBase->mFlags & ESM::NPC::Female ? 0 : 1; case SelectWrapper::Function_PcClothingModifier: { @@ -324,7 +329,11 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return result; } - + + case SelectWrapper::Function_Level: + + return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel(); + default: throw std::runtime_error ("unknown integer select function"); @@ -361,6 +370,16 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return toLower (mActor.getCell()->mCell->mName)==select.getName(); + case SelectWrapper::Function_SameGender: + + return (player.get()->mBase->mFlags & ESM::NPC::Female)== + (mActor.get()->mBase->mFlags & ESM::NPC::Female); + + case SelectWrapper::Function_SameRace: + + return toLower (mActor.get()->mBase->mRace)!= + toLower (player.get()->mBase->mRace); + case SelectWrapper::Function_SameFaction: return MWWorld::Class::get (mActor).getNpcStats (mActor).isSameFaction ( diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 11f25741f..6ccc5d7e8 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -63,7 +63,9 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() { // 0, 1 case 2: return Function_RankRequirement; - // 3-5 + // 3 + case 4: return Function_HealthPercent; + // 5 case 6: return Function_PcLevel; case 7: return Function_PcHealthPercent; case 8: case 9: return Function_PcDynamicStat; @@ -75,10 +77,10 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 39: return Function_PcExpelled; case 40: return Function_PcCommonDisease; case 41: return Function_PcBlightDisease; - // 42 case 42: return Function_PcClothingModifier; case 43: return Function_PcCrimeLevel; - // 44-45 + case 44: return Function_SameGender; + case 45: return Function_SameRace; case 46: return Function_SameFaction; // 47-49 case 50: return Function_Choice; @@ -86,13 +88,14 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 58: return Function_PcCorprus; // 59 case 60: return Function_PcVampire; - // 61, 62 + case 61: return Function_Level; + // 62 case 63: return Function_TalkedToPc; case 64: return Function_PcDynamicStat; // 65 case 66: return Function_FriendlyHit; case 67: case 68: case 69: case 70: return Function_AiSetting; - // 71-77 + // 71 } return Function_False; @@ -199,7 +202,8 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_FriendlyHit, Function_PcLevel, Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, - Function_RankRequirement, + Function_RankRequirement, + Function_Level, Function_None // end marker }; @@ -207,6 +211,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const { Function_Global, Function_Local, Function_PcDynamicStat, Function_PcHealthPercent, + Function_HealthPercent, Function_None // end marker }; @@ -214,7 +219,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const { Function_False, Function_Id, Function_Faction, Function_Class, Function_Race, Function_Cell, - Function_SameFaction, + Function_SameGender, Function_SameRace, Function_SameFaction, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_PcExpelled, Function_PcVampire, Function_TalkedToPc, @@ -250,7 +255,7 @@ bool MWDialogue::SelectWrapper::isNpcOnly() const static const Function functions[] = { Function_Faction, SelectWrapper::Function_Class, SelectWrapper::Function_Race, - Function_SameFaction, + Function_SameGender, Function_SameRace, Function_SameFaction, Function_PcSkill, Function_PcExpelled, Function_PcVampire, diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index c12b39436..0668f312e 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -24,7 +24,7 @@ namespace MWDialogue Function_Cell, Function_Local, Function_Global, - Function_SameFaction, + Function_SameGender, Function_SameRace, Function_SameFaction, Function_Choice, Function_PcCommonDisease, Function_PcBlightDisease, Function_PcCorprus, Function_AiSetting, @@ -35,9 +35,10 @@ namespace MWDialogue Function_TalkedToPc, Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat, Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, - Function_RankRequirement + Function_RankRequirement, + Function_HealthPercent, Function_Level }; - + enum Type { Type_None, From e2ccec99f0cbf6fb439f837f46883f43c51496ef Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 12 Nov 2012 14:02:49 +0100 Subject: [PATCH 25/25] Issue #219: added another missing PC stats filter --- apps/openmw/mwdialogue/filter.cpp | 4 ++++ apps/openmw/mwdialogue/selectwrapper.cpp | 4 ++-- apps/openmw/mwdialogue/selectwrapper.hpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 7a98eed7b..21904b4bc 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -334,6 +334,10 @@ int MWDialogue::Filter::getSelectStructInteger (const SelectWrapper& select) con return MWWorld::Class::get (mActor).getCreatureStats (mActor).getLevel(); + case SelectWrapper::Function_PCReputation: + + return MWWorld::Class::get (player).getNpcStats (player).getReputation(); + default: throw std::runtime_error ("unknown integer select function"); diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 6ccc5d7e8..ae5b8c582 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -65,7 +65,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::decodeFunction() case 2: return Function_RankRequirement; // 3 case 4: return Function_HealthPercent; - // 5 + case 5: return Function_PCReputation; case 6: return Function_PcLevel; case 7: return Function_PcHealthPercent; case 8: case 9: return Function_PcDynamicStat; @@ -203,7 +203,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const Function_PcLevel, Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, Function_RankRequirement, - Function_Level, + Function_Level, Function_PCReputation, Function_None // end marker }; diff --git a/apps/openmw/mwdialogue/selectwrapper.hpp b/apps/openmw/mwdialogue/selectwrapper.hpp index 0668f312e..15cd5bfff 100644 --- a/apps/openmw/mwdialogue/selectwrapper.hpp +++ b/apps/openmw/mwdialogue/selectwrapper.hpp @@ -36,7 +36,7 @@ namespace MWDialogue Function_PcLevel, Function_PcHealthPercent, Function_PcDynamicStat, Function_PcGender, Function_PcClothingModifier, Function_PcCrimeLevel, Function_RankRequirement, - Function_HealthPercent, Function_Level + Function_HealthPercent, Function_Level, Function_PCReputation }; enum Type