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.
This commit is contained in:
Aftermoth 2016-04-17 23:32:56 +12:00
parent e543e4af8a
commit ca5d60db5f

View File

@ -15,90 +15,104 @@ http://www.gnu.org/licenses/lgpl-2.1.html
local function in_walkable(p) 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 return n and minetest.registered_nodes[n.name].walkable
end end
-- Update drop's physics and flags.
-- Update drop physics and flags.
local function disentomb(obj) local function disentomb(obj)
local p = obj:getpos() local p = obj:getpos()
if p then if p then
local ent = obj:get_luaentity()
if in_walkable(p) then local ent = obj:get_luaentity()
local brace = math.floor(p.y) + 0.800001 local w = in_walkable(p)
if ent.is_entombed then local brace = math.floor(p.y) + 0.800001
obj:setpos({x = p.x, y = brace + 1, z = p.z})
-- suppress bouncing if ent.is_entombed then
if not in_walkable(obj:getpos()) then local p2 = p
ent.is_entombed = false if w then
end p2 = {x = p.x, y = brace + 1, z = p.z}
else obj:setpos(p2)
end
ent.is_entombed = in_walkable(p2)
else
if w then
obj:setpos({x = p.x, y = brace, z = p.z}) obj:setpos({x = p.x, y = brace, z = p.z})
ent.is_entombed = true ent.is_entombed = true
end end
if ent.is_entombed then
minetest.after(1.0, disentomb, obj)
end
else
ent.is_entombed = false
end 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
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) local function wait_itemstring(ent, c)
if ent.itemstring == "" then if ent.itemstring == "" then
if c < 10 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 end
return return
end end
local obj = ent.object if ent.is_entombed then
disentomb(obj) disentomb(ent.object)
-- 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})
end end
end end
local function append_to_core_defns() local function append_to_core_defns()
local dropentity=minetest.registered_entities["__builtin:item"] local dropentity=minetest.registered_entities["__builtin:item"]
dropentity.is_entombed = false -- Ensure consistency across reloads.
-- Update drops when reloaded or spawned to maintain consistent behaviour.
local on_activate_copy = dropentity.on_activate local on_activate_copy = dropentity.on_activate
dropentity.on_activate = function(ent, staticdata, dtime_s) dropentity.on_activate = function(ent, staticdata, dtime_s)
local r = {on_activate_copy(ent, staticdata, dtime_s)} on_activate_copy(ent, staticdata, dtime_s)
wait_itemstring(ent,0) if staticdata ~= "" then
return unpack(r) 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 end
-- Update drops inside newly placed (including fallen) nodes. -- Update drops inside newly placed (including fallen) nodes.
local add_node_copy = minetest.add_node local add_node_copy = minetest.add_node
minetest.add_node = function(pos,node) minetest.add_node = function(pos,node)
local r = {add_node_copy(pos, node)} add_node_copy(pos, node)
local a = minetest.get_objects_inside_radius(pos, 0.87)
local a = minetest.get_objects_inside_radius(pos, 0.87) -- Radius must include cube corners.
for _,obj in ipairs(a) do for _,obj in ipairs(a) do
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
if ent and ent.name == "__builtin:item" then if ent and ent.name == "__builtin:item" then
disentomb(obj) disentomb(obj)
end end
end end
return unpack(r)
end end
end end
append_to_core_defns()
append_to_core_defns()