From ca5d60db5f7f03495d5633382604af37ab07f84c Mon Sep 17 00:00:00 2001 From: Aftermoth Date: Sun, 17 Apr 2016 23:32:56 +1200 Subject: [PATCH] Update init.lua Improved consistency across reload using staticdata. Specifically, drops at rest on irregular node boxes are not read as entombed. Rearranged conditionals to simplify planned behaviour extension. --- init.lua | 94 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/init.lua b/init.lua index 916c4f6..39e3edf 100644 --- a/init.lua +++ b/init.lua @@ -15,90 +15,104 @@ http://www.gnu.org/licenses/lgpl-2.1.html local function in_walkable(p) - local n=minetest.get_node_or_nil(p) + local n = minetest.get_node_or_nil(p) return n and minetest.registered_nodes[n.name].walkable end --- Update drop's physics and flags. + +-- Update drop physics and flags. local function disentomb(obj) local p = obj:getpos() if p then - local ent = obj:get_luaentity() - if in_walkable(p) then - local brace = math.floor(p.y) + 0.800001 - if ent.is_entombed then - obj:setpos({x = p.x, y = brace + 1, z = p.z}) - -- suppress bouncing - if not in_walkable(obj:getpos()) then - ent.is_entombed = false - end - else + local ent = obj:get_luaentity() + local w = in_walkable(p) + local brace = math.floor(p.y) + 0.800001 + + if ent.is_entombed then + local p2 = p + if w then + p2 = {x = p.x, y = brace + 1, z = p.z} + obj:setpos(p2) + end + ent.is_entombed = in_walkable(p2) + else + if w then obj:setpos({x = p.x, y = brace, z = p.z}) ent.is_entombed = true end - - if ent.is_entombed then - minetest.after(1.0, disentomb, obj) - end - else - ent.is_entombed = false end + + if ent.is_entombed then + obj:setvelocity({x = 0, y = 0, z = 0}) + obj:setacceleration({x = 0, y = 0, z = 0}) + minetest.after(1.0, disentomb, obj) + end + end end --- Properties set by on_activate are not accessible until it returns --- so this function polls until they are before continuing. + +-- Poll until defaults are ready before continuing. local function wait_itemstring(ent, c) if ent.itemstring == "" then if c < 10 then - minetest.after(0.1, wait_itemstring, ent, c + 1) -- 2 ticks + minetest.after(0.1, wait_itemstring, ent, c + 1) end return end - local obj = ent.object - disentomb(obj) - - -- stabilise entombed spawns - if in_walkable(obj:getpos()) then - obj:setvelocity({x = 0, y = 0, z = 0}) - obj:setacceleration({x = 0,y = 0, z = 0}) + if ent.is_entombed then + disentomb(ent.object) end end + local function append_to_core_defns() local dropentity=minetest.registered_entities["__builtin:item"] - dropentity.is_entombed = false - - -- Update drops when reloaded or spawned to maintain consistent behaviour. + -- Ensure consistency across reloads. local on_activate_copy = dropentity.on_activate dropentity.on_activate = function(ent, staticdata, dtime_s) - local r = {on_activate_copy(ent, staticdata, dtime_s)} - wait_itemstring(ent,0) - return unpack(r) + on_activate_copy(ent, staticdata, dtime_s) + if staticdata ~= "" then + ent.is_entombed = minetest.deserialize(staticdata).is_entombed + end + wait_itemstring(ent, 0) + end + + -- Preserve state across reloads + local get_staticdata_copy = dropentity.get_staticdata + dropentity.get_staticdata = function(ent) + local s = get_staticdata_copy(ent) + if ent.is_entombed then + local r = {} + if s ~= "" then + r = minetest.deserialize(s) + end + r.is_entombed=true + return minetest.serialize(r) + end + return s end -- Update drops inside newly placed (including fallen) nodes. local add_node_copy = minetest.add_node minetest.add_node = function(pos,node) - local r = {add_node_copy(pos, node)} - - local a = minetest.get_objects_inside_radius(pos, 0.87) -- Radius must include cube corners. + add_node_copy(pos, node) + local a = minetest.get_objects_inside_radius(pos, 0.87) for _,obj in ipairs(a) do local ent = obj:get_luaentity() if ent and ent.name == "__builtin:item" then disentomb(obj) end end - - return unpack(r) end + end -append_to_core_defns() +append_to_core_defns()