mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 13:53:53 +00:00
Issue #219: moved checks for local and global variables from DialogueManager to Filter
This commit is contained in:
parent
e68bb3481e
commit
e6021a3fe3
4 changed files with 49 additions and 141 deletions
|
@ -84,71 +84,6 @@ namespace
|
||||||
throw std::runtime_error ("unknown compare type in dialogue info select");
|
throw std::runtime_error ("unknown compare type in dialogue info select");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
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<ESM::Script>().find (scriptName);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
|
|
||||||
if (script->mVarNames[i]==name)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (i>=static_cast<int> (script->mVarNames.size()))
|
|
||||||
return false; // script does not have a variable of this name
|
|
||||||
|
|
||||||
const MWScript::Locals& locals = actor.getRefData().getLocals();
|
|
||||||
|
|
||||||
if (i<script->mData.mNumShorts)
|
|
||||||
return selectCompare (comp, locals.mShorts[i], value);
|
|
||||||
else
|
|
||||||
i -= script->mData.mNumShorts;
|
|
||||||
|
|
||||||
if (i<script->mData.mNumLongs)
|
|
||||||
return selectCompare (comp, locals.mLongs[i], value);
|
|
||||||
else
|
|
||||||
i -= script->mData.mNumShorts;
|
|
||||||
|
|
||||||
return selectCompare (comp, locals.mFloats.at (i), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
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
|
//helper function
|
||||||
std::string::size_type find_str_ci(const std::string& str, const std::string& substr,size_t pos)
|
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,
|
bool DialogueManager::isMatching (const MWWorld::Ptr& actor,
|
||||||
const ESM::DialInfo::SelectStruct& select) const
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,48 @@ bool MWDialogue::Filter::testSelectStructNumeric (const SelectWrapper& select) c
|
||||||
{
|
{
|
||||||
switch (select.getFunction())
|
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<ESM::Script>().find (scriptName);
|
||||||
|
|
||||||
|
std::string name = select.getName();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (; i<static_cast<int> (script->mVarNames.size()); ++i)
|
||||||
|
if (script->mVarNames[i]==name)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i>=static_cast<int> (script->mVarNames.size()))
|
||||||
|
return false; // script does not have a variable of this name
|
||||||
|
|
||||||
|
const MWScript::Locals& locals = mActor.getRefData().getLocals();
|
||||||
|
|
||||||
|
if (i<script->mData.mNumShorts)
|
||||||
|
return select.selectCompare (static_cast<int> (locals.mShorts[i]));
|
||||||
|
|
||||||
|
i -= script->mData.mNumShorts;
|
||||||
|
|
||||||
|
if (i<script->mData.mNumLongs)
|
||||||
|
return select.selectCompare (locals.mLongs[i]);
|
||||||
|
|
||||||
|
i -= script->mData.mNumShorts;
|
||||||
|
|
||||||
|
return select.selectCompare (locals.mFloats.at (i));
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
throw std::runtime_error ("unknown numeric select function");
|
throw std::runtime_error ("unknown numeric select function");
|
||||||
|
|
|
@ -60,6 +60,8 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
case '2': return Function_Global;
|
||||||
|
case '3': return Function_Local;
|
||||||
case '4': return Function_Journal;
|
case '4': return Function_Journal;
|
||||||
case '5': return Function_Item;
|
case '5': return Function_Item;
|
||||||
case '6': return Function_Dead;
|
case '6': return Function_Dead;
|
||||||
|
@ -68,6 +70,7 @@ MWDialogue::SelectWrapper::Function MWDialogue::SelectWrapper::getFunction() con
|
||||||
case '9': return Function_Class;
|
case '9': return Function_Class;
|
||||||
case 'A': return Function_Race;
|
case 'A': return Function_Race;
|
||||||
case 'B': return Function_Cell;
|
case 'B': return Function_Cell;
|
||||||
|
case 'C': return Function_Local;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Function_None;
|
return Function_None;
|
||||||
|
@ -83,6 +86,7 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
|
||||||
|
|
||||||
static const Function numericFunctions[] =
|
static const Function numericFunctions[] =
|
||||||
{
|
{
|
||||||
|
Function_Global, Function_Local,
|
||||||
Function_None // end marker
|
Function_None // end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,9 @@ namespace MWDialogue
|
||||||
Function_Faction,
|
Function_Faction,
|
||||||
Function_Class,
|
Function_Class,
|
||||||
Function_Race,
|
Function_Race,
|
||||||
Function_Cell
|
Function_Cell,
|
||||||
|
Function_Local,
|
||||||
|
Function_Global
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Type
|
enum Type
|
||||||
|
|
Loading…
Reference in a new issue