diff options
author | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-03-10 23:31:32 +0100 |
---|---|---|
committer | Erik Schilling <ablu.erikschilling@googlemail.com> | 2012-03-11 10:16:35 +0100 |
commit | 520705579d6a68cf6908275026eef2edee0758af (patch) | |
tree | 2d37eb5e28a1f6d95bac4094a613f054c08c55b2 /src | |
parent | 78c912fb4007c3e5f0b43de02646772acb21ecf2 (diff) | |
download | manaserv-520705579d6a68cf6908275026eef2edee0758af.tar.gz manaserv-520705579d6a68cf6908275026eef2edee0758af.tar.bz2 manaserv-520705579d6a68cf6908275026eef2edee0758af.tar.xz manaserv-520705579d6a68cf6908275026eef2edee0758af.zip |
Added callbacks for map/worldvar changes
Reviewed-by: bjorn.
Diffstat (limited to 'src')
-rw-r--r-- | src/game-server/mapcomposite.cpp | 35 | ||||
-rw-r--r-- | src/game-server/mapcomposite.h | 19 | ||||
-rw-r--r-- | src/game-server/state.cpp | 17 | ||||
-rw-r--r-- | src/game-server/state.h | 6 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 22 | ||||
-rw-r--r-- | src/scripting/luascript.cpp | 8 |
6 files changed, 104 insertions, 3 deletions
diff --git a/src/game-server/mapcomposite.cpp b/src/game-server/mapcomposite.cpp index ec455962..a0d48f5b 100644 --- a/src/game-server/mapcomposite.cpp +++ b/src/game-server/mapcomposite.cpp @@ -658,11 +658,46 @@ void MapComposite::setVariable(const std::string &key, const std::string &value) { // changed value or unknown variable mScriptVariables[key] = value; + callMapVariableCallback(key, value); // update accountserver accountHandler->updateMapVar(this, key, value); } } +static void callVariableCallback(Script::Ref &function, const std::string &key, + const std::string &value, MapComposite *map) +{ + if (function.isValid()) + { + Script *s = ScriptManager::currentState(); + s->setMap(map); + s->prepare(function); + s->push(key); + s->push(value); + s->execute(); + } +} + +void MapComposite::callMapVariableCallback(const std::string &key, + const std::string &value) +{ + std::map<const std::string, Script::Ref>::iterator it = + mMapVariableCallbacks.find(key); + if (it == mMapVariableCallbacks.end()) + return; + callVariableCallback(it->second, key, value, this); +} + +void MapComposite::callWorldVariableCallback(const std::string &key, + const std::string &value) +{ + std::map<const std::string, Script::Ref>::iterator it = + mWorldVariableCallbacks.find(key); + if (it == mWorldVariableCallbacks.end()) + return; + callVariableCallback(it->second, key, value, this); +} + /** * Initializes the map content. This creates the warps, spawn areas, npcs and * other scripts. diff --git a/src/game-server/mapcomposite.h b/src/game-server/mapcomposite.h index 54334663..15310a97 100644 --- a/src/game-server/mapcomposite.h +++ b/src/game-server/mapcomposite.h @@ -338,6 +338,21 @@ class MapComposite const std::string &value) { mScriptVariables[key] = value; } + /** + * Sets callback for map variable + */ + void setMapVariableCallback(const std::string &key, Script *script) + { script->assignCallback(mMapVariableCallbacks[key]); } + + /** + * Sets callback for global variable + */ + void setWorldVariableCallback(const std::string &key, Script *script) + { script->assignCallback(mWorldVariableCallbacks[key]); } + + void callWorldVariableCallback(const std::string &key, + const std::string &value); + static void setInitializeCallback(Script *script) { script->assignCallback(mInitializeCallback); } @@ -345,6 +360,8 @@ class MapComposite MapComposite(const MapComposite &); void initializeContent(); + void callMapVariableCallback(const std::string &key, + const std::string &value); Map *mMap; /**< Actual map. */ MapContent *mContent; /**< Entities on the map. */ @@ -353,6 +370,8 @@ class MapComposite /** Cached persistent variables */ std::map<std::string, std::string> mScriptVariables; PvPRules mPvPRules; + std::map<const std::string, Script::Ref> mMapVariableCallbacks; + std::map<const std::string, Script::Ref> mWorldVariableCallbacks; static Script::Ref mInitializeCallback; }; diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index cd2b8e5d..34ede681 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -832,12 +832,29 @@ std::string GameState::getVariable(const std::string &key) void GameState::setVariable(const std::string &key, const std::string &value) { + if (mScriptVariables[key] == value) + return; mScriptVariables[key] = value; accountHandler->updateWorldVar(key, value); + callVariableCallbacks(key, value); } void GameState::setVariableFromDbserver(const std::string &key, const std::string &value) { + if (mScriptVariables[key] == value) + return; mScriptVariables[key] = value; + callVariableCallbacks(key, value); +} + +void GameState::callVariableCallbacks(const std::string &key, + const std::string &value) +{ + const MapManager::Maps &maps = MapManager::getMaps(); + for (MapManager::Maps::const_iterator m = maps.begin(), + m_end = maps.end(); m != m_end; ++m) + { + m->second->callWorldVariableCallback(key, value); + } } diff --git a/src/game-server/state.h b/src/game-server/state.h index 479cc1d9..6fae5c89 100644 --- a/src/game-server/state.h +++ b/src/game-server/state.h @@ -121,6 +121,12 @@ namespace GameState */ void setVariableFromDbserver (const std::string &key, const std::string &value); + /** + * Informs all maps about the change of a variable so the maps can call + * callbacks for those. + */ + void callVariableCallbacks(const std::string &key, + const std::string &value); } #endif diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 5053070a..a416771f 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -161,6 +161,26 @@ static int on_get_special_recharge_cost(lua_State *s) return 0; } +static int on_mapvar_changed(lua_State *s) +{ + const char *key = luaL_checkstring(s, 1); + luaL_checktype(s, 2, LUA_TFUNCTION); + luaL_argcheck(s, key[0] != 0, 2, "empty variable name"); + MapComposite *m = checkCurrentMap(s); + m->setMapVariableCallback(key, getScript(s)); + return 0; +} + +static int on_worldvar_changed(lua_State *s) +{ + const char *key = luaL_checkstring(s, 1); + luaL_checktype(s, 2, LUA_TFUNCTION); + luaL_argcheck(s, key[0] != 0, 2, "empty variable name"); + MapComposite *m = checkCurrentMap(s); + m->setWorldVariableCallback(key, getScript(s)); + return 0; +} + static int get_item_class(lua_State *s) { LuaItemClass::push(s, checkItemClass(s, 1)); @@ -2139,6 +2159,8 @@ LuaScript::LuaScript(): { "on_craft", &on_craft }, { "on_use_special", &on_use_special }, { "on_get_special_recharge_cost", &on_get_special_recharge_cost }, + { "on_mapvar_changed", &on_mapvar_changed }, + { "on_worldvar_changed", &on_worldvar_changed }, { "get_item_class", &get_item_class }, { "get_monster_class", &get_monster_class }, { "get_status_effect", &get_status_effect }, diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp index dfa64d0f..e45588b9 100644 --- a/src/scripting/luascript.cpp +++ b/src/scripting/luascript.cpp @@ -118,10 +118,11 @@ void LuaScript::push(const std::list<InventoryItem> &itemList) int LuaScript::execute() { assert(nbArgs >= 0); - assert(!mCurrentThread); - int res = lua_pcall(mCurrentState, nbArgs, 1, 1); + + const int tmpNbArgs = nbArgs; nbArgs = -1; + int res = lua_pcall(mCurrentState, tmpNbArgs, 1, 1); if (res || !(lua_isnil(mCurrentState, -1) || lua_isnumber(mCurrentState, -1))) { @@ -144,8 +145,9 @@ bool LuaScript::resume() assert(mCurrentThread); setMap(mCurrentThread->mMap); - int result = lua_resume(mCurrentState, nbArgs); + const int tmpNbArgs = nbArgs; nbArgs = -1; + int result = lua_resume(mCurrentState, tmpNbArgs); setMap(0); if (result == 0) // Thread is done |