forked from Mirrorlandia_minetest/minetest
Add after_destruct and cache the existence of on_construct, on_destruct and after_destruct for quick skipping when a node does not have them
This commit is contained in:
parent
c3658e7c79
commit
3a0562bebc
@ -1150,15 +1150,18 @@ Node definition (register_node)
|
|||||||
on_destruct = func(pos),
|
on_destruct = func(pos),
|
||||||
^ Node destructor; always called before removing node
|
^ Node destructor; always called before removing node
|
||||||
^ default: nil
|
^ default: nil
|
||||||
|
after_destruct = func(pos, oldnode),
|
||||||
|
^ Node destructor; always called after removing node
|
||||||
|
^ default: nil
|
||||||
|
|
||||||
after_place_node = func(pos, placer),
|
after_place_node = func(pos, placer),
|
||||||
^ Called after constructing node when node was placed using
|
^ Called after constructing node when node was placed using
|
||||||
minetest.item_place_node
|
minetest.item_place_node / minetest.env:place_node
|
||||||
^ default: nil
|
^ default: nil
|
||||||
after_dig_node = func(pos, oldnode, oldmetadata, digger),
|
after_dig_node = func(pos, oldnode, oldmetadata, digger),
|
||||||
^ oldmetadata is in table format
|
^ oldmetadata is in table format
|
||||||
^ Called after destructing node when node was dug using
|
^ Called after destructing node when node was dug using
|
||||||
minetest.node_dig
|
minetest.node_dig / minetest.env:dig_node
|
||||||
^ default: nil
|
^ default: nil
|
||||||
can_dig = function(pos,player)
|
can_dig = function(pos,player)
|
||||||
^ returns true if node can be dug, or false if not
|
^ returns true if node can be dug, or false if not
|
||||||
|
@ -468,6 +468,10 @@ minetest.register_node("experimental:tester_node_1", {
|
|||||||
experimental.print_to_everything("experimental:tester_node_1:on_destruct("..minetest.pos_to_string(pos)..")")
|
experimental.print_to_everything("experimental:tester_node_1:on_destruct("..minetest.pos_to_string(pos)..")")
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
after_destruct = function(pos)
|
||||||
|
experimental.print_to_everything("experimental:tester_node_1:after_destruct("..minetest.pos_to_string(pos)..")")
|
||||||
|
end,
|
||||||
|
|
||||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||||
experimental.print_to_everything("experimental:tester_node_1:after_dig_node("..minetest.pos_to_string(pos)..")")
|
experimental.print_to_everything("experimental:tester_node_1:after_dig_node("..minetest.pos_to_string(pos)..")")
|
||||||
end,
|
end,
|
||||||
|
@ -117,6 +117,9 @@ void ContentFeatures::reset()
|
|||||||
visual_solidness = 0;
|
visual_solidness = 0;
|
||||||
backface_culling = true;
|
backface_culling = true;
|
||||||
#endif
|
#endif
|
||||||
|
has_on_construct = false;
|
||||||
|
has_on_destruct = false;
|
||||||
|
has_after_destruct = false;
|
||||||
/*
|
/*
|
||||||
Actual data
|
Actual data
|
||||||
|
|
||||||
|
@ -144,6 +144,11 @@ struct ContentFeatures
|
|||||||
bool backface_culling;
|
bool backface_culling;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Server-side cached callback existence for fast skipping
|
||||||
|
bool has_on_construct;
|
||||||
|
bool has_on_destruct;
|
||||||
|
bool has_after_destruct;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Actual data
|
Actual data
|
||||||
*/
|
*/
|
||||||
|
@ -994,6 +994,18 @@ static ContentFeatures read_content_features(lua_State *L, int index)
|
|||||||
index = lua_gettop(L) + 1 + index;
|
index = lua_gettop(L) + 1 + index;
|
||||||
|
|
||||||
ContentFeatures f;
|
ContentFeatures f;
|
||||||
|
|
||||||
|
/* Cache existence of some callbacks */
|
||||||
|
lua_getfield(L, index, "on_construct");
|
||||||
|
if(!lua_isnil(L, -1)) f.has_on_construct = true;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_getfield(L, index, "on_destruct");
|
||||||
|
if(!lua_isnil(L, -1)) f.has_on_destruct = true;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_getfield(L, index, "after_destruct");
|
||||||
|
if(!lua_isnil(L, -1)) f.has_after_destruct = true;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
/* Name */
|
/* Name */
|
||||||
getstringfield(L, index, "name", f.name);
|
getstringfield(L, index, "name", f.name);
|
||||||
|
|
||||||
@ -3024,20 +3036,26 @@ private:
|
|||||||
EnvRef *o = checkobject(L, 1);
|
EnvRef *o = checkobject(L, 1);
|
||||||
ServerEnvironment *env = o->m_env;
|
ServerEnvironment *env = o->m_env;
|
||||||
if(env == NULL) return 0;
|
if(env == NULL) return 0;
|
||||||
// pos
|
INodeDefManager *ndef = env->getGameDef()->ndef();
|
||||||
|
// parameters
|
||||||
v3s16 pos = read_v3s16(L, 2);
|
v3s16 pos = read_v3s16(L, 2);
|
||||||
// content
|
MapNode n = readnode(L, 3, ndef);
|
||||||
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
|
|
||||||
// Do it
|
// Do it
|
||||||
// Call destructor
|
|
||||||
MapNode n_old = env->getMap().getNodeNoEx(pos);
|
MapNode n_old = env->getMap().getNodeNoEx(pos);
|
||||||
scriptapi_node_on_destruct(L, pos, n_old);
|
// Call destructor
|
||||||
|
if(ndef->get(n_old).has_on_destruct)
|
||||||
|
scriptapi_node_on_destruct(L, pos, n_old);
|
||||||
// Replace node
|
// Replace node
|
||||||
bool succeeded = env->getMap().addNodeWithEvent(pos, n);
|
bool succeeded = env->getMap().addNodeWithEvent(pos, n);
|
||||||
|
if(succeeded){
|
||||||
|
// Call post-destructor
|
||||||
|
if(ndef->get(n_old).has_after_destruct)
|
||||||
|
scriptapi_node_after_destruct(L, pos, n_old);
|
||||||
|
// Call constructor
|
||||||
|
if(ndef->get(n).has_on_construct)
|
||||||
|
scriptapi_node_on_construct(L, pos, n);
|
||||||
|
}
|
||||||
lua_pushboolean(L, succeeded);
|
lua_pushboolean(L, succeeded);
|
||||||
// Call constructor
|
|
||||||
if(succeeded)
|
|
||||||
scriptapi_node_on_construct(L, pos, n);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3053,14 +3071,22 @@ private:
|
|||||||
EnvRef *o = checkobject(L, 1);
|
EnvRef *o = checkobject(L, 1);
|
||||||
ServerEnvironment *env = o->m_env;
|
ServerEnvironment *env = o->m_env;
|
||||||
if(env == NULL) return 0;
|
if(env == NULL) return 0;
|
||||||
|
INodeDefManager *ndef = env->getGameDef()->ndef();
|
||||||
|
// parameters
|
||||||
v3s16 pos = read_v3s16(L, 2);
|
v3s16 pos = read_v3s16(L, 2);
|
||||||
// Do it
|
// Do it
|
||||||
|
MapNode n_old = env->getMap().getNodeNoEx(pos);
|
||||||
// Call destructor
|
// Call destructor
|
||||||
MapNode n = env->getMap().getNodeNoEx(pos);
|
if(ndef->get(n_old).has_on_destruct)
|
||||||
scriptapi_node_on_destruct(L, pos, n);
|
scriptapi_node_on_destruct(L, pos, n_old);
|
||||||
// Replace with air
|
// Replace with air
|
||||||
// This is slightly optimized compared to addNodeWithEvent(air)
|
// This is slightly optimized compared to addNodeWithEvent(air)
|
||||||
bool succeeded = env->getMap().removeNodeWithEvent(pos);
|
bool succeeded = env->getMap().removeNodeWithEvent(pos);
|
||||||
|
if(succeeded){
|
||||||
|
// Call post-destructor
|
||||||
|
if(ndef->get(n_old).has_after_destruct)
|
||||||
|
scriptapi_node_after_destruct(L, pos, n_old);
|
||||||
|
}
|
||||||
lua_pushboolean(L, succeeded);
|
lua_pushboolean(L, succeeded);
|
||||||
// Air doesn't require constructor
|
// Air doesn't require constructor
|
||||||
return 1;
|
return 1;
|
||||||
@ -5143,6 +5169,25 @@ void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node)
|
|||||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node)
|
||||||
|
{
|
||||||
|
realitycheck(L);
|
||||||
|
assert(lua_checkstack(L, 20));
|
||||||
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
|
INodeDefManager *ndef = get_server(L)->ndef();
|
||||||
|
|
||||||
|
// Push callback function on stack
|
||||||
|
if(!get_item_callback(L, ndef->get(node).name.c_str(), "after_destruct"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Call function
|
||||||
|
push_v3s16(L, p);
|
||||||
|
pushnode(L, node, ndef);
|
||||||
|
if(lua_pcall(L, 2, 0, 0))
|
||||||
|
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||||
|
}
|
||||||
|
|
||||||
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
||||||
const std::string &formname,
|
const std::string &formname,
|
||||||
const std::map<std::string, std::string> &fields,
|
const std::map<std::string, std::string> &fields,
|
||||||
|
@ -86,6 +86,8 @@ bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node,
|
|||||||
void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node);
|
void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node);
|
||||||
// Node destructor
|
// Node destructor
|
||||||
void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node);
|
void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node);
|
||||||
|
// Node post-destructor
|
||||||
|
void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node);
|
||||||
// Called when a metadata form returns values
|
// Called when a metadata form returns values
|
||||||
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
||||||
const std::string &formname,
|
const std::string &formname,
|
||||||
|
Loading…
Reference in New Issue
Block a user