1
0
Fork 0
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:
Marc Zinnschlag 2012-11-08 22:11:50 +01:00
parent e68bb3481e
commit e6021a3fe3
4 changed files with 49 additions and 141 deletions

View file

@ -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;
}

View file

@ -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");

View file

@ -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
};

View file

@ -21,7 +21,9 @@ namespace MWDialogue
Function_Faction,
Function_Class,
Function_Race,
Function_Cell
Function_Cell,
Function_Local,
Function_Global
};
enum Type