diff --git a/doc/lua_api.txt b/doc/lua_api.txt index a4d61b2f8..c984d44d3 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -775,18 +775,13 @@ methods: - get_owner() - set_owner(string) Generic node metadata specific: -- set_infotext(infotext) -- get_inventory() -> InvRef -- set_inventory_draw_spec(string) -- set_allow_text_input(bool) -- set_allow_removal(bool) -- set_enforce_owner(bool) -- is_inventory_modified() -- reset_inventory_modified() -- is_text_modified() -- reset_text_modified() - set_string(name, value) - get_string(name) +- set_int(name, value) +- get_int(name) +- set_float(name, value) +- get_float(name) +- get_inventory() -> InvRef ObjectRef: Moving things in the game are generally these (basically reference to a C++ ServerActiveObject) @@ -983,9 +978,13 @@ Item definition (register_node, register_craftitem, register_tool) choppy={times={[3]=0.90}, maxwear=0.05, maxlevel=0} } } - on_drop = func(itemstack, dropper, pos), + on_place = func(itemstack, placer, pointed_thing), + ^ default: minetest.item_place + on_drop = func(itemstack, dropper, pos), + ^ default: minetest.item_drop on_use = func(itemstack, user, pointed_thing), + ^ default: nil ^ Function must return either nil if no item shall be removed from inventory, or an itemstack to replace the original itemstack. eg. itemstack:take_item(); return itemstack @@ -1032,6 +1031,19 @@ Node definition (register_node) dig = , -- "__group" = group-based sound (default) dug = , }, + + on_construct = func(pos), + ^ Node constructor; always called after adding node + ^ Can set up metadata and stuff like that + on_destruct = func(pos), + ^ Node destructor; always called before removing node + + on_punch = func(pos, node, puncher), + ^ default: minetest.node_punch + ^ By default: does nothing + on_dig = func(pos, node, digger), + ^ default: minetest.node_dig + ^ By default: checks privileges, wears out tool and removes node } Recipe: (register_craft) diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index 07f8fda0d..255d37fc2 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -2978,8 +2978,15 @@ private: // content MapNode n = readnode(L, 3, env->getGameDef()->ndef()); // Do it + // Call destructor + MapNode n_old = env->getMap().getNodeNoEx(pos); + scriptapi_node_on_destruct(L, pos, n_old); + // Replace node bool succeeded = env->getMap().addNodeWithEvent(pos, n); lua_pushboolean(L, succeeded); + // Call constructor + if(succeeded) + scriptapi_node_on_construct(L, pos, n); return 1; } @@ -2999,8 +3006,13 @@ private: // pos v3s16 pos = read_v3s16(L, 2); // Do it + // Call destructor + MapNode n = env->getMap().getNodeNoEx(pos); + scriptapi_node_on_destruct(L, pos, n); + // Replace with air bool succeeded = env->getMap().removeNodeWithEvent(pos); lua_pushboolean(L, succeeded); + // Air doesn't require constructor return 1; } @@ -4881,7 +4893,7 @@ bool scriptapi_item_on_use(lua_State *L, ItemStack &item, return true; } -bool scriptapi_node_on_punch(lua_State *L, v3s16 pos, MapNode node, +bool scriptapi_node_on_punch(lua_State *L, v3s16 p, MapNode node, ServerActiveObject *puncher) { realitycheck(L); @@ -4895,7 +4907,7 @@ bool scriptapi_node_on_punch(lua_State *L, v3s16 pos, MapNode node, return false; // Call function - push_v3s16(L, pos); + push_v3s16(L, p); pushnode(L, node, ndef); objectref_get_or_create(L, puncher); if(lua_pcall(L, 3, 0, 0)) @@ -4903,7 +4915,7 @@ bool scriptapi_node_on_punch(lua_State *L, v3s16 pos, MapNode node, return true; } -bool scriptapi_node_on_dig(lua_State *L, v3s16 pos, MapNode node, +bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node, ServerActiveObject *digger) { realitycheck(L); @@ -4917,7 +4929,7 @@ bool scriptapi_node_on_dig(lua_State *L, v3s16 pos, MapNode node, return false; // Call function - push_v3s16(L, pos); + push_v3s16(L, p); pushnode(L, node, ndef); objectref_get_or_create(L, digger); if(lua_pcall(L, 3, 0, 0)) @@ -4925,6 +4937,42 @@ bool scriptapi_node_on_dig(lua_State *L, v3s16 pos, MapNode node, return true; } +void scriptapi_node_on_construct(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(), "on_construct")) + return; + + // Call function + push_v3s16(L, p); + if(lua_pcall(L, 1, 0, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); +} + +void scriptapi_node_on_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(), "on_destruct")) + return; + + // Call function + push_v3s16(L, p); + if(lua_pcall(L, 1, 0, 0)) + script_error(L, "error: %s", lua_tostring(L, -1)); +} + /* environment */ diff --git a/src/scriptapi.h b/src/scriptapi.h index fe8b26e04..cd6a5614c 100644 --- a/src/scriptapi.h +++ b/src/scriptapi.h @@ -81,6 +81,8 @@ bool scriptapi_node_on_punch(lua_State *L, v3s16 p, MapNode node, ServerActiveObject *puncher); bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node, ServerActiveObject *digger); +void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node); +void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node); /* luaentity */ // Returns true if succesfully added into Lua; false otherwise.