summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Sehmisch <tmw@crushnet.org>2008-07-07 19:56:02 +0000
committerPhilipp Sehmisch <tmw@crushnet.org>2008-07-07 19:56:02 +0000
commit5996ff324d4123d1b1c6adb1c81eb16dd5e7b466 (patch)
tree92943ff0856aa4ed4accd04d9e870d96cf186a21
parente5d4c719a52d03bfe9bfb4ea2fea0570842985bc (diff)
downloadmanaserv-5996ff324d4123d1b1c6adb1c81eb16dd5e7b466.tar.gz
manaserv-5996ff324d4123d1b1c6adb1c81eb16dd5e7b466.tar.bz2
manaserv-5996ff324d4123d1b1c6adb1c81eb16dd5e7b466.tar.xz
manaserv-5996ff324d4123d1b1c6adb1c81eb16dd5e7b466.zip
Implemented death listener for scripting engine.
-rw-r--r--ChangeLog8
-rw-r--r--data/scripts/libtmw.lua19
-rw-r--r--data/test.lua19
-rw-r--r--src/scripting/lua.cpp41
-rw-r--r--src/scripting/script.cpp5
-rw-r--r--src/scripting/script.hpp23
6 files changed, 108 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 163755cc..f39b9533 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-07-07 Philipp Sehmisch <tmw@crushnet.org>
+
+ * src/scripting/script.cpp, src/scripting/script.hpp, src/scripting/lua.cpp,
+ data/scripts/libtmw.lua: Implemented death listener for scripting engine.
+ * data/test.lua: Made the spider tamer a scorpion tamer (because spiders aren't
+ implemeted and thus make bad test subjects in this case) and used the death
+ listeners to make him complain when the scorpions are killed.
+
2008-07-07 Roderic Morris <roderic@ccs.neu.edu>
* src/chat-server/chathandler.hpp, src/chat-server/chathandler.cpp,
diff --git a/data/scripts/libtmw.lua b/data/scripts/libtmw.lua
index e788a59b..83e3b40b 100644
--- a/data/scripts/libtmw.lua
+++ b/data/scripts/libtmw.lua
@@ -322,6 +322,25 @@ function schedule_every(seconds, funct)
end
+-- DEATH NOTIFICATIONS
+local ondeath_functs = {}
+
+function onDeath(being, funct)
+ if ondeath_functs[being] == nil then
+ ondeath_functs[being] = {}
+ end
+ table.insert(ondeath_functs[being], funct)
+ tmw.noteOnDeath(being)
+end
+
+function deathNotification(being)
+ if type(ondeath_functs[being]) == "table" then
+ for i,funct in pairs(ondeath_functs[being]) do
+ funct()
+ end
+ end
+end
+
-- Below are some convenience methods added to the engine API
diff --git a/data/test.lua b/data/test.lua
index cebabddb..75a903ed 100644
--- a/data/test.lua
+++ b/data/test.lua
@@ -20,7 +20,7 @@ require "data/scripts/npclib"
atinit(function()
create_npc("Test NPC", 200, 50 * TILESIZE + 16, 19 * TILESIZE + 16, npc1_talk, npclib.walkaround_small)
create_npc("Teleporter", 201, 51 * TILESIZE + 16, 25 * TILESIZE + 16, npc4_talk, npclib.walkaround_wide)
- create_npc("Spider Tamer", 126, 45 * TILESIZE + 16, 25 * TILESIZE + 16, npc5_talk, npclib.walkaround_map)
+ create_npc("Scorpion Tamer", 126, 45 * TILESIZE + 16, 25 * TILESIZE + 16, npc5_talk, nil)
create_npc("Guard", 122, 58 * TILESIZE + 16, 15 * TILESIZE + 16, npc6_talk, npc6_update)
create_npc("Fire Demon", 202, 58 * TILESIZE + 16, 35 * TILESIZE + 16, firedemon_talk, firedemon_update)
@@ -115,15 +115,22 @@ function npc4_talk(npc, ch)
end
function npc5_talk(npc, ch)
- do_message(npc, ch, "I am the spider tamer. Do you want me to spawn some spiders?")
+ do_message(npc, ch, "I am the scorpion tamer. Do you want me to spawn some scorpions?")
local answer = do_choice(npc, ch, "Yes", "No");
if answer == 1 then
local x = tmw.posX(npc)
local y = tmw.posY(npc)
- tmw.monster_create(1012, x + TILESIZE, y + TILESIZE)
- tmw.monster_create(112, x - TILESIZE, y + TILESIZE)
- tmw.monster_create(1012, x + TILESIZE, y - TILESIZE)
- tmw.monster_create(1012, x - TILESIZE, y - TILESIZE)
+ m1 = tmw.monster_create(1, x + TILESIZE, y + TILESIZE)
+ m2 = tmw.monster_create(1, x - TILESIZE, y + TILESIZE)
+ m3 = tmw.monster_create(1, x + TILESIZE, y - TILESIZE)
+ m4 = tmw.monster_create(1, x - TILESIZE, y - TILESIZE)
+
+ onDeath(m1, function() tmw.being_say(npc, "NOOO!") end)
+ onDeath(m2, function() tmw.being_say(npc, "Please stop this violence!") end)
+ onDeath(m3, function() tmw.being_say(npc, "Stop slaughtering my scorpions!") end)
+ onDeath(m4, function() tmw.being_say(npc, "Leave my scorpions alone!") end)
+ onDeath(m4, function() tmw.being_say(m4, "AAARGH!") end)
+
end
end
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index ae9ff1b2..5a9364db 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -79,6 +79,8 @@ class LuaScript: public Script
static void getQuestCallback(Character *, std::string const &,
std::string const &, void *);
+ void processDeathEvent(Being* thing);
+
private:
lua_State *mState;
@@ -721,6 +723,33 @@ static int LuaGetBeingsInCircle(lua_State *s)
return 1;
}
+/**
+ * Makes the server call the lua function deathEvent
+ * with the being ID when the being dies.
+ * tmw.noteOnDeath (being)
+ */
+static int LuaNoteOnDeath(lua_State *s)
+{
+ if (!lua_islightuserdata(s, 1) || lua_gettop(s) != 1)
+ {
+ raiseScriptError(s, "lua_noteOnDeath called with incorrect parameters.");
+ return 0;
+ }
+
+ lua_pushlightuserdata(s, (void *)&registryKey);
+ lua_gettable(s, LUA_REGISTRYINDEX);
+ Script *t = static_cast<Script *>(lua_touserdata(s, -1));
+ Being *being = getBeing(s, 1);
+ if (!being)
+ {
+ raiseScriptError(s, "lua_noteOnDeath called for nonexistent being.");
+ return 0;
+ }
+
+ being->addListener(t->getScriptDeathListener());
+ return 0;
+}
+
LuaScript::LuaScript():
nbArgs(-1)
{
@@ -747,6 +776,7 @@ LuaScript::LuaScript():
{ "trigger_create", &LuaTrigger_Create },
{ "chatmessage", &LuaChatmessage },
{ "get_beings_in_circle", &LuaGetBeingsInCircle},
+ { "noteOnDeath", &LuaNoteOnDeath },
{ NULL, NULL }
};
luaL_register(mState, "tmw", callbacks);
@@ -835,6 +865,17 @@ void LuaScript::load(char const *prog)
}
}
+void LuaScript::processDeathEvent(Being *being)
+{
+ prepare("deathNotification");
+ 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(getScriptDeathListener());
+}
+
static Script *LuaFactory()
{
return new LuaScript();
diff --git a/src/scripting/script.cpp b/src/scripting/script.cpp
index 408bf28a..7c6318af 100644
--- a/src/scripting/script.cpp
+++ b/src/scripting/script.cpp
@@ -33,6 +33,11 @@ typedef std::map< std::string, Script::Factory > Engines;
static Engines *engines = NULL;
+Script::Script():
+ mMap(NULL),
+ mEventListener(&scriptDeathEventDispatch)
+{}
+
void Script::registerEngine(std::string const &name, Factory f)
{
if (!engines)
diff --git a/src/scripting/script.hpp b/src/scripting/script.hpp
index 6a101edf..d9a8aca7 100644
--- a/src/scripting/script.hpp
+++ b/src/scripting/script.hpp
@@ -26,6 +26,8 @@
#include <string>
+#include "game-server/eventlistener.hpp"
+
class MapComposite;
class Thing;
@@ -51,7 +53,7 @@ class Script
/**
* Constructor.
*/
- Script(): mMap(NULL) {}
+ Script();
/**
* Destructor.
@@ -124,8 +126,27 @@ class Script
MapComposite *getMap() const
{ return mMap; }
+ EventListener *getScriptDeathListener()
+ { return &mEventListener; }
+
+ virtual void processDeathEvent(Being* thing) = 0;
+
private:
MapComposite *mMap;
+ EventListener mEventListener; /**< Tracking of being deaths. */
+
+ friend struct ScriptDeathEventDispatch;
};
+struct ScriptDeathEventDispatch: EventDispatch
+{
+ ScriptDeathEventDispatch()
+ {
+ typedef EventListenerFactory< Script, &Script::mEventListener > Factory;
+ died = &Factory::create< Being, &Script::processDeathEvent >::function;
+ }
+};
+
+static ScriptDeathEventDispatch scriptDeathEventDispatch;
+
#endif