diff options
-rw-r--r-- | data/test.lua | 9 | ||||
-rw-r--r-- | src/game-server/testing.cpp | 21 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 53 | ||||
-rw-r--r-- | src/scripting/script.hpp | 18 |
4 files changed, 75 insertions, 26 deletions
diff --git a/data/test.lua b/data/test.lua index 2c756165..109e3dc3 100644 --- a/data/test.lua +++ b/data/test.lua @@ -1,24 +1,23 @@ +function initialize() + tmw.obj_create_npc(110, 50 * 32 + 16, 19 * 32 + 16) +end + function npc_start(npc, ch) tmw.msg_npc_message(npc, ch, "What do you want?") - return 0 end function npc_next(npc, ch) tmw.msg_npc_choice(npc, ch, "Guns! Lots of guns!:Nothing") - return 0 end function npc_choose(npc, ch, v) if v == 1 then tmw.msg_npc_message(npc, ch, "Sorry, this is a heroic-fantasy game, I do not have any gun.") end - return 0 end function npc_update(npc) - return 0 end function update() - return 0 end diff --git a/src/game-server/testing.cpp b/src/game-server/testing.cpp index 19156203..d08f2ee6 100644 --- a/src/game-server/testing.cpp +++ b/src/game-server/testing.cpp @@ -10,18 +10,10 @@ #include "game-server/itemmanager.hpp" #include "game-server/mapcomposite.hpp" #include "game-server/mapmanager.hpp" -#include "game-server/npc.hpp" #include "game-server/state.hpp" #include "net/messageout.hpp" #include "scripting/script.hpp" -// For testing purpose only, the NPC class is not meant to be inherited!! -struct DummyNPC: NPC -{ - DummyNPC(): NPC(110, Script::create("lua", "test.lua")) - {} -}; - static void dropItem(MapComposite *map, int x, int y, int type) { ItemClass *ic = ItemManager::getItem(type); @@ -43,11 +35,14 @@ void testingMap(MapComposite *map) dropItem(map, 58 * 32 + 16, 20 * 32 + 16, 508); dropItem(map, 58 * 32 + 16, 21 * 32 + 16, 524); - // Add an NPC - NPC *q = new DummyNPC; - q->setMap(map); - q->setPosition(Point(50 * 32 + 16, 19 * 32 + 16)); - GameState::insert(q); + // Associate a script + Script *s = Script::create("lua", "test.lua"); + if (s) + { + s->setMap(map); + s->prepare("initialize"); + s->execute(); + } } break; } } diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index f9575b68..9cac37d0 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -33,6 +33,7 @@ extern "C" { #include "game-server/character.hpp" #include "game-server/gamehandler.hpp" #include "game-server/npc.hpp" +#include "game-server/state.hpp" #include "net/messageout.hpp" #include "scripting/script.hpp" #include "utils/logger.h" @@ -62,6 +63,8 @@ class LuaScript: public Script int nbArgs; }; +static char const registryKey = 0; + /* Functions below are unsafe, as they assume the script has passed pointers to objects which have not yet been destroyed. If the script never keeps pointers around, there will be no problem. In order to be safe, the engine @@ -128,6 +131,34 @@ static int LuaMsg_NpcChoice(lua_State *s) return 0; } +/** + * Callback for creating a NPC on the current map with the current script + * (1: int) (2: int) (3: int). + */ +static int LuaObj_CreateNpc(lua_State *s) +{ + if (!lua_isnumber(s, 1) || !lua_isnumber(s, 2) || !lua_isnumber(s, 3)) + { + LOG_WARN("LuaObj_CreateNpc called with incorrect parameters."); + return 0; + } + lua_pushlightuserdata(s, (void *)®istryKey); + lua_gettable(s, LUA_REGISTRYINDEX); + Script *t = static_cast<Script *>(lua_touserdata(s, -1)); + NPC *q = new NPC(lua_tointeger(s, 1), t); + MapComposite *m = t->getMap(); + if (!m) + { + LOG_WARN("LuaObj_CreateNpc called outside a map."); + return 0; + } + q->setMap(m); + q->setPosition(Point(lua_tointeger(s, 2), lua_tointeger(s, 3))); + GameState::insert(q); + lua_pushlightuserdata(s, q); + return 1; +} + LuaScript::LuaScript(lua_State *s): mState(s), nbArgs(-1) @@ -138,18 +169,26 @@ LuaScript::LuaScript(lua_State *s): if (res) { LOG_ERROR("Failure while initializing Lua script: " - << lua_tostring(mState, 1)); - lua_pop(mState, 1); + << lua_tostring(mState, -1)); + lua_settop(s, 0); return; } + // Put some callback functions in the scripting environment. static luaL_reg const callbacks[] = { - { "msg_npc_message", &LuaMsg_NpcMessage }, - { "msg_npc_choice", &LuaMsg_NpcChoice }, + { "msg_npc_message", &LuaMsg_NpcMessage }, + { "msg_npc_choice", &LuaMsg_NpcChoice }, + { "obj_create_npc", &LuaObj_CreateNpc }, { NULL, NULL } }; luaL_register(mState, "tmw", callbacks); - lua_pop(mState, 1); + + // Make script object available to callback functions. + lua_pushlightuserdata(mState, (void *)®istryKey); + lua_pushlightuserdata(mState, this); + lua_settable(mState, LUA_REGISTRYINDEX); + + lua_settop(s, 0); } LuaScript::~LuaScript() @@ -183,7 +222,7 @@ int LuaScript::execute() assert(nbArgs >= 0); int res = lua_pcall(mState, nbArgs, 1, 0); nbArgs = -1; - if (res || !lua_isnumber(mState, 1)) + if (res || !(lua_isnil(mState, 1) || lua_isnumber(mState, 1))) { char const *s = lua_tostring(mState, 1); LOG_WARN("Failure while calling Lua function: error=" << res @@ -228,5 +267,3 @@ struct LuaRegister }; static LuaRegister dummy; - - diff --git a/src/scripting/script.hpp b/src/scripting/script.hpp index 5862e50c..8ab89c25 100644 --- a/src/scripting/script.hpp +++ b/src/scripting/script.hpp @@ -26,6 +26,7 @@ #include <string> +class MapComposite; class Thing; /** @@ -47,6 +48,8 @@ class Script */ static Script *create(std::string const &engine, std::string const &file); + Script(): mMap(NULL) {} + virtual ~Script() {} /** @@ -79,6 +82,21 @@ class Script * @return the value returned by the script. */ virtual int execute() = 0; + + /** + * Sets associated map. + */ + void setMap(MapComposite *m) + { mMap = m; } + + /** + * Gets associated map. + */ + MapComposite *getMap() const + { return mMap; } + + private: + MapComposite *mMap; }; #endif |