summaryrefslogtreecommitdiff
path: root/src/scripting
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripting')
-rw-r--r--src/scripting/lua.cpp26
-rw-r--r--src/scripting/luascript.cpp20
-rw-r--r--src/scripting/luascript.h4
-rw-r--r--src/scripting/script.cpp2
-rw-r--r--src/scripting/script.h33
-rw-r--r--src/scripting/scriptmanager.cpp13
-rw-r--r--src/scripting/scriptmanager.h5
7 files changed, 81 insertions, 22 deletions
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 9aec6b3f..7a94ce24 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -74,6 +74,30 @@ static Script *getScript(lua_State *s)
/**
+ * mana.on_character_death( function(Character*) ): void
+ * Sets a listener function to the character death event.
+ */
+static int on_character_death(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ Character::setDeathCallback(getScript(s));
+ return 0;
+}
+
+/**
+ * mana.on_character_death_accept( function(Character*) ): void
+ * Sets a listener function that is called when the player clicks on the OK
+ * button after the death message appeared. It should be used to implement the
+ * respawn mechanic.
+ */
+static int on_character_death_accept(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ Character::setDeathAcceptedCallback(getScript(s));
+ return 0;
+}
+
+/**
* mana.npc_message(NPC*, Character*, string): void
* Callback for sending a NPC_MESSAGE.
*/
@@ -2564,6 +2588,8 @@ LuaScript::LuaScript():
// Put the callback functions in the scripting environment.
static luaL_Reg const callbacks[] = {
+ { "on_character_death", &on_character_death },
+ { "on_character_death_accept", &on_character_death_accept },
{ "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 c487aa67..605302e6 100644
--- a/src/scripting/luascript.cpp
+++ b/src/scripting/luascript.cpp
@@ -35,6 +35,15 @@ LuaScript::~LuaScript()
lua_close(mState);
}
+void LuaScript::prepare(Ref function)
+{
+ assert(nbArgs == -1);
+ lua_rawgeti(mState, LUA_REGISTRYINDEX, function);
+ assert(lua_isfunction(mState, -1));
+ nbArgs = 0;
+ mCurFunction = "<callback>"; // We don't know the function name
+}
+
void LuaScript::prepare(const std::string &name)
{
assert(nbArgs == -1);
@@ -108,6 +117,17 @@ int LuaScript::execute()
mCurFunction.clear();
}
+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);
+
+ function = luaL_ref(mState, LUA_REGISTRYINDEX);
+}
+
void LuaScript::load(const char *prog, const char *name)
{
int res = luaL_loadbuffer(mState, prog, std::strlen(prog), name);
diff --git a/src/scripting/luascript.h b/src/scripting/luascript.h
index 0d59703c..6f2bceee 100644
--- a/src/scripting/luascript.h
+++ b/src/scripting/luascript.h
@@ -44,6 +44,8 @@ class LuaScript : public Script
void load(const char *prog, const char *name);
+ void prepare(Ref function);
+
void prepare(const std::string &);
void push(int);
@@ -56,6 +58,8 @@ class LuaScript : public Script
int execute();
+ void assignCallback(Ref &function);
+
static void getQuestCallback(Character *, const std::string &,
const std::string &, void *);
diff --git a/src/scripting/script.cpp b/src/scripting/script.cpp
index db44bd57..66720842 100644
--- a/src/scripting/script.cpp
+++ b/src/scripting/script.cpp
@@ -34,6 +34,8 @@ 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 bd143114..b475a0f0 100644
--- a/src/scripting/script.h
+++ b/src/scripting/script.h
@@ -21,11 +21,12 @@
#ifndef SCRIPTING_SCRIPT_H
#define SCRIPTING_SCRIPT_H
-#include <string>
-
-#include "game-server/character.h"
+#include "common/inventorydata.h"
#include "game-server/eventlistener.h"
+#include <list>
+#include <string>
+
class MapComposite;
class Thing;
@@ -35,7 +36,9 @@ class Thing;
class Script
{
public:
-
+ /**
+ * Defines a function that creates a Script instance.
+ */
typedef Script *(*Factory)();
/**
@@ -48,6 +51,15 @@ 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;
+
Script();
virtual ~Script() {}
@@ -81,6 +93,12 @@ class Script
virtual void update();
/**
+ * Prepares a call to the referenced function.
+ * Only one function can be prepared at once.
+ */
+ virtual void prepare(Ref function) = 0;
+
+ /**
* Prepares a call to the given function.
* Only one function can be prepared at once.
*/
@@ -117,6 +135,13 @@ class Script
virtual int execute() = 0;
/**
+ * Assigns the current callback to the given \a function.
+ *
+ * Where the callback exactly comes from is up to the script engine.
+ */
+ virtual void assignCallback(Ref &function) = 0;
+
+ /**
* Sets associated map.
*/
void setMap(MapComposite *m)
diff --git a/src/scripting/scriptmanager.cpp b/src/scripting/scriptmanager.cpp
index 52515699..d58379f6 100644
--- a/src/scripting/scriptmanager.cpp
+++ b/src/scripting/scriptmanager.cpp
@@ -49,19 +49,6 @@ Script *ScriptManager::currentState()
// TODO: Have some generic event mechanism rather than calling global functions
-bool ScriptManager::executeGlobalEventFunction(const std::string &function, Being* obj)
-{
- bool isScriptHandled = false;
- _currentState->setMap(obj->getMap());
- _currentState->prepare(function);
- _currentState->push(obj);
- _currentState->execute();
- _currentState->setMap(NULL);
- isScriptHandled = true; // TODO: don't set to true when execution failed
- return isScriptHandled;
-}
-
-
void ScriptManager::addDataToSpecial(int id, Special *special)
{
/* currently only gets the recharge cost.
diff --git a/src/scripting/scriptmanager.h b/src/scripting/scriptmanager.h
index 7560c343..ade76c19 100644
--- a/src/scripting/scriptmanager.h
+++ b/src/scripting/scriptmanager.h
@@ -56,11 +56,6 @@ bool loadMainScript(const std::string &file);
*/
Script *currentState();
-
-/**
- * Runs a global function from the global event script file
- */
-bool executeGlobalEventFunction(const std::string &function, Being *obj);
void addDataToSpecial(int specialId, Special *special);
bool performSpecialAction(int specialId, Being *caster);
bool performCraft(Being *crafter, const std::list<InventoryItem> &recipe);