Default: Optimise and simplify leafdecay ABM, remove cache
authorparamat <mat.gregory@virginmedia.com>
Sun, 7 Aug 2016 02:54:08 +0000 (03:54 +0100)
committerparamat <mat.gregory@virginmedia.com>
Mon, 15 Aug 2016 19:42:50 +0000 (20:42 +0100)
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

index 07f358cbaac2a8986455979cc387377be7270f6a..3c8a871a1667db3f8f21fce24a341e9ba8e8b0d8 100644 (file)
@@ -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
 --