mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 11:23:52 +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");
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<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:
|
||||
|
||||
throw std::runtime_error ("unknown numeric select function");
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,9 @@ namespace MWDialogue
|
|||
Function_Faction,
|
||||
Function_Class,
|
||||
Function_Race,
|
||||
Function_Cell
|
||||
Function_Cell,
|
||||
Function_Local,
|
||||
Function_Global
|
||||
};
|
||||
|
||||
enum Type
|
||||
|
|
Loading…
Reference in a new issue