diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index a369486fa..55059b522 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -270,6 +270,72 @@ namespace MWScript MWBase::Environment::get().getWorld()->disable (ref); } + int InterpreterContext::getMemberShort (const std::string& id, const std::string& name) const + { + const MWWorld::Ptr ptr = getReference (id, false); + + std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr); + + int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's'); + + return ptr.getRefData().getLocals().mShorts[index]; + } + + int InterpreterContext::getMemberLong (const std::string& id, const std::string& name) const + { + const MWWorld::Ptr ptr = getReference (id, false); + + std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr); + + int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l'); + + return ptr.getRefData().getLocals().mLongs[index]; + } + + float InterpreterContext::getMemberFloat (const std::string& id, const std::string& name) const + { + const MWWorld::Ptr ptr = getReference (id, false); + + std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr); + + int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f'); + + return ptr.getRefData().getLocals().mFloats[index]; + } + + void InterpreterContext::setMemberShort (const std::string& id, const std::string& name, int value) + { + const MWWorld::Ptr ptr = getReference (id, false); + + std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr); + + int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 's'); + + ptr.getRefData().getLocals().mShorts[index] = value; + } + + void InterpreterContext::setMemberLong (const std::string& id, const std::string& name, int value) + { + const MWWorld::Ptr ptr = getReference (id, false); + + std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr); + + int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'l'); + + ptr.getRefData().getLocals().mLongs[index] = value; + } + + void InterpreterContext::setMemberFloat (const std::string& id, const std::string& name, float value) + { + const MWWorld::Ptr ptr = getReference (id, false); + + std::string scriptId = MWWorld::Class::get (ptr).getScript (ptr); + + int index = MWBase::Environment::get().getScriptManager()->getLocalIndex (scriptId, name, 'f'); + + ptr.getRefData().getLocals().mFloats[index] = value; + } + MWWorld::Ptr InterpreterContext::getReference() { return getReference ("", true); diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index 40f53337d..9fdc3c21a 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -107,6 +107,18 @@ namespace MWScript virtual void disable (const std::string& id = ""); + virtual int getMemberShort (const std::string& id, const std::string& name) const; + + virtual int getMemberLong (const std::string& id, const std::string& name) const; + + virtual float getMemberFloat (const std::string& id, const std::string& name) const; + + virtual void setMemberShort (const std::string& id, const std::string& name, int value); + + virtual void setMemberLong (const std::string& id, const std::string& name, int value); + + virtual void setMemberFloat (const std::string& id, const std::string& name, float value); + MWWorld::Ptr getReference(); ///< Reference, that the script is running from (can be empty) }; diff --git a/apps/openmw/mwscript/scriptmanager.cpp b/apps/openmw/mwscript/scriptmanager.cpp index 506cf049c..6ae506483 100644 --- a/apps/openmw/mwscript/scriptmanager.cpp +++ b/apps/openmw/mwscript/scriptmanager.cpp @@ -156,4 +156,43 @@ namespace MWScript { return mGlobalScripts; } + + int ScriptManager::getLocalIndex (const std::string& scriptId, const std::string& variable, + char type) + { + const ESM::Script *script = mStore.scripts.find (scriptId); + + int offset = 0; + int size = 0; + + switch (type) + { + case 's': + + offset = 0; + size = script->data.numShorts; + break; + + case 'l': + + offset = script->data.numShorts; + size = script->data.numLongs; + break; + + case 'f': + + offset = script->data.numShorts+script->data.numLongs; + size = script->data.numFloats; + + default: + + throw std::runtime_error ("invalid variable type"); + } + + for (int i=0; ivarNames.at (i+offset)==variable) + return i; + + throw std::runtime_error ("unable to access local variable " + variable + " of " + scriptId); + } } diff --git a/apps/openmw/mwscript/scriptmanager.hpp b/apps/openmw/mwscript/scriptmanager.hpp index 35c1fadd9..34cc0defe 100644 --- a/apps/openmw/mwscript/scriptmanager.hpp +++ b/apps/openmw/mwscript/scriptmanager.hpp @@ -67,6 +67,10 @@ namespace MWScript ///< Return locals for script \a name. GlobalScripts& getGlobalScripts(); + + int getLocalIndex (const std::string& scriptId, const std::string& variable, char type); + ///< Return index of the variable of the given name and type in the given script. Will + /// throw an exception, if there is no such script or variable or the type does not match. }; }; diff --git a/components/interpreter/context.hpp b/components/interpreter/context.hpp index 973b22d35..4221da36e 100644 --- a/components/interpreter/context.hpp +++ b/components/interpreter/context.hpp @@ -65,6 +65,19 @@ namespace Interpreter virtual void enable (const std::string& id = "") = 0; virtual void disable (const std::string& id = "") = 0; + + virtual int getMemberShort (const std::string& id, const std::string& name) const = 0; + + virtual int getMemberLong (const std::string& id, const std::string& name) const = 0; + + virtual float getMemberFloat (const std::string& id, const std::string& name) const = 0; + + virtual void setMemberShort (const std::string& id, const std::string& name, int value) = 0; + + virtual void setMemberLong (const std::string& id, const std::string& name, int value) = 0; + + virtual void setMemberFloat (const std::string& id, const std::string& name, float value) + = 0; }; }