diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index f339fa520..6074a12d0 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -198,13 +198,12 @@ namespace MWScript if (iter==mScripts.end()) { - if (const ESM::Script *script = mStore.get().find (name)) - { - GlobalScriptDesc desc; - desc.mLocals.configure (*script); + const ESM::Script *script = mStore.get().find (name); - iter = mScripts.insert (std::make_pair (name, desc)).first; - } + GlobalScriptDesc desc; + desc.mLocals.configure (*script); + + iter = mScripts.insert (std::make_pair (name2, desc)).first; } return iter->second.mLocals; diff --git a/apps/openmw/mwscript/locals.cpp b/apps/openmw/mwscript/locals.cpp index a18d0d5ae..ee93ea2e7 100644 --- a/apps/openmw/mwscript/locals.cpp +++ b/apps/openmw/mwscript/locals.cpp @@ -9,13 +9,32 @@ #include "../mwbase/environment.hpp" #include "../mwbase/scriptmanager.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/esmstore.hpp" #include namespace MWScript { - void Locals::configure (const ESM::Script& script) + void Locals::ensure (const std::string& scriptName) { + if (!mInitialised) + { + const ESM::Script *script = MWBase::Environment::get().getWorld()->getStore(). + get().find (scriptName); + + configure (*script); + } + } + + Locals::Locals() : mInitialised (false) {} + + bool Locals::configure (const ESM::Script& script) + { + if (mInitialised) + return false; + const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals (script.mId); @@ -25,6 +44,9 @@ namespace MWScript mLongs.resize (locals.get ('l').size(), 0); mFloats.clear(); mFloats.resize (locals.get ('f').size(), 0); + + mInitialised = true; + return true; } bool Locals::isEmpty() const @@ -36,6 +58,8 @@ namespace MWScript { try { + ensure (script); + const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = locals.getIndex(var); @@ -49,6 +73,8 @@ namespace MWScript int Locals::getIntVar(const std::string &script, const std::string &var) { + ensure (script); + const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = locals.getIndex(var); char type = locals.getType(var); @@ -73,6 +99,8 @@ namespace MWScript bool Locals::setVarByInt(const std::string& script, const std::string& var, int val) { + ensure (script); + const Compiler::Locals& locals = MWBase::Environment::get().getScriptManager()->getLocals(script); int index = locals.getIndex(var); char type = locals.getType(var); @@ -94,8 +122,11 @@ namespace MWScript return false; } - void Locals::write (ESM::Locals& locals, const std::string& script) const + bool Locals::write (ESM::Locals& locals, const std::string& script) const { + if (!mInitialised) + return false; + try { const Compiler::Locals& declarations = @@ -132,10 +163,14 @@ namespace MWScript catch (const Compiler::SourceException&) { } + + return true; } void Locals::read (const ESM::Locals& locals, const std::string& script) { + ensure (script); + try { const Compiler::Locals& declarations = diff --git a/apps/openmw/mwscript/locals.hpp b/apps/openmw/mwscript/locals.hpp index a9fcf317c..bb4df42bf 100644 --- a/apps/openmw/mwscript/locals.hpp +++ b/apps/openmw/mwscript/locals.hpp @@ -15,30 +15,50 @@ namespace MWScript { class Locals { + bool mInitialised; + + void ensure (const std::string& scriptName); + public: std::vector mShorts; std::vector mLongs; std::vector mFloats; + Locals(); + /// Are there any locals? + /// + /// \note Will return false, if locals have not been configured yet. bool isEmpty() const; - void configure (const ESM::Script& script); + /// \return Did the state of *this change from uninitialised to initialised? + bool configure (const ESM::Script& script); /// @note var needs to be in lowercase + /// + /// \note Locals will be automatically configured first, if necessary bool setVarByInt(const std::string& script, const std::string& var, int val); + /// \note Locals will be automatically configured first, if necessary + // + // \note If it can not be determined if the variable exists, the error will be + // ignored and false will be returned. bool hasVar(const std::string& script, const std::string& var); /// if var does not exist, returns 0 /// @note var needs to be in lowercase + /// + /// \note Locals will be automatically configured first, if necessary int getIntVar (const std::string& script, const std::string& var); - void write (ESM::Locals& locals, const std::string& script) const; + /// \note If locals have not been configured yet, no data is written. + /// + /// \return Locals written? + bool write (ESM::Locals& locals, const std::string& script) const; + /// \note Locals will be automatically configured first, if necessary void read (const ESM::Locals& locals, const std::string& script); }; } #endif - diff --git a/apps/openmw/mwscript/scriptmanagerimp.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp index 084beb812..b73c9a642 100644 --- a/apps/openmw/mwscript/scriptmanagerimp.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -170,7 +170,7 @@ namespace MWScript return iter->second; } - if (const ESM::Script *script = mStore.get().find (name2)) + if (const ESM::Script *script = mStore.get().search (name2)) { if (mVerbose) std::cout diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index 2062e78d9..88a6fa353 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -14,7 +14,6 @@ namespace MWWorld { mBaseNode = refData.mBaseNode; mLocals = refData.mLocals; - mHasLocals = refData.mHasLocals; mEnabled = refData.mEnabled; mCount = refData.mCount; mPosition = refData.mPosition; @@ -34,7 +33,7 @@ namespace MWWorld } RefData::RefData() - : mBaseNode(0), mDeleted(false), mHasLocals (false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false) + : mBaseNode(0), mDeleted(false), mEnabled (true), mCount (1), mCustomData (0), mChanged(false) { for (int i=0; i<3; ++i) { @@ -45,7 +44,7 @@ namespace MWWorld } RefData::RefData (const ESM::CellRef& cellRef) - : mBaseNode(0), mDeleted(false), mHasLocals (false), mEnabled (true), + : mBaseNode(0), mDeleted(false), mEnabled (true), mCount (1), mPosition (cellRef.mPos), mCustomData (0), mChanged(false) // Loading from ESM/ESP files -> assume unchanged @@ -56,13 +55,13 @@ namespace MWWorld } RefData::RefData (const ESM::ObjectState& objectState) - : mBaseNode(0), mDeleted(false), mHasLocals (false), + : mBaseNode(0), mDeleted(false), mEnabled (objectState.mEnabled != 0), mCount (objectState.mCount), mPosition (objectState.mPosition), mCustomData (0), mChanged(true) // Loading from a savegame -> assume changed - { + { for (int i=0; i<3; ++i) mLocalRotation.rot[i] = objectState.mLocalRotation[i]; } @@ -83,10 +82,7 @@ namespace MWWorld void RefData::write (ESM::ObjectState& objectState, const std::string& scriptId) const { - objectState.mHasLocals = mHasLocals; - - if (mHasLocals) - mLocals.write (objectState.mLocals, scriptId); + objectState.mHasLocals = mLocals.write (objectState.mLocals, scriptId); objectState.mEnabled = mEnabled; objectState.mCount = mCount; @@ -139,13 +135,8 @@ namespace MWWorld void RefData::setLocals (const ESM::Script& script) { - if (!mHasLocals) - { - mLocals.configure (script); - mHasLocals = true; - if (!mLocals.isEmpty()) - mChanged = true; - } + if (mLocals.configure (script) && !mLocals.isEmpty()) + mChanged = true; } void RefData::setCount (int count) diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 61055aa73..4075f62ce 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -31,11 +31,9 @@ namespace MWWorld { osg::PositionAttitudeTransform* mBaseNode; - MWScript::Locals mLocals; // if we find the overhead of heaving a locals - // object in the refdata of refs without a script, - // we can make this a pointer later. + MWScript::Locals mLocals; + bool mDeleted; // separate delete flag used for deletion by a content file - bool mHasLocals; bool mEnabled; int mCount; // 0: deleted