From 2ecbc43a7a299894d1ce0f7b27b262a0b6fba71c Mon Sep 17 00:00:00 2001 From: paramat Date: Sun, 7 Aug 2016 03:54:08 +0100 Subject: [PATCH] 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 --- mods/default/functions.lua | 104 +++++++++++-------------------------- 1 file changed, 31 insertions(+), 73 deletions(-) diff --git a/mods/default/functions.lua b/mods/default/functions.lua index 07f358cb..3c8a871a 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -126,6 +126,7 @@ minetest.register_abm({ -- -- optimized helper to put all items in an inventory into a drops list -- + function default.get_inventory_drops(pos, inventory, drops) local inv = minetest.get_meta(pos):get_inventory() local n = #drops @@ -229,6 +230,7 @@ end -- -- Fence registration helper -- + function default.register_fence(name, def) minetest.register_craft({ output = name .. " 4", @@ -286,16 +288,7 @@ end -- Leafdecay -- -default.leafdecay_trunk_cache = {} -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) +-- Prevent decay of placed leaves default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) 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 +-- Leafdecay ABM + minetest.register_abm({ label = "Leaf decay", nodenames = {"group:leafdecay"}, - neighbors = {"air", "group:liquid"}, - -- A low interval and a high inverse chance spreads the load + neighbors = {"air"}, interval = 2, - chance = 5, + chance = 10, + catch_up = false, - action = function(p0, node, _, _) - --print("leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")") - local do_preserve = false - local d = minetest.registered_nodes[node.name].groups.leafdecay - if not d or d == 0 then - --print("not groups.leafdecay") + action = function(pos, node, _, _) + -- Check if leaf is placed + if node.param2 ~= 0 then return end - local n0 = minetest.get_node(p0) - if n0.param2 ~= 0 then - --print("param2 ~= 0") + + local rad = minetest.registered_nodes[node.name].groups.leafdecay + -- 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 end - local p0_hash = nil - if default.leafdecay_enable_cache then - 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) + -- Drop stuff + local itemstacks = minetest.get_node_drops(node.name) + for _, itemname in ipairs(itemstacks) do + if itemname ~= node.name or + minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then + local p_drop = { + x = pos.x - 0.5 + math.random(), + y = pos.y - 0.5 + math.random(), + z = pos.z - 0.5 + math.random(), + } + minetest.add_item(p_drop, itemname) 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 - if minetest.get_item_group(n0.name, "leafdecay_drop") ~= 0 or - itemname ~= n0.name then - local p_drop = { - x = p0.x - 0.5 + math.random(), - y = p0.y - 0.5 + math.random(), - z = p0.z - 0.5 + math.random(), - } - minetest.add_item(p_drop, itemname) - end - end - -- Remove node - minetest.remove_node(p0) - nodeupdate(p0) - end + -- Remove node + minetest.remove_node(pos) + nodeupdate(pos) end }) @@ -440,6 +397,7 @@ minetest.register_abm({ end }) + -- -- Grass and dry grass removed in darkness --