From 550c0404a8b6fbee857003c961bb802121e88f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Blot?= Date: Thu, 27 Jul 2017 11:32:35 +0200 Subject: [PATCH] Add LuaEntity on_death callback (#6177) Add LuaEntity on_death callback This fixes #5474 --- doc/lua_api.txt | 3 +++ games/minimal/mods/experimental/init.lua | 15 ++++++++----- src/content_sao.cpp | 4 +++- src/script/cpp_api/s_entity.cpp | 28 ++++++++++++++++++++++++ src/script/cpp_api/s_entity.h | 1 + 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 2a092300..b9dc1b47 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3864,6 +3864,9 @@ Registered entities * `tool_capabilities`: capability table of used tool (can be `nil`) * `dir`: unit vector of direction of punch. Always defined. Points from the puncher to the punched. + `on_death(self, killer)` + * Called when the object dies. + * `killer`: an `ObjectRef` (can be `nil`) * `on_rightclick(self, clicker)` * `get_staticdata(self)` * Should return a string that will be passed to `on_activate` when diff --git a/games/minimal/mods/experimental/init.lua b/games/minimal/mods/experimental/init.lua index 6e0fb173..ba7a8901 100644 --- a/games/minimal/mods/experimental/init.lua +++ b/games/minimal/mods/experimental/init.lua @@ -317,6 +317,9 @@ minetest.register_entity("experimental:testentity", { self.object:remove() hitter:add_to_inventory('craft testobject1 1') end, + on_death = function(self, killer) + print("testentity.on_death") + end }) -- @@ -398,11 +401,11 @@ minetest.register_abm({ if ncpos ~= nil then return end - + if pos.x % 16 ~= 8 or pos.z % 16 ~= 8 then return end - + pos.y = pos.y + 1 n = minetest.get_node(pos) print(dump(n)) @@ -431,7 +434,7 @@ minetest.register_abm({ return end nctime = clock - + s0 = ncstuff[ncq] ncq = s0[1] s1 = ncstuff[ncq] @@ -477,15 +480,15 @@ minetest.register_node("experimental:tester_node_1", { experimental.print_to_everything("incorrect metadata found") end end, - + on_destruct = function(pos) experimental.print_to_everything("experimental:tester_node_1:on_destruct("..minetest.pos_to_string(pos)..")") 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) experimental.print_to_everything("experimental:tester_node_1:after_dig_node("..minetest.pos_to_string(pos)..")") end, diff --git a/src/content_sao.cpp b/src/content_sao.cpp index df5cae34..5ba4f1ad 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -582,8 +582,10 @@ int LuaEntitySAO::punch(v3f dir, } } - if (getHP() == 0) + if (getHP() == 0) { m_removed = true; + m_env->getScriptIface()->luaentity_on_death(m_id, puncher); + } diff --git a/src/script/cpp_api/s_entity.cpp b/src/script/cpp_api/s_entity.cpp index 4c1e296d..a97b0c12 100644 --- a/src/script/cpp_api/s_entity.cpp +++ b/src/script/cpp_api/s_entity.cpp @@ -262,6 +262,34 @@ bool ScriptApiEntity::luaentity_Punch(u16 id, return retval; } +bool ScriptApiEntity::luaentity_on_death(u16 id, ServerActiveObject *killer) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + // Get core.luaentities[id] + luaentity_get(L, id); + int object = lua_gettop(L); + // State: object is at top of stack + // Get function + lua_getfield(L, -1, "on_death"); + if (lua_isnil(L, -1)) { + lua_pop(L, 2); // Pop on_death and entity + return false; + } + luaL_checktype(L, -1, LUA_TFUNCTION); + lua_pushvalue(L, object); // self + objectrefGetOrCreate(L, killer); // killer reference + + setOriginFromTable(object); + PCALL_RES(lua_pcall(L, 6, 1, error_handler)); + + bool retval = lua_toboolean(L, -1); + lua_pop(L, 2); // Pop object and error handler + return retval; +} + // Calls entity:on_rightclick(ObjectRef clicker) void ScriptApiEntity::luaentity_Rightclick(u16 id, ServerActiveObject *clicker) diff --git a/src/script/cpp_api/s_entity.h b/src/script/cpp_api/s_entity.h index 4e2a056b..07b06edf 100644 --- a/src/script/cpp_api/s_entity.h +++ b/src/script/cpp_api/s_entity.h @@ -41,6 +41,7 @@ public: bool luaentity_Punch(u16 id, ServerActiveObject *puncher, float time_from_last_punch, const ToolCapabilities *toolcap, v3f dir, s16 damage); + bool luaentity_on_death(u16 id, ServerActiveObject *killer); void luaentity_Rightclick(u16 id, ServerActiveObject *clicker); };