Don't spawn vines on group:leafdecay
[minetest_hades/hades_revisited.git] / mods / hades_trees / leafdecay.lua
bloba9a58ad4b9b8811216fa33e9910a02a0d61337df
1 --
2 -- Leafdecay
3 --
5 -- To enable leaf decay for a node, add it to the "leafdecay" group.
6 --
7 -- The rating of the group determines how far from a node in the group "tree"
8 -- the node can be without decaying.
9 --
10 -- If param2 of the node is ~= 0, the node will always be preserved. Thus, if
11 -- the player places a node of that kind, you will want to set param2=1 or so.
13 -- If the node is in the leafdecay_drop group then the it will always be dropped
14 -- as an item
17 hades_trees.leafdecay_trunk_cache = {}
18 hades_trees.leafdecay_enable_cache = true
19 -- Spread the load of finding trunks
20 hades_trees.leafdecay_trunk_find_allow_accumulator = 0
22 minetest.register_globalstep(function(dtime)
23 local finds_per_second = 5000
24 hades_trees.leafdecay_trunk_find_allow_accumulator =
25 math.floor(dtime * finds_per_second)
26 end)
28 local function leafdecay_particles(pos, node)
29 minetest.add_particlespawner({
30 amount = math.random(10, 20),
31 time = 0.1,
32 minpos = vector.add(pos, {x=-0.4, y=-0.4, z=-0.4}),
33 maxpos = vector.add(pos, {x=0.4, y=0.4, z=0.4}),
34 minvel = {x=-0.2, y=-0.2, z=-0.2},
35 maxvel = {x=0.2, y=0.1, z=0.2},
36 minacc = {x=0, y=-9.81, z=0},
37 maxacc = {x=0, y=-9.81, z=0},
38 minexptime = 0.1,
39 maxexptime = 0.5,
40 minsize = 0.5,
41 maxsize = 1.5,
42 collisiondetection = true,
43 vertical = false,
44 node = node,
46 end
48 minetest.register_abm({
49 label = "Leaf decay",
50 nodenames = {"group:leafdecay"},
51 neighbors = {"air", "group:liquid"},
52 -- A low interval and a high inverse chance spreads the load
53 interval = 2,
54 chance = 5,
56 action = function(p0, node, _, _)
57 minetest.log("verbose", "[hades_trees] leafdecay ABM at "..p0.x..", "..p0.y..", "..p0.z..")")
58 local do_preserve = false
59 local d = minetest.registered_nodes[node.name].groups.leafdecay
60 if not d or d == 0 then
61 minetest.log("verbose", "[hades_trees] not groups.leafdecay")
62 return
63 end
64 local n0 = minetest.get_node(p0)
65 if n0.param2 ~= 0 then
66 -- Prevent decay
67 return
68 end
69 local p0_hash = nil
70 if hades_trees.leafdecay_enable_cache then
71 p0_hash = minetest.hash_node_position(p0)
72 local trunkp = hades_trees.leafdecay_trunk_cache[p0_hash]
73 if trunkp then
74 local n = minetest.get_node(trunkp)
75 local reg = minetest.registered_nodes[n.name]
76 -- Assume ignore is a trunk, to make the thing work at the border of the active area
77 if n.name == "ignore" or (reg and reg.groups.tree and reg.groups.tree ~= 0) then
78 minetest.log("verbose", "[hades_trees] leafdecay: cached trunk still exists")
79 return
80 end
81 minetest.log("verbose", "[hades_trees] leafdecay: cached trunk is invalid")
82 -- Cache is invalid
83 table.remove(hades_trees.leafdecay_trunk_cache, p0_hash)
84 end
85 end
86 if hades_trees.leafdecay_trunk_find_allow_accumulator <= 0 then
87 return
88 end
89 hades_trees.leafdecay_trunk_find_allow_accumulator =
90 hades_trees.leafdecay_trunk_find_allow_accumulator - 1
91 -- Assume ignore is a trunk, to make the thing work at the border of the active area
92 local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"})
93 if p1 then
94 do_preserve = true
95 if hades_trees.leafdecay_enable_cache then
96 minetest.log("verbose", "[hades_trees] leafdecay: caching trunk")
97 -- Cache the trunk
98 hades_trees.leafdecay_trunk_cache[p0_hash] = p1
99 end
101 if not do_preserve then
102 -- Drop stuff other than the node itself
103 local itemstacks = minetest.get_node_drops(n0.name)
104 local drop_items = false
105 for _, itemname in ipairs(itemstacks) do
106 if minetest.get_item_group(n0.name, "leafdecay_drop") ~= 0 or
107 itemname ~= n0.name then
108 local p_drop = {
109 x = p0.x - 0.5 + math.random(),
110 y = p0.y - 0.5 + math.random(),
111 z = p0.z - 0.5 + math.random(),
113 drop_items = true
114 minetest.add_item(p_drop, itemname)
117 -- Remove node
118 minetest.remove_node(p0)
119 if not drop_items then
120 leafdecay_particles(p0, n0)
122 minetest.check_for_falling(p0)