diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 9f31fdda6..37a84b287 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -159,6 +159,39 @@ bool MWDialogue::Filter::testDisposition (const ESM::DialInfo& info, bool invert : (actorDisposition >= info.mData.mDisposition); } +bool MWDialogue::Filter::testFunctionLocal(const MWDialogue::SelectWrapper& select) const +{ + std::string scriptName = mActor.getClass().getScript (mActor); + + if (scriptName.empty()) + return false; // no script + + std::string name = Misc::StringUtils::lowerCase (select.getName()); + + const Compiler::Locals& localDefs = + MWBase::Environment::get().getScriptManager()->getLocals (scriptName); + + char type = localDefs.getType (name); + + if (type==' ') + return false; // script does not have a variable of this name. + + int index = localDefs.getIndex (name); + if (index < 0) + return false; // shouldn't happen, we checked that variable has a type above, so must exist + + const MWScript::Locals& locals = mActor.getRefData().getLocals(); + + switch (type) + { + case 's': return select.selectCompare (static_cast (locals.mShorts[index])); + case 'l': return select.selectCompare (locals.mLongs[index]); + case 'f': return select.selectCompare (locals.mFloats[index]); + } + + throw std::logic_error ("unknown local variable type in dialogue filter"); +} + bool MWDialogue::Filter::testSelectStruct (const SelectWrapper& select) const { if (select.isNpcOnly() && (mActor.getTypeName() != typeid (ESM::NPC).name())) @@ -200,35 +233,12 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c case SelectWrapper::Function_Local: { - std::string scriptName = mActor.getClass().getScript (mActor); - - if (scriptName.empty()) - return false; // no script - - std::string name = Misc::StringUtils::lowerCase (select.getName()); - - const Compiler::Locals& localDefs = - MWBase::Environment::get().getScriptManager()->getLocals (scriptName); - - char type = localDefs.getType (name); - - if (type==' ') - return false; // script does not have a variable of this name. - - int index = localDefs.getIndex (name); - if (index < 0) - return false; // shouldn't happen, we checked that variable has a type above, so must exist - - const MWScript::Locals& locals = mActor.getRefData().getLocals(); - - switch (type) - { - case 's': return select.selectCompare (static_cast (locals.mShorts[index])); - case 'l': return select.selectCompare (locals.mLongs[index]); - case 'f': return select.selectCompare (locals.mFloats[index]); - } + return testFunctionLocal(select); + } - throw std::logic_error ("unknown local variable type in dialogue filter"); + case SelectWrapper::Function_NotLocal: + { + return !testFunctionLocal(select); } case SelectWrapper::Function_PcHealthPercent: @@ -472,20 +482,6 @@ bool MWDialogue::Filter::getSelectStructBoolean (const SelectWrapper& select) co return !Misc::StringUtils::ciEqual(MWBase::Environment::get().getWorld()->getCellName(mActor.getCell()) , select.getName()); - case SelectWrapper::Function_NotLocal: - { - std::string scriptName = mActor.getClass().getScript (mActor); - - if (scriptName.empty()) - // This actor has no attached script, so there is no local variable - return true; - - const Compiler::Locals& localDefs = - MWBase::Environment::get().getScriptManager()->getLocals (scriptName); - - return localDefs.getIndex (Misc::StringUtils::lowerCase (select.getName()))==-1; - } - case SelectWrapper::Function_SameGender: return (player.get()->mBase->mFlags & ESM::NPC::Female)== diff --git a/apps/openmw/mwdialogue/filter.hpp b/apps/openmw/mwdialogue/filter.hpp index d41b7aa1e..4e2ebe6e5 100644 --- a/apps/openmw/mwdialogue/filter.hpp +++ b/apps/openmw/mwdialogue/filter.hpp @@ -33,6 +33,8 @@ namespace MWDialogue bool testDisposition (const ESM::DialInfo& info, bool invert=false) const; ///< Is the actor disposition toward the player high enough (or low enough, if \a invert is true)? + bool testFunctionLocal(const SelectWrapper& select) const; + bool testSelectStruct (const SelectWrapper& select) const; bool testSelectStructNumeric (const SelectWrapper& select) const; diff --git a/apps/openmw/mwdialogue/selectwrapper.cpp b/apps/openmw/mwdialogue/selectwrapper.cpp index 68c88e943..793963e48 100644 --- a/apps/openmw/mwdialogue/selectwrapper.cpp +++ b/apps/openmw/mwdialogue/selectwrapper.cpp @@ -210,7 +210,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const static const Function numericFunctions[] = { - Function_Global, Function_Local, + Function_Global, Function_Local, Function_NotLocal, Function_PcDynamicStat, Function_PcHealthPercent, Function_HealthPercent, Function_None // end marker @@ -232,7 +232,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const static const Function invertedBooleanFunctions[] = { Function_NotId, Function_NotFaction, Function_NotClass, - Function_NotRace, Function_NotCell, Function_NotLocal, + Function_NotRace, Function_NotCell, Function_None // end marker };