Add LuaEntity on_death callback (#6177)
authorLoïc Blot <nerzhul@users.noreply.github.com>
Thu, 27 Jul 2017 09:32:35 +0000 (11:32 +0200)
committerGitHub <noreply@github.com>
Thu, 27 Jul 2017 09:32:35 +0000 (11:32 +0200)
Add LuaEntity on_death callback

This fixes #5474

doc/lua_api.txt
games/minimal/mods/experimental/init.lua
src/content_sao.cpp
src/script/cpp_api/s_entity.cpp
src/script/cpp_api/s_entity.h

index 2a092300ed28b875d1138f61afe00ba4d8414f62..b9dc1b47fc10afff1d48d5bdde02f3075b1aade1 100644 (file)
@@ -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
index 6e0fb1738b17bfda95276340d4e4818c70843869..ba7a8901878fa7784f4b1fedecd9748e1d0f1b95 100644 (file)
@@ -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,
index df5cae34fae3b59725c0dbab57d78c5391db23a0..5ba4f1ad1fc43016955935604193feca0657cf31 100644 (file)
@@ -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);
+       }
 
 
 
index 4c1e296d4925e63fa2aba18af9a0ac99fc24737f..a97b0c12c8c6aac92fdaf928a82ec1fcc68b04e3 100644 (file)
@@ -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)
index 4e2a056bbb4cc10a001c943ca387216dd4549bda..07b06edff5c1eae36ad8c5075317f5977adbd3f8 100644 (file)
@@ -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);
 };