Default: Optimise and simplify leafdecay ABM, remove cache

With thanks to contributor tenplus1
Remove leaf cache and globalstep accumulator limiter
Use 'pos' instead of 'p0'
Remove non-essential 'group:liquid' from 'neighbors'
Increase chance value to 10 to compensate for disabled cache
Disable 'catch-up' to avoid the ABM often becoming 10 times more
intensive
Remove use of 'do preserve' bool, instead simply 'return'
Remove unnecessary checks for 'd' and 'd == 0'
Don't 'get' n0, use already present 'node' instead
Swap order two conditionals so that the one most likely is first
This commit is contained in:
paramat 2016-08-07 03:54:08 +01:00
parent 619ac52693
commit 2ecbc43a7a

View File

@ -126,6 +126,7 @@ minetest.register_abm({
-- --
-- optimized helper to put all items in an inventory into a drops list -- optimized helper to put all items in an inventory into a drops list
-- --
function default.get_inventory_drops(pos, inventory, drops) function default.get_inventory_drops(pos, inventory, drops)
local inv = minetest.get_meta(pos):get_inventory() local inv = minetest.get_meta(pos):get_inventory()
local n = #drops local n = #drops
@ -229,6 +230,7 @@ end
-- --
-- Fence registration helper -- Fence registration helper
-- --
function default.register_fence(name, def) function default.register_fence(name, def)
minetest.register_craft({ minetest.register_craft({
output = name .. " 4", output = name .. " 4",
@ -286,16 +288,7 @@ end
-- Leafdecay -- Leafdecay
-- --
default.leafdecay_trunk_cache = {} -- Prevent decay of placed leaves
default.leafdecay_enable_cache = true
-- Spread the load of finding trunks
default.leafdecay_trunk_find_allow_accumulator = 0
minetest.register_globalstep(function(dtime)
local finds_per_second = 5000
default.leafdecay_trunk_find_allow_accumulator =
math.floor(dtime * finds_per_second)
end)
default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
if placer and not placer:get_player_control().sneak then if placer and not placer:get_player_control().sneak then
@ -305,80 +298,44 @@ default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
end end
end end
-- Leafdecay ABM
minetest.register_abm({ minetest.register_abm({
label = "Leaf decay", label = "Leaf decay",
nodenames = {"group:leafdecay"}, nodenames = {"group:leafdecay"},
neighbors = {"air", "group:liquid"}, neighbors = {"air"},
-- A low interval and a high inverse chance spreads the load
interval = 2, interval = 2,
chance = 5, chance = 10,
catch_up = false,
action = function(p0, node, _, _) action = function(pos, node, _, _)
--print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")") -- Check if leaf is placed
local do_preserve = false if node.param2 ~= 0 then
local d = minetest.registered_nodes[node.name].groups.leafdecay
if not d or d == 0 then
--print("not groups.leafdecay")
return return
end end
local n0 = minetest.get_node(p0)
if n0.param2 ~= 0 then local rad = minetest.registered_nodes[node.name].groups.leafdecay
--print("param2 ~= 0") -- Assume ignore is a trunk, to make this
-- work at the border of a loaded area
if minetest.find_node_near(pos, rad, {"ignore", "group:tree"}) then
return return
end end
local p0_hash = nil -- Drop stuff
if default.leafdecay_enable_cache then local itemstacks = minetest.get_node_drops(node.name)
p0_hash = minetest.hash_node_position(p0)
local trunkp = default.leafdecay_trunk_cache[p0_hash]
if trunkp then
local n = minetest.get_node(trunkp)
local reg = minetest.registered_nodes[n.name]
-- Assume ignore is a trunk, to make the thing
-- work at the border of the active area
if n.name == "ignore" or (reg and reg.groups.tree and
reg.groups.tree ~= 0) then
--print("cached trunk still exists")
return
end
--print("cached trunk is invalid")
-- Cache is invalid
table.remove(default.leafdecay_trunk_cache, p0_hash)
end
end
if default.leafdecay_trunk_find_allow_accumulator <= 0 then
return
end
default.leafdecay_trunk_find_allow_accumulator =
default.leafdecay_trunk_find_allow_accumulator - 1
-- Assume ignore is a trunk, to make the thing
-- work at the border of the active area
local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"})
if p1 then
do_preserve = true
if default.leafdecay_enable_cache then
--print("caching trunk")
-- Cache the trunk
default.leafdecay_trunk_cache[p0_hash] = p1
end
end
if not do_preserve then
-- Drop stuff other than the node itself
local itemstacks = minetest.get_node_drops(n0.name)
for _, itemname in ipairs(itemstacks) do for _, itemname in ipairs(itemstacks) do
if minetest.get_item_group(n0.name, "leafdecay_drop") ~= 0 or if itemname ~= node.name or
itemname ~= n0.name then minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then
local p_drop = { local p_drop = {
x = p0.x - 0.5 + math.random(), x = pos.x - 0.5 + math.random(),
y = p0.y - 0.5 + math.random(), y = pos.y - 0.5 + math.random(),
z = p0.z - 0.5 + math.random(), z = pos.z - 0.5 + math.random(),
} }
minetest.add_item(p_drop, itemname) minetest.add_item(p_drop, itemname)
end end
end end
-- Remove node -- Remove node
minetest.remove_node(p0) minetest.remove_node(pos)
nodeupdate(p0) nodeupdate(pos)
end
end end
}) })
@ -440,6 +397,7 @@ minetest.register_abm({
end end
}) })
-- --
-- Grass and dry grass removed in darkness -- Grass and dry grass removed in darkness
-- --