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 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 ent = obj:get_luaentity()
local w = in_walkable(p)
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
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
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
else
ent.is_entombed = false
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()