summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2012-03-10 23:31:32 +0100
committerErik Schilling <ablu.erikschilling@googlemail.com>2012-03-11 10:16:35 +0100
commit520705579d6a68cf6908275026eef2edee0758af (patch)
tree2d37eb5e28a1f6d95bac4094a613f054c08c55b2 /src
parent78c912fb4007c3e5f0b43de02646772acb21ecf2 (diff)
downloadmanaserv-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.cpp35
-rw-r--r--src/game-server/mapcomposite.h19
-rw-r--r--src/game-server/state.cpp17
-rw-r--r--src/game-server/state.h6
-rw-r--r--src/scripting/lua.cpp22
-rw-r--r--src/scripting/luascript.cpp8
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