diff options
Diffstat (limited to 'src/scripting')
-rw-r--r-- | src/scripting/lua.cpp | 10 | ||||
-rw-r--r-- | src/scripting/luascript.cpp | 25 | ||||
-rw-r--r-- | src/scripting/luascript.h | 5 | ||||
-rw-r--r-- | src/scripting/luautil.cpp | 2 | ||||
-rw-r--r-- | src/scripting/script.cpp | 25 | ||||
-rw-r--r-- | src/scripting/script.h | 50 | ||||
-rw-r--r-- | src/scripting/scriptmanager.cpp | 2 |
7 files changed, 74 insertions, 45 deletions
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 4e2cd283..e305fcd7 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1438,17 +1438,11 @@ static int chr_request_quest(lua_State *s) Script::Ref callback; script->assignCallback(callback); - // Backup the map since execute will reset it - MapComposite *map = script->getMap(); - script->prepare(callback); script->push(ch); script->push(name); script->push(value); - script->execute(); - - // Restore map - script->setMap(map); + script->execute(ch->getMap()); return 0; } @@ -2132,7 +2126,7 @@ static int get_map_id(lua_State *s) { Script *script = getScript(s); - if (MapComposite *mapComposite = script->getMap()) + if (MapComposite *mapComposite = script->getContext()->map) lua_pushinteger(s, mapComposite->getID()); else lua_pushnil(s); diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp index f4ea39ac..e9f4492d 100644 --- a/src/scripting/luascript.cpp +++ b/src/scripting/luascript.cpp @@ -118,10 +118,12 @@ void LuaScript::push(const std::list<InventoryItem> &itemList) ++nbArgs; } -int LuaScript::execute() +int LuaScript::execute(const Context &context) { assert(nbArgs >= 0); + const Context *previousContext = mContext; + mContext = &context; const int tmpNbArgs = nbArgs; nbArgs = -1; @@ -139,7 +141,7 @@ int LuaScript::execute() } res = lua_tointeger(mCurrentState, -1); lua_pop(mCurrentState, 1); - setMap(0); + mContext = previousContext; return res; } @@ -148,7 +150,9 @@ bool LuaScript::resume() assert(nbArgs >= 0); assert(mCurrentThread); - setMap(mCurrentThread->mMap); + const Context *previousContext = mContext; + mContext = &mCurrentThread->getContext(); + const int tmpNbArgs = nbArgs; nbArgs = -1; #if LUA_VERSION_NUM < 502 @@ -156,7 +160,6 @@ bool LuaScript::resume() #else int result = lua_resume(mCurrentState, NULL, tmpNbArgs); #endif - setMap(0); if (result == 0) // Thread is done { @@ -181,6 +184,7 @@ bool LuaScript::resume() } lua_settop(mCurrentState, 0); + mContext = previousContext; const bool done = result != LUA_YIELD; if (done) @@ -215,8 +219,11 @@ void LuaScript::unref(Ref &ref) } } -void LuaScript::load(const char *prog, const char *name) +void LuaScript::load(const char *prog, const char *name, + const Context &context) { + const Context *previousContext = mContext; + mContext = &context; int res = luaL_loadbuffer(mRootState, prog, std::strlen(prog), name); if (res) { @@ -238,19 +245,18 @@ void LuaScript::load(const char *prog, const char *name) << lua_tostring(mRootState, -1)); lua_pop(mRootState, 1); } - setMap(0); + mContext = previousContext; } void LuaScript::processDeathEvent(Being *entity) { if (mDeathNotificationCallback.isValid()) { - setMap(entity->getMap()); prepare(mDeathNotificationCallback); push(entity); //TODO: get and push a list of creatures who contributed to killing the // being. This might be very interesting for scripting quests. - execute(); + Script::execute(entity->getMap()); } } @@ -258,12 +264,11 @@ void LuaScript::processRemoveEvent(Entity *entity) { if (mRemoveNotificationCallback.isValid()) { - setMap(entity->getMap()); prepare(mRemoveNotificationCallback); push(entity); //TODO: get and push a list of creatures who contributed to killing the // being. This might be very interesting for scripting quests. - execute(); + Script::execute(entity->getMap()); } } diff --git a/src/scripting/luascript.h b/src/scripting/luascript.h index 9515bf0e..3bedbc28 100644 --- a/src/scripting/luascript.h +++ b/src/scripting/luascript.h @@ -44,7 +44,8 @@ class LuaScript : public Script ~LuaScript(); - void load(const char *prog, const char *name); + void load(const char *prog, const char *name, + const Context &context = Context()); Thread *newThread(); @@ -60,7 +61,7 @@ class LuaScript : public Script void push(const std::list<InventoryItem> &itemList); - int execute(); + int execute(const Context &context = Context()); bool resume(); diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index f7b39e29..6210eda0 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -267,7 +267,7 @@ MapComposite *checkCurrentMap(lua_State *s, Script *script /* = 0 */) if (!script) script = getScript(s); - MapComposite *mapComposite = script->getMap(); + MapComposite *mapComposite = script->getContext()->map; if (!mapComposite) luaL_error(s, "no current map"); diff --git a/src/scripting/script.cpp b/src/scripting/script.cpp index 63ab7ff4..72943d43 100644 --- a/src/scripting/script.cpp +++ b/src/scripting/script.cpp @@ -40,7 +40,7 @@ Script::Ref Script::mUpdateCallback; Script::Script(): mCurrentThread(0), - mMap(0) + mContext(0) {} Script::~Script() @@ -95,14 +95,14 @@ static char *skipPotentialBom(char *text) return (strncmp(text, utf8Bom, bomLength) == 0) ? text + bomLength : text; } -bool Script::loadFile(const std::string &name) +bool Script::loadFile(const std::string &name, const Context &context) { int size; char *buffer = ResourceManager::loadFile(name, size); if (buffer) { mScriptFile = name; - load(skipPotentialBom(buffer), name.c_str()); + load(skipPotentialBom(buffer), name.c_str(), context); free(buffer); return true; } else { @@ -114,7 +114,8 @@ void Script::loadNPC(const std::string &name, int id, ManaServ::BeingGender gender, int x, int y, - const char *prog) + const char *prog, + MapComposite *map) { if (!mCreateNpcDelayedCallback.isValid()) { @@ -122,14 +123,23 @@ void Script::loadNPC(const std::string &name, "Could not enabled NPC"); return; } - load(prog, name.c_str()); + Context context; + context.map = map; + load(prog, name.c_str(), context); prepare(mCreateNpcDelayedCallback); push(name); push(id); push(gender); push(x); push(y); - execute(); + execute(context); +} + +int Script::execute(MapComposite *map) +{ + Context context; + context.map = map; + return execute(context); } @@ -153,8 +163,7 @@ static void fastRemoveOne(std::vector<T> &vector, T value) Script::Thread::Thread(Script *script) : mScript(script), - mState(ThreadPending), - mMap(0) + mState(ThreadPending) { script->mThreads.push_back(this); } diff --git a/src/scripting/script.h b/src/scripting/script.h index 8dee23a9..574d1b9b 100644 --- a/src/scripting/script.h +++ b/src/scripting/script.h @@ -27,6 +27,7 @@ #include <list> #include <string> #include <vector> +#include <stack> #include <sigc++/trackable.h> @@ -40,6 +41,15 @@ class Entity; class Script : public sigc::trackable { public: + struct Context + { + MapComposite *map; + + Context() + : map(0) + {} + }; + /** * Defines a function that creates a Script instance. */ @@ -87,9 +97,12 @@ class Script : public sigc::trackable Thread(Script *script); virtual ~Thread(); + Context &getContext() + { return mContext; } + Script * const mScript; ThreadState mState; - MapComposite *mMap; + Context mContext; }; Script(); @@ -102,14 +115,18 @@ class Script : public sigc::trackable * * @param prog the program text to load * @param name the name of the text, used for error reporting + * @param context the context that is supposed to be used for loading */ - virtual void load(const char *prog, const char *name) = 0; + virtual void load(const char *prog, + const char *name, + const Context &context = Context()) = 0; /** * Loads a text file into script context and executes its global * statements. */ - virtual bool loadFile(const std::string &); + virtual bool loadFile(const std::string &, + const Context &context = Context()); /** * Loads a chunk of text and considers it as an NPC handler. This @@ -119,7 +136,8 @@ class Script : public sigc::trackable int id, ManaServ::BeingGender gender, int x, int y, - const char *); + const char *, + MapComposite *map); /** * Called every tick for the script to manage its data. @@ -174,9 +192,17 @@ class Script : public sigc::trackable /** * Executes the function being prepared. + * @param context the context that is supposed to be used for executing * @return the value returned by the script. */ - virtual int execute() = 0; + virtual int execute(const Context &context = Context()) = 0; + + /** + * Executes the function being prepared. + * @param the map which is set as context + * @return the value returned by the script. + */ + int execute(MapComposite *map); /** * Starts or resumes the current thread. Deletes the thread when it is @@ -207,16 +233,10 @@ class Script : public sigc::trackable { return mCurrentThread; } /** - * Sets associated map. - */ - void setMap(MapComposite *m) - { mMap = m; } - - /** - * Gets associated map. + * Returns the current context. */ - MapComposite *getMap() const - { return mMap; } + const Context *getContext() const + { return mContext; } virtual void processDeathEvent(Being *entity) = 0; @@ -231,9 +251,9 @@ class Script : public sigc::trackable protected: std::string mScriptFile; Thread *mCurrentThread; + const Context *mContext; private: - MapComposite *mMap; std::vector<Thread*> mThreads; static Ref mCreateNpcDelayedCallback; diff --git a/src/scripting/scriptmanager.cpp b/src/scripting/scriptmanager.cpp index c9d1ce85..39a1a6a5 100644 --- a/src/scripting/scriptmanager.cpp +++ b/src/scripting/scriptmanager.cpp @@ -60,7 +60,7 @@ bool ScriptManager::performCraft(Being *crafter, _currentState->prepare(_craftCallback); _currentState->push(crafter); _currentState->push(recipe); - _currentState->execute(); + _currentState->execute(crafter->getMap()); return true; } |