Node place/dig Lua callbacks

This commit is contained in:
Perttu Ahola 2011-11-17 11:22:24 +02:00
parent d7cb6146c8
commit cc03718d3c
5 changed files with 255 additions and 31 deletions

@ -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,

@ -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;

@ -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}
};
@ -807,6 +895,12 @@ void scriptapi_export(lua_State *L, Server *server)
lua_newtable(L);
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");
@ -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
*/

@ -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.

@ -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);
}
/*
@ -2877,6 +2883,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
client->SetBlocksNotSent(modified_blocks);
}
/*
Run script hook
*/
scriptapi_environment_on_placenode(m_lua, p_over, n);
/*
Calculate special events
*/