Leafdecay
---------
-To enable leaf decay for a node, add it to the `leafdecay` group.
+To enable leaf decay for leaves when a tree is cut down by a player,
+register the tree with the default.register_leafdecay(leafdecaydef)
+function.
-The rating of the group determines how far from a node in the group `tree`
-the node can be without decaying.
+If `param2` of any registered node is ~= 0, the node will always be
+preserved. Thus, if the player places a node of that kind, you will
+want to set `param2 = 1` or so.
-If `param2` of the node is ~= 0, the node will always be preserved. Thus, if
-the player places a node of that kind, you will want to set `param2 = 1` or so.
+The function `default.after_place_leaves` can be set as
+`after_place_node of a node` to set param2 to 1 if the player places
+the node (should not be used for nodes that use param2 otherwise
+(e.g. facedir)).
-The function `default.after_place_leaves` can be set as `after_place_node of a node`
-to set param2 to 1 if the player places the node (should not be used for nodes
-that use param2 otherwise (e.g. facedir)).
+If the node is in the `leafdecay_drop` group then it will always be
+dropped as an item.
+
+`default.register_leafdecay(leafdecaydef)`
+
+`leafdecaydef` is a table, with following members:
+ {
+ trunks = {"default:tree"}, -- nodes considered trunks
+ leaves = {"default:leaves", "default:apple"},
+ -- nodes considered for removal
+ radius = 3, -- radius to consider for searching
+ }
+
+Note: all the listed nodes in `trunks` have their `on_after_destruct`
+callback overridden. All the nodes listed in `leaves` have their
+`on_timer` callback overridden.
-If the node is in the `leafdecay_drop` group then it will always be dropped as an
-item.
Dyes
----
end
end
--- Leafdecay ABM
-
-minetest.register_abm({
- label = "Leaf decay",
- nodenames = {"group:leafdecay"},
- neighbors = {"air"},
- interval = 2,
- chance = 10,
- catch_up = false,
-
- action = function(pos, node, _, _)
- -- Check if leaf is placed
- if node.param2 ~= 0 then
- return
+-- Leafdecay
+local function leafdecay_after_destruct(pos, oldnode, def)
+ for _, v in pairs(minetest.find_nodes_in_area(vector.subtract(pos, def.radius),
+ vector.add(pos, def.radius), def.leaves)) do
+ local node = minetest.get_node(v)
+ if node.param2 == 0 then
+ minetest.get_node_timer(v):start(math.random(20, 120) / 10)
end
+ end
+end
- 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
- -- 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)
+local function leafdecay_on_timer(pos, def)
+ if minetest.find_node_near(pos, def.radius, def.trunks) then
+ return false
+ end
+
+ local node = minetest.get_node(pos)
+ local drops = minetest.get_node_drops(node.name)
+ for _, item in ipairs(drops) do
+ local is_leaf
+ for _, v in pairs(def.leaves) do
+ if v == item then
+ is_leaf = true
end
end
- -- Remove node
- minetest.remove_node(pos)
- minetest.check_for_falling(pos)
+ if minetest.get_item_group(item, "leafdecay_drop") ~= 0 or
+ not is_leaf then
+ minetest.add_item({
+ x = pos.x - 0.5 + math.random(),
+ y = pos.y - 0.5 + math.random(),
+ z = pos.z - 0.5 + math.random(),
+ }, item)
+ end
end
-})
+ minetest.remove_node(pos)
+ minetest.check_for_falling(pos)
+end
+
+function default.register_leafdecay(def)
+ assert(def.leaves)
+ assert(def.trunks)
+ assert(def.radius)
+ for _, v in pairs(def.trunks) do
+ minetest.override_item(v, {
+ after_destruct = function(pos, oldnode)
+ leafdecay_after_destruct(pos, oldnode, def)
+ end,
+ })
+ end
+ for _, v in pairs(def.leaves) do
+ minetest.override_item(v, {
+ on_timer = function(pos)
+ leafdecay_on_timer(pos, def)
+ end,
+ })
+ end
+end
--
-- Convert dirt to something that fits the environment
sounds = default.node_sound_defaults(),
groups = {not_in_creative_inventory = 1},
})
+
+--
+-- register trees for leafdecay
+--
+
+if minetest.get_mapgen_setting("mg_name") == "v6" then
+ default.register_leafdecay({
+ trunks = {"default:tree"},
+ leaves = {"default:apple", "default:leaves"},
+ radius = 2,
+ })
+
+ default.register_leafdecay({
+ trunks = {"default:jungletree"},
+ leaves = {"default:jungleleaves"},
+ radius = 3,
+ })
+
+ default.register_leafdecay({
+ trunks = {"default:pine_tree"},
+ leaves = {"default:pine_needles"},
+ radius = 3,
+ })
+else
+ default.register_leafdecay({
+ trunks = {"default:tree"},
+ leaves = {"default:apple", "default:leaves"},
+ radius = 3,
+ })
+
+ default.register_leafdecay({
+ trunks = {"default:jungletree"},
+ leaves = {"default:jungleleaves"},
+ radius = 2,
+ })
+
+ default.register_leafdecay({
+ trunks = {"default:pine_tree"},
+ leaves = {"default:pine_needles"},
+ radius = 2,
+ })
+end
+
+default.register_leafdecay({
+ trunks = {"default:acacia_tree"},
+ leaves = {"default:acacia_leaves"},
+ radius = 2,
+})
+
+default.register_leafdecay({
+ trunks = {"default:aspen_tree"},
+ leaves = {"default:aspen_leaves"},
+ radius = 3,
+})