From 2ecbc43a7a299894d1ce0f7b27b262a0b6fba71c Mon Sep 17 00:00:00 2001
From: paramat <mat.gregory@virginmedia.com>
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 | 106 +++++++++++--------------------------
 1 file changed, 32 insertions(+), 74 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,
-
-	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")
-			return
-		end
-		local n0 = minetest.get_node(p0)
-		if n0.param2 ~= 0 then
-			--print("param2 ~= 0")
+	chance = 10,
+	catch_up = false,
+
+	action = function(pos, node, _, _)
+		-- Check if leaf is placed
+		if node.param2 ~= 0 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)
-			end
-		end
-		if default.leafdecay_trunk_find_allow_accumulator <= 0 then
+
+		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
-		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
+		-- 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 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
 --
-- 
GitLab