aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-11-21 11:15:15 +0200
committerPerttu Ahola <celeron55@gmail.com>2011-11-29 19:13:49 +0200
commit0ce0c8fcfba655c8db5f53ce8e3ab7adfa59768a (patch)
tree7491e7b68e0cd4c43a19de54b7352d4d9e0de778
parent811ac5ac3ae6de6ee152f724aaf392ac73c3ed40 (diff)
downloadminetest-0ce0c8fcfba655c8db5f53ce8e3ab7adfa59768a.tar.gz
minetest-0ce0c8fcfba655c8db5f53ce8e3ab7adfa59768a.tar.bz2
minetest-0ce0c8fcfba655c8db5f53ce8e3ab7adfa59768a.zip
Improve LuaEntity velocity/acceleration handling (by kahrl); implement staticdata interface to Lua
-rw-r--r--data/mods/default/init.lua50
-rw-r--r--src/content_cao.cpp9
-rw-r--r--src/content_cao.h2
-rw-r--r--src/content_sao.cpp24
-rw-r--r--src/content_sao.h4
-rw-r--r--src/scriptapi.cpp192
-rw-r--r--src/scriptapi.h6
-rw-r--r--src/server.cpp26
8 files changed, 234 insertions, 79 deletions
diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua
index 949816c9e..a8a1d08f4 100644
--- a/data/mods/default/init.lua
+++ b/data/mods/default/init.lua
@@ -101,6 +101,7 @@ end
-- - add_node(pos, node)
-- - remove_node(pos)
-- - get_node(pos)
+-- - add_luaentity(pos, name)
--
-- ObjectRef is basically ServerActiveObject.
-- ObjectRef methods:
@@ -114,6 +115,12 @@ end
-- - Functions receive a "luaentity" as self:
-- - It has the member .object, which is an ObjectRef pointing to the object
-- - The original prototype stuff is visible directly via a metatable
+-- - Callbacks:
+-- - on_activate(self, staticdata)
+-- - on_step(self, dtime)
+-- - on_punch(self, hitter)
+-- - on_rightclick(self, clicker)
+-- - get_staticdata(self): return string
--
-- MapNode representation:
-- {name="name", param1=num, param2=num}
@@ -654,11 +661,20 @@ local TNT = {
--textures = {"mese.png^[forcesingle"},
-- Initial value for our timer
timer = 0,
+ -- Number of punches required to defuse
+ health = 3,
-- List names of state variables, for serializing object state
-- (NOTE: not implemented and implementation will not be like this)
-- state_variables = {"timer"},
}
+-- Called when a TNT object is created
+function TNT:on_activate(staticdata)
+ print("TNT:on_activate()")
+ self.object:setvelocity({x=0, y=1, z=0})
+ self.object:setacceleration({x=0, y=-5, z=0})
+end
+
-- Called periodically
function TNT:on_step(dtime)
--print("TNT:on_step()")
@@ -667,15 +683,18 @@ end
-- Called when object is punched
function TNT:on_punch(hitter)
print("TNT:on_punch()")
- self.object:remove()
- hitter:add_to_inventory("CraftItem testobject1 1")
+ self.health = self.health - 1
+ if self.health <= 0 then
+ self.object:remove()
+ hitter:add_to_inventory("NodeItem TNT 1")
+ end
end
-- Called when object is right-clicked
function TNT:on_rightclick(clicker)
- pos = self.object:getpos()
- pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
- self.object:moveto(pos, false)
+ --pos = self.object:getpos()
+ --pos = {x=pos.x, y=pos.y+0.1, z=pos.z}
+ --self.object:moveto(pos, false)
end
print("TNT dump: "..dump(TNT))
@@ -694,16 +713,13 @@ function register_falling_node(nodename, texture)
visual = "cube",
textures = {texture,texture,texture,texture,texture,texture},
-- State
- fallspeed = 0,
-- Methods
on_step = function(self, dtime)
- -- Apply gravity manually
- self.fallspeed = self.fallspeed + dtime * 5
- fp = self.object:getpos()
- fp.y = fp.y - self.fallspeed * dtime
- self.object:moveto(fp, true)
+ -- Set gravity
+ self.object:setacceleration({x=0, y=-10, z=0})
-- Turn to actual sand when collides to ground or just move
- bcp = {x=fp.x, y=fp.y-0.5, z=fp.z} -- Position of bottom center point
+ pos = self.object:getpos()
+ bcp = {x=pos.x, y=pos.y-0.5, z=pos.z} -- Position of bottom center point
bcn = minetest.env:get_node(bcp)
if bcn.name ~= "air" then
-- Turn to a sand node
@@ -772,6 +788,16 @@ function on_dignode(p, node)
end
minetest.register_on_dignode(on_dignode)
+function on_punchnode(p, node)
+ print("on_punchnode")
+ if node.name == "TNT" then
+ minetest.env:remove_node(p)
+ minetest.env:add_luaentity(p, "TNT")
+ nodeupdate(p)
+ end
+end
+minetest.register_on_punchnode(on_punchnode)
+
--
-- Done, print some random stuff
--
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index ca9e22811..f5ef3fb07 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -1278,6 +1278,8 @@ LuaEntityCAO::LuaEntityCAO(IGameDef *gamedef):
m_meshnode(NULL),
m_spritenode(NULL),
m_position(v3f(0,10*BS,0)),
+ m_velocity(v3f(0,0,0)),
+ m_acceleration(v3f(0,0,0)),
m_yaw(0),
m_prop(new LuaEntityProperties)
{
@@ -1455,6 +1457,9 @@ void LuaEntityCAO::updateNodePos()
void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
{
+ m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
+ m_velocity += dtime * m_acceleration;
+ pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
pos_translator.translate(dtime);
updateNodePos();
}
@@ -1471,6 +1476,10 @@ void LuaEntityCAO::processMessage(const std::string &data)
bool do_interpolate = readU8(is);
// pos
m_position = readV3F1000(is);
+ // velocity
+ m_velocity = readV3F1000(is);
+ // acceleration
+ m_acceleration = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
// is_end_position (for interpolation)
diff --git a/src/content_cao.h b/src/content_cao.h
index 3a3fbbcda..3f6b9d877 100644
--- a/src/content_cao.h
+++ b/src/content_cao.h
@@ -428,6 +428,8 @@ private:
scene::IMeshSceneNode *m_meshnode;
scene::MyBillboardSceneNode *m_spritenode;
v3f m_position;
+ v3f m_velocity;
+ v3f m_acceleration;
float m_yaw;
struct LuaEntityProperties *m_prop;
SmoothTranslator pos_translator;
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index dc112275f..986e3f15f 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -1550,6 +1550,8 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
m_init_state(state),
m_registered(false),
m_prop(new LuaEntityProperties),
+ m_velocity(0,0,0),
+ m_acceleration(0,0,0),
m_yaw(0),
m_last_sent_yaw(0),
m_last_sent_position(0,0,0),
@@ -1610,6 +1612,9 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
{
m_last_sent_position_timer += dtime;
+ m_base_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
+ m_velocity += dtime * m_acceleration;
+
if(m_registered){
lua_State *L = m_env->getLua();
scriptapi_luaentity_step(L, m_id, dtime);
@@ -1618,6 +1623,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
if(send_recommended == false)
return;
+ // TODO: force send when velocity/acceleration changes enough
float minchange = 0.2*BS;
if(m_last_sent_position_timer > 1.0){
minchange = 0.01*BS;
@@ -1659,7 +1665,7 @@ std::string LuaEntitySAO::getStaticData()
// state
if(m_registered){
lua_State *L = m_env->getLua();
- std::string state = scriptapi_luaentity_get_state(L, m_id);
+ std::string state = scriptapi_luaentity_get_staticdata(L, m_id);
os<<serializeLongString(state);
} else {
os<<serializeLongString(m_init_state);
@@ -1709,6 +1715,16 @@ float LuaEntitySAO::getMinimumSavedMovement()
return 0.1 * BS;
}
+void LuaEntitySAO::setVelocity(v3f velocity)
+{
+ m_velocity = velocity;
+}
+
+void LuaEntitySAO::setAcceleration(v3f acceleration)
+{
+ m_acceleration = acceleration;
+}
+
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
{
m_last_sent_move_precision = m_base_position.getDistanceFrom(
@@ -1716,6 +1732,8 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
m_last_sent_position_timer = 0;
m_last_sent_yaw = m_yaw;
m_last_sent_position = m_base_position;
+ //m_last_sent_velocity = m_velocity;
+ //m_last_sent_acceleration = m_acceleration;
float update_interval = m_env->getSendRecommendedInterval();
@@ -1727,6 +1745,10 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
writeU8(os, do_interpolate);
// pos
writeV3F1000(os, m_base_position);
+ // velocity
+ writeV3F1000(os, m_velocity);
+ // acceleration
+ writeV3F1000(os, m_acceleration);
// yaw
writeF1000(os, m_yaw);
// is_end_position (for interpolation)
diff --git a/src/content_sao.h b/src/content_sao.h
index cd7474960..04d33647e 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -216,6 +216,8 @@ public:
void setPos(v3f pos);
void moveTo(v3f pos, bool continuous);
float getMinimumSavedMovement();
+ void setVelocity(v3f velocity);
+ void setAcceleration(v3f acceleration);
private:
void sendPosition(bool do_interpolate, bool is_movement_end);
@@ -224,6 +226,8 @@ private:
bool m_registered;
struct LuaEntityProperties *m_prop;
+ v3f m_velocity;
+ v3f m_acceleration;
float m_yaw;
float m_last_sent_yaw;
v3f m_last_sent_position;
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index a18c144d3..02db2ce02 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -61,6 +61,7 @@ TODO:
meta.set("owner", playername)
meta.get("owner")
- Item definition (actually, only CraftItem)
+- (not scripting) Putting items in node metadata (virtual)
*/
static void stackDump(lua_State *L, std::ostream &o)
@@ -424,24 +425,21 @@ 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)
+static int register_lua_callback(lua_State *L, const char *tablename)
{
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");
+ lua_getfield(L, -1, tablename);
luaL_checktype(L, -1, LUA_TTABLE);
- int registered_globalsteps = lua_gettop(L);
+ int registered = lua_gettop(L);
// table.insert(registered_globalsteps, func)
lua_pushvalue(L, table_insert);
- lua_pushvalue(L, registered_globalsteps);
+ lua_pushvalue(L, registered);
lua_pushvalue(L, 1); // push function from argument 1
// Call insert
if(lua_pcall(L, 2, 0, 0))
@@ -450,54 +448,33 @@ static int l_register_globalstep(lua_State *L)
return 0; /* number of results */
}
+// Register a global step function
+// register_globalstep(function)
+static int l_register_globalstep(lua_State *L)
+{
+ infostream<<"register_globalstep"<<std::endl;
+ return register_lua_callback(L, "registered_globalsteps");
+}
+
// 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 */
+ return register_lua_callback(L, "registered_on_placenodes");
}
// 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;
+ return register_lua_callback(L, "registered_on_dignodes");
+}
- 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 */
+// register_on_punchnode(function)
+static int l_register_on_punchnode(lua_State *L)
+{
+ infostream<<"register_on_punchnode"<<std::endl;
+ return register_lua_callback(L, "registered_on_punchnodes");
}
static const struct luaL_Reg minetest_f [] = {
@@ -508,6 +485,7 @@ static const struct luaL_Reg minetest_f [] = {
{"register_globalstep", l_register_globalstep},
{"register_on_placenode", l_register_on_placenode},
{"register_on_dignode", l_register_on_dignode},
+ {"register_on_punchnode", l_register_on_punchnode},
{NULL, NULL}
};
@@ -583,8 +561,9 @@ private:
// content
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
// Do it
- env->getMap().addNodeWithEvent(pos, n);
- return 0;
+ bool succeeded = env->getMap().addNodeWithEvent(pos, n);
+ lua_pushboolean(L, succeeded);
+ return 1;
}
// EnvRef:remove_node(pos)
@@ -598,8 +577,9 @@ private:
// pos
v3s16 pos = readpos(L, 2);
// Do it
- env->getMap().removeNodeWithEvent(pos);
- return 0;
+ bool succeeded = env->getMap().removeNodeWithEvent(pos);
+ lua_pushboolean(L, succeeded);
+ return 1;
}
// EnvRef:get_node(pos)
@@ -810,6 +790,32 @@ private:
return 0;
}
+ // setvelocity(self, velocity)
+ static int l_setvelocity(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // pos
+ v3f pos = readFloatPos(L, 2);
+ // Do it
+ co->setVelocity(pos);
+ return 0;
+ }
+
+ // setacceleration(self, acceleration)
+ static int l_setacceleration(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // pos
+ v3f pos = readFloatPos(L, 2);
+ // Do it
+ co->setAcceleration(pos);
+ return 0;
+ }
+
// add_to_inventory(self, itemstring)
// returns: true if item was added, false otherwise
static int l_add_to_inventory(lua_State *L)
@@ -902,6 +908,8 @@ const luaL_reg ObjectRef::methods[] = {
method(ObjectRef, getpos),
method(ObjectRef, setpos),
method(ObjectRef, moveto),
+ method(ObjectRef, setvelocity),
+ method(ObjectRef, setacceleration),
method(ObjectRef, add_to_inventory),
{0,0}
};
@@ -958,6 +966,9 @@ void scriptapi_export(lua_State *L, Server *server)
lua_setfield(L, -2, "registered_on_dignodes");
lua_newtable(L);
+ lua_setfield(L, -2, "registered_on_punchnodes");
+
+ lua_newtable(L);
lua_setfield(L, -2, "object_refs");
lua_newtable(L);
@@ -1159,12 +1170,45 @@ void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode)
}
}
+void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode oldnode)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ //infostream<<"scriptapi_environment_on_punchnode"<<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_punchnodes
+ lua_getglobal(L, "minetest");
+ lua_getfield(L, -1, "registered_on_punchnodes");
+ 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
*/
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
- const char *init_state)
+ const std::string &staticdata)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
@@ -1172,8 +1216,6 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
<<name<<"\""<<std::endl;
StackUnroller stack_unroller(L);
- // Create object as a dummy string (TODO: Create properly)
-
// Get minetest.registered_entities[name]
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_entities");
@@ -1213,17 +1255,19 @@ bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
lua_pushvalue(L, object); // Copy object to top of stack
lua_settable(L, -3);
- // This callback doesn't really make sense
- /*// Get on_activate function
+ // Get on_activate function
lua_pushvalue(L, object);
lua_getfield(L, -1, "on_activate");
- luaL_checktype(L, -1, LUA_TFUNCTION);
- lua_pushvalue(L, object); // self
- // Call with 1 arguments, 0 results
- if(lua_pcall(L, 1, 0, 0))
- script_error(L, "error running function %s:on_activate: %s\n",
- name, lua_tostring(L, -1));*/
-
+ if(!lua_isnil(L, -1)){
+ luaL_checktype(L, -1, LUA_TFUNCTION);
+ lua_pushvalue(L, object); // self
+ lua_pushlstring(L, staticdata.c_str(), staticdata.size());
+ // Call with 2 arguments, 0 results
+ if(lua_pcall(L, 2, 0, 0))
+ script_error(L, "error running function %s:on_activate: %s\n",
+ name, lua_tostring(L, -1));
+ }
+
return true;
}
@@ -1247,13 +1291,33 @@ void scriptapi_luaentity_rm(lua_State *L, u16 id)
lua_pop(L, 2); // pop luaentities, minetest
}
-std::string scriptapi_luaentity_get_state(lua_State *L, u16 id)
+std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- infostream<<"scriptapi_luaentity_get_state: id="<<id<<std::endl;
+ infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
+ StackUnroller stack_unroller(L);
+
+ // Get minetest.luaentities[id]
+ luaentity_get(L, id);
+ int object = lua_gettop(L);
+
+ // Get get_staticdata function
+ lua_pushvalue(L, object);
+ lua_getfield(L, -1, "get_staticdata");
+ if(lua_isnil(L, -1))
+ return "";
+
+ luaL_checktype(L, -1, LUA_TFUNCTION);
+ lua_pushvalue(L, object); // self
+ // Call with 1 arguments, 1 results
+ if(lua_pcall(L, 1, 1, 0))
+ script_error(L, "error running function get_staticdata: %s\n",
+ lua_tostring(L, -1));
- return "";
+ size_t len=0;
+ const char *s = lua_tolstring(L, -1, &len);
+ return std::string(s, len);
}
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
@@ -1344,7 +1408,7 @@ void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
lua_pushnumber(L, dtime); // dtime
// Call with 2 arguments, 0 results
if(lua_pcall(L, 2, 0, 0))
- script_error(L, "error running function 'step': %s\n", lua_tostring(L, -1));
+ script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
}
// Calls entity:on_punch(ObjectRef puncher)
diff --git a/src/scriptapi.h b/src/scriptapi.h
index e7ff84039..46bc8233b 100644
--- a/src/scriptapi.h
+++ b/src/scriptapi.h
@@ -44,13 +44,15 @@ void scriptapi_environment_step(lua_State *L, float dtime);
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);
+// When punching node
+void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node);
/* luaentity */
// Returns true if succesfully added into Lua; false otherwise.
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
- const char *init_state);
+ const std::string &staticdata);
void scriptapi_luaentity_rm(lua_State *L, u16 id);
-std::string scriptapi_luaentity_get_state(lua_State *L, u16 id);
+std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id);
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
LuaEntityProperties *prop);
void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime);
diff --git a/src/server.cpp b/src/server.cpp
index 467153031..ad80851dd 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -2501,6 +2501,32 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
NOTE: This can be used in the future to check if
somebody is cheating, by checking the timing.
*/
+ bool cannot_punch_node = false;
+
+ MapNode n(CONTENT_IGNORE);
+
+ try
+ {
+ n = m_env->getMap().getNode(p_under);
+ }
+ catch(InvalidPositionException &e)
+ {
+ infostream<<"Server: Not punching: Node not found."
+ <<" Adding block to emerge queue."
+ <<std::endl;
+ m_emerge_queue.addBlock(peer_id,
+ getNodeBlockPos(p_over), BLOCK_EMERGE_FLAG_FROMDISK);
+ cannot_punch_node = true;
+ }
+
+ if(cannot_punch_node)
+ return;
+
+ /*
+ Run script hook
+ */
+ scriptapi_environment_on_punchnode(m_lua, p_under, n);
+
} // action == 0
/*