summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-03-01 21:54:04 +0100
committerThorbjørn Lindeijer <thorbjorn@lindeijer.nl>2012-03-02 22:57:47 +0100
commitc0c208d4c29ff49f940e8a6c54adb26cc4e5eba3 (patch)
tree8de105c5e154912acf354bbe1bbf8509ac44e25a /src
parentba5b55f3eba0aa3898c5fe42de9838b22473c24a (diff)
downloadmanaserv-c0c208d4c29ff49f940e8a6c54adb26cc4e5eba3.tar.gz
manaserv-c0c208d4c29ff49f940e8a6c54adb26cc4e5eba3.tar.bz2
manaserv-c0c208d4c29ff49f940e8a6c54adb26cc4e5eba3.tar.xz
manaserv-c0c208d4c29ff49f940e8a6c54adb26cc4e5eba3.zip
Converted functions called by LuaScript to callbacks
This includes the quest reply, post reply, death notification and remove notification. Also, Script::Ref was changed from a typedef to a small class, automating initialization and making the check for validness clearer. Reviewed-by: Erik Schilling
Diffstat (limited to 'src')
-rw-r--r--src/game-server/character.cpp6
-rw-r--r--src/game-server/postman.h7
-rw-r--r--src/game-server/quest.cpp2
-rw-r--r--src/game-server/quest.h5
-rw-r--r--src/scripting/lua.cpp32
-rw-r--r--src/scripting/luascript.cpp81
-rw-r--r--src/scripting/luascript.h22
-rw-r--r--src/scripting/script.cpp2
-rw-r--r--src/scripting/script.h17
9 files changed, 119 insertions, 55 deletions
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index b5051764..950c6496 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -52,12 +52,12 @@ const float Character::EXPCURVE_FACTOR = 10.0f;
const float Character::LEVEL_SKILL_PRECEDENCE_FACTOR = 0.75f;
const float Character::EXP_LEVEL_FLEXIBILITY = 1.0f;
-Script::Ref Character::mDeathCallback = Script::NoRef;
-Script::Ref Character::mDeathAcceptedCallback = Script::NoRef;
+Script::Ref Character::mDeathCallback;
+Script::Ref Character::mDeathAcceptedCallback;
static bool executeCallback(Script::Ref function, Character *character)
{
- if (function == Script::NoRef)
+ if (!function.isValid())
return false;
Script *script = ScriptManager::currentState();
diff --git a/src/game-server/postman.h b/src/game-server/postman.h
index 82b7a5a7..5669ebef 100644
--- a/src/game-server/postman.h
+++ b/src/game-server/postman.h
@@ -25,12 +25,13 @@
#include <string>
class Character;
+class Script;
struct PostCallback
{
void (*handler)(Character *, const std::string &sender,
- const std::string &letter, void *data);
- void *data;
+ const std::string &letter, Script *script);
+ Script *script;
};
class PostMan
@@ -64,7 +65,7 @@ public:
std::map<Character*, PostCallback>::iterator itr = mCallbacks.find(player);
if (itr != mCallbacks.end())
{
- itr->second.handler(player, sender, letter, itr->second.data);
+ itr->second.handler(player, sender, letter, itr->second.script);
}
}
diff --git a/src/game-server/quest.cpp b/src/game-server/quest.cpp
index e4607c6a..974fc4ce 100644
--- a/src/game-server/quest.cpp
+++ b/src/game-server/quest.cpp
@@ -152,7 +152,7 @@ void recoveredQuestVar(int id, const std::string &name,
for (QuestCallbacks::const_iterator k = j->second.begin(),
k_end = j->second.end(); k != k_end; ++k)
{
- k->handler(ch, name, value, k->data);
+ k->handler(ch, name, value, k->script);
}
variables.erase(j);
diff --git a/src/game-server/quest.h b/src/game-server/quest.h
index 56fa5c2a..86d2be46 100644
--- a/src/game-server/quest.h
+++ b/src/game-server/quest.h
@@ -24,12 +24,13 @@
#include <string>
class Character;
+class Script;
struct QuestCallback
{
void (*handler)(Character *, const std::string &name,
- const std::string &value, void *data);
- void *data;
+ const std::string &value, Script *script);
+ Script *script;
};
/**
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 7a94ce24..33bd9eb9 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -97,6 +97,34 @@ static int on_character_death_accept(lua_State *s)
return 0;
}
+static int on_npc_quest_reply(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ LuaScript::setQuestReplyCallback(getScript(s));
+ return 0;
+}
+
+static int on_npc_post_reply(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ LuaScript::setPostReplyCallback(getScript(s));
+ return 0;
+}
+
+static int on_being_death(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ LuaScript::setDeathNotificationCallback(getScript(s));
+ return 0;
+}
+
+static int on_being_remove(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ LuaScript::setRemoveNotificationCallback(getScript(s));
+ return 0;
+}
+
/**
* mana.npc_message(NPC*, Character*, string): void
* Callback for sending a NPC_MESSAGE.
@@ -2590,6 +2618,10 @@ LuaScript::LuaScript():
static luaL_Reg const callbacks[] = {
{ "on_character_death", &on_character_death },
{ "on_character_death_accept", &on_character_death_accept },
+ { "on_npc_quest_reply", &on_npc_quest_reply },
+ { "on_npc_post_reply", &on_npc_post_reply },
+ { "on_being_death", &on_being_death },
+ { "on_being_remove", &on_being_remove },
{ "npc_create", &npc_create },
{ "npc_message", &npc_message },
{ "npc_choice", &npc_choice },
diff --git a/src/scripting/luascript.cpp b/src/scripting/luascript.cpp
index 605302e6..27361579 100644
--- a/src/scripting/luascript.cpp
+++ b/src/scripting/luascript.cpp
@@ -24,12 +24,17 @@
#include "scripting/luautil.h"
-#include "game-server/being.h"
+#include "game-server/character.h"
#include "utils/logger.h"
#include <cassert>
#include <cstring>
+Script::Ref LuaScript::mQuestReplyCallback;
+Script::Ref LuaScript::mPostReplyCallback;
+Script::Ref LuaScript::mDeathNotificationCallback;
+Script::Ref LuaScript::mRemoveNotificationCallback;
+
LuaScript::~LuaScript()
{
lua_close(mState);
@@ -38,7 +43,8 @@ LuaScript::~LuaScript()
void LuaScript::prepare(Ref function)
{
assert(nbArgs == -1);
- lua_rawgeti(mState, LUA_REGISTRYINDEX, function);
+ assert(function.isValid());
+ lua_rawgeti(mState, LUA_REGISTRYINDEX, function.value);
assert(lua_isfunction(mState, -1));
nbArgs = 0;
mCurFunction = "<callback>"; // We don't know the function name
@@ -122,10 +128,10 @@ void LuaScript::assignCallback(Script::Ref &function)
assert(lua_isfunction(mState, -1));
// If there is already a callback set, replace it
- if (function != NoRef)
- luaL_unref(mState, LUA_REGISTRYINDEX, function);
+ if (function.isValid())
+ luaL_unref(mState, LUA_REGISTRYINDEX, function.value);
- function = luaL_ref(mState, LUA_REGISTRYINDEX);
+ function.value = luaL_ref(mState, LUA_REGISTRYINDEX);
}
void LuaScript::load(const char *prog, const char *name)
@@ -155,20 +161,26 @@ void LuaScript::load(const char *prog, const char *name)
void LuaScript::processDeathEvent(Being *being)
{
- prepare("death_notification");
- push(being);
- //TODO: get and push a list of creatures who contributed to killing the
- // being. This might be very interesting for scripting quests.
- execute();
+ if (mDeathNotificationCallback.isValid())
+ {
+ prepare(mDeathNotificationCallback);
+ push(being);
+ //TODO: get and push a list of creatures who contributed to killing the
+ // being. This might be very interesting for scripting quests.
+ execute();
+ }
}
void LuaScript::processRemoveEvent(Thing *being)
{
- prepare("remove_notification");
- push(being);
- //TODO: get and push a list of creatures who contributed to killing the
- // being. This might be very interesting for scripting quests.
- execute();
+ if (mRemoveNotificationCallback.isValid())
+ {
+ prepare(mRemoveNotificationCallback);
+ push(being);
+ //TODO: get and push a list of creatures who contributed to killing the
+ // being. This might be very interesting for scripting quests.
+ execute();
+ }
being->removeListener(getScriptListener());
}
@@ -177,31 +189,30 @@ void LuaScript::processRemoveEvent(Thing *being)
* Called when the server has recovered the value of a quest variable.
*/
void LuaScript::getQuestCallback(Character *q, const std::string &name,
- const std::string &value, void *data)
+ const std::string &value, Script *script)
{
- LuaScript *s = static_cast< LuaScript * >(data);
- assert(s->nbArgs == -1);
- lua_getglobal(s->mState, "quest_reply");
- lua_pushlightuserdata(s->mState, q);
- lua_pushstring(s->mState, name.c_str());
- lua_pushstring(s->mState, value.c_str());
- s->nbArgs = 3;
- s->execute();
+ if (mQuestReplyCallback.isValid())
+ {
+ script->prepare(mQuestReplyCallback);
+ script->push(q);
+ script->push(name);
+ script->push(value);
+ script->execute();
+ }
}
/**
- * Called when the server has recovered the post for a user
+ * Called when the server has recovered the post for a user.
*/
void LuaScript::getPostCallback(Character *q, const std::string &sender,
- const std::string &letter, void *data)
+ const std::string &letter, Script *script)
{
- // get the script
- LuaScript *s = static_cast<LuaScript*>(data);
- assert(s->nbArgs == -1);
- lua_getglobal(s->mState, "post_reply");
- lua_pushlightuserdata(s->mState, q);
- lua_pushstring(s->mState, sender.c_str());
- lua_pushstring(s->mState, letter.c_str());
- s->nbArgs = 3;
- s->execute();
+ if (mPostReplyCallback.isValid())
+ {
+ script->prepare(mPostReplyCallback);
+ script->push(q);
+ script->push(sender);
+ script->push(letter);
+ script->execute();
+ }
}
diff --git a/src/scripting/luascript.h b/src/scripting/luascript.h
index 6f2bceee..ecd249ae 100644
--- a/src/scripting/luascript.h
+++ b/src/scripting/luascript.h
@@ -61,19 +61,37 @@ class LuaScript : public Script
void assignCallback(Ref &function);
static void getQuestCallback(Character *, const std::string &,
- const std::string &, void *);
+ const std::string &, Script *);
static void getPostCallback(Character *, const std::string &,
- const std::string &, void *);
+ const std::string &, Script *);
void processDeathEvent(Being *thing);
void processRemoveEvent(Thing *thing);
+
+ static void setQuestReplyCallback(Script *script)
+ { script->assignCallback(mQuestReplyCallback); }
+
+ static void setPostReplyCallback(Script *script)
+ { script->assignCallback(mPostReplyCallback); }
+
+ static void setDeathNotificationCallback(Script *script)
+ { script->assignCallback(mDeathNotificationCallback); }
+
+ static void setRemoveNotificationCallback(Script *script)
+ { script->assignCallback(mRemoveNotificationCallback); }
+
private:
lua_State *mState;
int nbArgs;
std::string mCurFunction;
+
+ static Ref mQuestReplyCallback;
+ static Ref mPostReplyCallback;
+ static Ref mDeathNotificationCallback;
+ static Ref mRemoveNotificationCallback;
};
static char const registryKey = 0;
diff --git a/src/scripting/script.cpp b/src/scripting/script.cpp
index 66720842..db44bd57 100644
--- a/src/scripting/script.cpp
+++ b/src/scripting/script.cpp
@@ -34,8 +34,6 @@ typedef std::map< std::string, Script::Factory > Engines;
static Engines *engines = NULL;
-Script::Ref Script::NoRef = -1;
-
Script::Script():
mMap(NULL),
mEventListener(&scriptEventDispatch)
diff --git a/src/scripting/script.h b/src/scripting/script.h
index b475a0f0..9cc50a1c 100644
--- a/src/scripting/script.h
+++ b/src/scripting/script.h
@@ -52,13 +52,16 @@ class Script
static Script *create(const std::string &engine);
/**
- * A reference to a script object. It's just an integer, but the
- * typedef makes the purpose of the variable clear.
- *
- * Variables of this type should be initialized to Script::NoRef.
- */
- typedef int Ref;
- static Ref NoRef;
+ * A reference to a script object. It wraps an integer value, but adds
+ * custom initialization and a definition of valid. It also makes the
+ * purpose clear.
+ */
+ class Ref {
+ public:
+ Ref() : value(-1) {}
+ bool isValid() const { return value != -1; }
+ int value;
+ };
Script();