diff options
author | Perttu Ahola <celeron55@gmail.com> | 2011-11-17 11:22:24 +0200 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2011-11-29 19:13:49 +0200 |
commit | cc03718d3c492a401bbc4b071d0ae1f0c808de95 (patch) | |
tree | d3b701f5ab5ca0b2d94a22a0c49eeeb0ba98fb51 | |
parent | d7cb6146c8ddbd3e1c03c9743e32d7d4e86ec78e (diff) | |
download | minetest-cc03718d3c492a401bbc4b071d0ae1f0c808de95.tar.gz minetest-cc03718d3c492a401bbc4b071d0ae1f0c808de95.tar.bz2 minetest-cc03718d3c492a401bbc4b071d0ae1f0c808de95.zip |
Node place/dig Lua callbacks
-rw-r--r-- | data/mods/default/init.lua | 23 | ||||
-rw-r--r-- | src/mapnode.h | 24 | ||||
-rw-r--r-- | src/scriptapi.cpp | 218 | ||||
-rw-r--r-- | src/scriptapi.h | 6 | ||||
-rw-r--r-- | src/server.cpp | 15 |
5 files changed, 255 insertions, 31 deletions
diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua index 5f8eeadee..966b807ae 100644 --- a/data/mods/default/init.lua +++ b/data/mods/default/init.lua @@ -78,7 +78,12 @@ end -- -- Global functions: -- minetest.register_entity(name, prototype_table) +-- minetest.register_tool(name, {lots of stuff}) +-- minetest.register_node(name, {lots of stuff}) +-- minetest.register_craft({output=item, recipe={...}) -- minetest.register_globalstep(func) +-- minetest.register_on_placenode(func) +-- minetest.register_on_dignode(func) -- -- Global objects: -- minetest.env - environment reference @@ -91,9 +96,12 @@ end -- minetest.luaentities -- ^ List of lua entities, indexed by active object id -- +-- EnvRef is basically ServerEnvironment and ServerMap combined. -- EnvRef methods: -- - add_node(pos, content); pos={x=num, y=num, z=num} +-- TODO: content -> MapNode as described below -- +-- ObjectRef is basically ServerActiveObject. -- ObjectRef methods: -- - remove(): remove object (after returning from Lua) -- - getpos(): returns {x=num, y=num, z=num} @@ -106,6 +114,9 @@ end -- - It has the member .object, which is an ObjectRef pointing to the object -- - The original prototype stuff is visible directly via a metatable -- +-- MapNode representation: +-- {name="name", param1=num, param2=num} +-- print("omg lol") print("minetest dump: "..dump(minetest)) @@ -117,6 +128,18 @@ end minetest.register_globalstep(on_step) +function on_placenode(p, node) + print("on_placenode") +end + +minetest.register_on_placenode(on_placenode) + +function on_dignode(p, node) + print("on_dignode") +end + +minetest.register_on_dignode(on_dignode) + minetest.register_tool("WPick", { image = "tool_woodpick.png", basetime = 2.0, diff --git a/src/mapnode.h b/src/mapnode.h index e287ea54f..65fc3b3e2 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -183,6 +183,30 @@ struct MapNode param2 |= (c&0x0f)<<4; } } + u8 getParam1() const + { + return param1; + } + void setParam1(u8 p) + { + param1 = p; + } + u8 getParam2() const + { + if(param0 < 0x80) + return param2; + else + return param2 & 0x0f; + } + void setParam2(u8 p) + { + if(param0 < 0x80) + param2 = p; + else{ + param2 &= 0xf0; + param2 |= (p&0x0f); + } + } void setLight(enum LightBank bank, u8 a_light, INodeDefManager *nodemgr); u8 getLight(enum LightBank bank, INodeDefManager *nodemgr) const; diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index cd501060f..c9356fe4f 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -123,7 +123,7 @@ public: } }; -v3f readFloatPos(lua_State *L, int index) +static v3f readFloatPos(lua_State *L, int index) { v3f pos; lua_pushvalue(L, index); // Push pos @@ -142,6 +142,42 @@ v3f readFloatPos(lua_State *L, int index) return pos; } +static void pushpos(lua_State *L, v3s16 p) +{ + lua_newtable(L); + lua_pushnumber(L, p.X); + lua_setfield(L, -2, "x"); + lua_pushnumber(L, p.Y); + lua_setfield(L, -2, "y"); + lua_pushnumber(L, p.Z); + lua_setfield(L, -2, "z"); +} + +static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef) +{ + lua_newtable(L); + lua_pushstring(L, ndef->get(n).name.c_str()); + lua_setfield(L, -2, "name"); + lua_pushnumber(L, n.getParam1()); + lua_setfield(L, -2, "param1"); + lua_pushnumber(L, n.getParam2()); + lua_setfield(L, -2, "param2"); +} + +static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef) +{ + lua_getfield(L, index, "name"); + const char *name = lua_tostring(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "param1"); + u8 param1 = lua_tonumber(L, -1); + lua_pop(L, 1); + lua_getfield(L, index, "param2"); + u8 param2 = lua_tonumber(L, -1); + lua_pop(L, 1); + return MapNode(ndef, name, param1, param2); +} + /* Global functions */ @@ -180,32 +216,6 @@ static int l_register_entity(lua_State *L) return 0; /* number of results */ } -// Register a global step function -// register_globalstep(function) -static int l_register_globalstep(lua_State *L) -{ - luaL_checktype(L, 1, LUA_TFUNCTION); - infostream<<"register_globalstep"<<std::endl; - - lua_getglobal(L, "table"); - lua_getfield(L, -1, "insert"); - int table_insert = lua_gettop(L); - // Get minetest.registered_globalsteps - lua_getglobal(L, "minetest"); - lua_getfield(L, -1, "registered_globalsteps"); - luaL_checktype(L, -1, LUA_TTABLE); - int registered_globalsteps = lua_gettop(L); - // table.insert(registered_globalsteps, func) - lua_pushvalue(L, table_insert); - lua_pushvalue(L, registered_globalsteps); - lua_pushvalue(L, 1); // push function from argument 1 - // Call insert - if(lua_pcall(L, 2, 0, 0)) - script_error(L, "error: %s\n", lua_tostring(L, -1)); - - return 0; /* number of results */ -} - // register_tool(name, {lots of stuff}) static int l_register_tool(lua_State *L) { @@ -395,12 +405,90 @@ static int l_register_craft(lua_State *L) return 0; /* number of results */ } +// Register a global step function +// register_globalstep(function) +static int l_register_globalstep(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TFUNCTION); + infostream<<"register_globalstep"<<std::endl; + + lua_getglobal(L, "table"); + lua_getfield(L, -1, "insert"); + int table_insert = lua_gettop(L); + // Get minetest.registered_globalsteps + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_globalsteps"); + luaL_checktype(L, -1, LUA_TTABLE); + int registered_globalsteps = lua_gettop(L); + // table.insert(registered_globalsteps, func) + lua_pushvalue(L, table_insert); + lua_pushvalue(L, registered_globalsteps); + lua_pushvalue(L, 1); // push function from argument 1 + // Call insert + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s\n", lua_tostring(L, -1)); + + return 0; /* number of results */ +} + +// register_on_placenode(function) +static int l_register_on_placenode(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TFUNCTION); + infostream<<"register_on_placenode"<<std::endl; + + lua_getglobal(L, "table"); + lua_getfield(L, -1, "insert"); + int table_insert = lua_gettop(L); + // Get minetest.registered_on_placenodes + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_placenodes"); + luaL_checktype(L, -1, LUA_TTABLE); + int registered_on_placenodes = lua_gettop(L); + // table.insert(registered_on_placenodes, func) + lua_pushvalue(L, table_insert); + lua_pushvalue(L, registered_on_placenodes); + lua_pushvalue(L, 1); // push function from argument 1 + // Call insert + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s\n", lua_tostring(L, -1)); + + return 0; /* number of results */ +} + +// register_on_dignode(function) +static int l_register_on_dignode(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TFUNCTION); + infostream<<"register_on_dignode"<<std::endl; + + lua_getglobal(L, "table"); + lua_getfield(L, -1, "insert"); + int table_insert = lua_gettop(L); + // Get minetest.registered_on_dignodes + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_dignodes"); + luaL_checktype(L, -1, LUA_TTABLE); + int registered_on_dignodes = lua_gettop(L); + // table.insert(registered_on_dignodes, func) + lua_pushvalue(L, table_insert); + lua_pushvalue(L, registered_on_dignodes); + lua_pushvalue(L, 1); // push function from argument 1 + // Call insert + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s\n", lua_tostring(L, -1)); + + return 0; /* number of results */ +} + static const struct luaL_Reg minetest_f [] = { {"register_entity", l_register_entity}, - {"register_globalstep", l_register_globalstep}, {"register_tool", l_register_tool}, {"register_node", l_register_node}, {"register_craft", l_register_craft}, + {"register_globalstep", l_register_globalstep}, + {"register_on_placenode", l_register_on_placenode}, + {"register_on_dignode", l_register_on_dignode}, {NULL, NULL} }; @@ -808,6 +896,12 @@ void scriptapi_export(lua_State *L, Server *server) lua_setfield(L, -2, "registered_globalsteps"); lua_newtable(L); + lua_setfield(L, -2, "registered_on_placenodes"); + + lua_newtable(L); + lua_setfield(L, -2, "registered_on_dignodes"); + + lua_newtable(L); lua_setfield(L, -2, "object_refs"); lua_newtable(L); @@ -922,7 +1016,7 @@ void scriptapi_environment_step(lua_State *L, float dtime) { realitycheck(L); assert(lua_checkstack(L, 20)); - //infostream<<"scriptapi_luaentity_step: id="<<id<<std::endl; + //infostream<<"scriptapi_environment_step"<<std::endl; StackUnroller stack_unroller(L); // Get minetest.registered_globalsteps @@ -943,6 +1037,72 @@ void scriptapi_environment_step(lua_State *L, float dtime) } } +void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode) +{ + realitycheck(L); + assert(lua_checkstack(L, 20)); + //infostream<<"scriptapi_environment_on_placenode"<<std::endl; + StackUnroller stack_unroller(L); + + // Get server from registry + lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server"); + Server *server = (Server*)lua_touserdata(L, -1); + // And get the writable node definition manager from the server + IWritableNodeDefManager *ndef = + server->getWritableNodeDefManager(); + + // Get minetest.registered_on_placenodes + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_placenodes"); + luaL_checktype(L, -1, LUA_TTABLE); + int table = lua_gettop(L); + // Foreach + lua_pushnil(L); + while(lua_next(L, table) != 0){ + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TFUNCTION); + // Call function + pushpos(L, p); + pushnode(L, newnode, ndef); + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s\n", lua_tostring(L, -1)); + // value removed, keep key for next iteration + } +} + +void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode) +{ + realitycheck(L); + assert(lua_checkstack(L, 20)); + //infostream<<"scriptapi_environment_on_dignode"<<std::endl; + StackUnroller stack_unroller(L); + + // Get server from registry + lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server"); + Server *server = (Server*)lua_touserdata(L, -1); + // And get the writable node definition manager from the server + IWritableNodeDefManager *ndef = + server->getWritableNodeDefManager(); + + // Get minetest.registered_on_dignodes + lua_getglobal(L, "minetest"); + lua_getfield(L, -1, "registered_on_dignodes"); + luaL_checktype(L, -1, LUA_TTABLE); + int table = lua_gettop(L); + // Foreach + lua_pushnil(L); + while(lua_next(L, table) != 0){ + // key at index -2 and value at index -1 + luaL_checktype(L, -1, LUA_TFUNCTION); + // Call function + pushpos(L, p); + pushnode(L, oldnode, ndef); + if(lua_pcall(L, 2, 0, 0)) + script_error(L, "error: %s\n", lua_tostring(L, -1)); + // value removed, keep key for next iteration + } +} + /* luaentity */ diff --git a/src/scriptapi.h b/src/scriptapi.h index ecd3d7b81..e7ff84039 100644 --- a/src/scriptapi.h +++ b/src/scriptapi.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes.h" #include <string> +#include "mapnode.h" class Server; class ServerEnvironment; @@ -37,7 +38,12 @@ void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj); void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj); /* environment */ +// On environment step void scriptapi_environment_step(lua_State *L, float dtime); +// After adding node +void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode); +// After removing node +void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode); /* luaentity */ // Returns true if succesfully added into Lua; false otherwise. diff --git a/src/server.cpp b/src/server.cpp index 894c3d362..467153031 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2527,10 +2527,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) u8 mineral = MINERAL_NONE; bool cannot_remove_node = false; - + + MapNode n(CONTENT_IGNORE); try { - MapNode n = m_env->getMap().getNode(p_under); + n = m_env->getMap().getNode(p_under); // Get mineral mineral = n.getMineral(m_nodedef); // Get material at position @@ -2734,6 +2735,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) continue; client->SetBlocksNotSent(modified_blocks); } + + /* + Run script hook + */ + scriptapi_environment_on_dignode(m_lua, p_under, n); } /* @@ -2878,6 +2884,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } /* + Run script hook + */ + scriptapi_environment_on_placenode(m_lua, p_over, n); + + /* Calculate special events */ |