From e6021a3fe3982acb7f35416aba5a4b43027359b8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 8 Nov 2012 22:11:50 +0100 Subject: [PATCH] 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 5d3bebbc0e..e12a22247f 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 9d14dbafcb..4ad7bc1578 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 90aa77f944..effb431108 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 10a20ef746..1bd528be05 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