aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-11-17 11:22:24 +0200
committerPerttu Ahola <celeron55@gmail.com>2011-11-29 19:13:49 +0200
commitcc03718d3c492a401bbc4b071d0ae1f0c808de95 (patch)
treed3b701f5ab5ca0b2d94a22a0c49eeeb0ba98fb51
parentd7cb6146c8ddbd3e1c03c9743e32d7d4e86ec78e (diff)
downloadminetest-cc03718d3c492a401bbc4b071d0ae1f0c808de95.tar.gz
minetest-cc03718d3c492a401bbc4b071d0ae1f0c808de95.tar.bz2
minetest-cc03718d3c492a401bbc4b071d0ae1f0c808de95.zip
Node place/dig Lua callbacks
-rw-r--r--data/mods/default/init.lua23
-rw-r--r--src/mapnode.h24
-rw-r--r--src/scriptapi.cpp218
-rw-r--r--src/scriptapi.h6
-rw-r--r--src/server.cpp15
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
*/