Skip to content

Commit 60e5b29

Browse files
MarkuBuparamat
authored andcommittedFeb 25, 2017
Leafdecay: Node timer based implementation, API
This implements a node-timer based leafdecay mechanism, and exposes an API to use it in mods. The API is documented in game_api.txt. `default.register_leafdecay(leafdecaydef)` `leafdecaydef` is a table, with following members: { trunks = { "default:tree"}, -- nodes considered trunks leaves = { "default:leaves", "default:apple"}, -- nodes considered leaves radius = 3, -- activates leafdecay this far from the trunk } The algorithm will drop `leaves` items in the area if no `trunks` are found in the `trunk_radius` sized area around the position of the leaf. If a node listed in `leaves` has a group `leafdecay_drop > 0`, then the item is dropped, otherwise the item is removed but not dropped. The algorithm also implements a value `default.leafdecay_speed` (default 15) which can be modified to increase or decrease of the leaf decay. The algorithm will vary the actual speed a bit to introduce randomness. Leaf decay is randomized by 0.1 seconds to reduce the chance that decay happens many times on the same second interval. This requires nodetimer_interval to be set to values lower than 1.0 to have an effect. The leaves will decay between 2 and 10 seconds after digging the trunk, and happen at non-integer second intervals. -- The API was added by sofar.
1 parent 37dd910 commit 60e5b29

File tree

3 files changed

+132
-45
lines changed

3 files changed

+132
-45
lines changed
 

‎game_api.txt

+26-10
Original file line numberDiff line numberDiff line change
@@ -658,20 +658,36 @@ default.player_get_animation(player)
658658
Leafdecay
659659
---------
660660

661-
To enable leaf decay for a node, add it to the `leafdecay` group.
661+
To enable leaf decay for leaves when a tree is cut down by a player,
662+
register the tree with the default.register_leafdecay(leafdecaydef)
663+
function.
662664

663-
The rating of the group determines how far from a node in the group `tree`
664-
the node can be without decaying.
665+
If `param2` of any registered node is ~= 0, the node will always be
666+
preserved. Thus, if the player places a node of that kind, you will
667+
want to set `param2 = 1` or so.
665668

666-
If `param2` of the node is ~= 0, the node will always be preserved. Thus, if
667-
the player places a node of that kind, you will want to set `param2 = 1` or so.
669+
The function `default.after_place_leaves` can be set as
670+
`after_place_node of a node` to set param2 to 1 if the player places
671+
the node (should not be used for nodes that use param2 otherwise
672+
(e.g. facedir)).
668673

669-
The function `default.after_place_leaves` can be set as `after_place_node of a node`
670-
to set param2 to 1 if the player places the node (should not be used for nodes
671-
that use param2 otherwise (e.g. facedir)).
674+
If the node is in the `leafdecay_drop` group then it will always be
675+
dropped as an item.
676+
677+
`default.register_leafdecay(leafdecaydef)`
678+
679+
`leafdecaydef` is a table, with following members:
680+
{
681+
trunks = {"default:tree"}, -- nodes considered trunks
682+
leaves = {"default:leaves", "default:apple"},
683+
-- nodes considered for removal
684+
radius = 3, -- radius to consider for searching
685+
}
686+
687+
Note: all the listed nodes in `trunks` have their `on_after_destruct`
688+
callback overridden. All the nodes listed in `leaves` have their
689+
`on_timer` callback overridden.
672690

673-
If the node is in the `leafdecay_drop` group then it will always be dropped as an
674-
item.
675691

676692
Dyes
677693
----

‎mods/default/functions.lua

+52-35
Original file line numberDiff line numberDiff line change
@@ -325,47 +325,64 @@ default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
325325
end
326326
end
327327

328-
-- Leafdecay ABM
329-
330-
minetest.register_abm({
331-
label = "Leaf decay",
332-
nodenames = {"group:leafdecay"},
333-
neighbors = {"air"},
334-
interval = 2,
335-
chance = 10,
336-
catch_up = false,
337-
338-
action = function(pos, node, _, _)
339-
-- Check if leaf is placed
340-
if node.param2 ~= 0 then
341-
return
328+
-- Leafdecay
329+
local function leafdecay_after_destruct(pos, oldnode, def)
330+
for _, v in pairs(minetest.find_nodes_in_area(vector.subtract(pos, def.radius),
331+
vector.add(pos, def.radius), def.leaves)) do
332+
local node = minetest.get_node(v)
333+
if node.param2 == 0 then
334+
minetest.get_node_timer(v):start(math.random(20, 120) / 10)
342335
end
336+
end
337+
end
343338

344-
local rad = minetest.registered_nodes[node.name].groups.leafdecay
345-
-- Assume ignore is a trunk, to make this
346-
-- work at the border of a loaded area
347-
if minetest.find_node_near(pos, rad, {"ignore", "group:tree"}) then
348-
return
349-
end
350-
-- Drop stuff
351-
local itemstacks = minetest.get_node_drops(node.name)
352-
for _, itemname in ipairs(itemstacks) do
353-
if itemname ~= node.name or
354-
minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then
355-
local p_drop = {
356-
x = pos.x - 0.5 + math.random(),
357-
y = pos.y - 0.5 + math.random(),
358-
z = pos.z - 0.5 + math.random(),
359-
}
360-
minetest.add_item(p_drop, itemname)
339+
local function leafdecay_on_timer(pos, def)
340+
if minetest.find_node_near(pos, def.radius, def.trunks) then
341+
return false
342+
end
343+
344+
local node = minetest.get_node(pos)
345+
local drops = minetest.get_node_drops(node.name)
346+
for _, item in ipairs(drops) do
347+
local is_leaf
348+
for _, v in pairs(def.leaves) do
349+
if v == item then
350+
is_leaf = true
361351
end
362352
end
363-
-- Remove node
364-
minetest.remove_node(pos)
365-
minetest.check_for_falling(pos)
353+
if minetest.get_item_group(item, "leafdecay_drop") ~= 0 or
354+
not is_leaf then
355+
minetest.add_item({
356+
x = pos.x - 0.5 + math.random(),
357+
y = pos.y - 0.5 + math.random(),
358+
z = pos.z - 0.5 + math.random(),
359+
}, item)
360+
end
366361
end
367-
})
368362

363+
minetest.remove_node(pos)
364+
minetest.check_for_falling(pos)
365+
end
366+
367+
function default.register_leafdecay(def)
368+
assert(def.leaves)
369+
assert(def.trunks)
370+
assert(def.radius)
371+
for _, v in pairs(def.trunks) do
372+
minetest.override_item(v, {
373+
after_destruct = function(pos, oldnode)
374+
leafdecay_after_destruct(pos, oldnode, def)
375+
end,
376+
})
377+
end
378+
for _, v in pairs(def.leaves) do
379+
minetest.override_item(v, {
380+
on_timer = function(pos)
381+
leafdecay_on_timer(pos, def)
382+
end,
383+
})
384+
end
385+
end
369386

370387
--
371388
-- Convert dirt to something that fits the environment

‎mods/default/nodes.lua

+54
Original file line numberDiff line numberDiff line change
@@ -2072,3 +2072,57 @@ minetest.register_node("default:cloud", {
20722072
sounds = default.node_sound_defaults(),
20732073
groups = {not_in_creative_inventory = 1},
20742074
})
2075+
2076+
--
2077+
-- register trees for leafdecay
2078+
--
2079+
2080+
if minetest.get_mapgen_setting("mg_name") == "v6" then
2081+
default.register_leafdecay({
2082+
trunks = {"default:tree"},
2083+
leaves = {"default:apple", "default:leaves"},
2084+
radius = 2,
2085+
})
2086+
2087+
default.register_leafdecay({
2088+
trunks = {"default:jungletree"},
2089+
leaves = {"default:jungleleaves"},
2090+
radius = 3,
2091+
})
2092+
2093+
default.register_leafdecay({
2094+
trunks = {"default:pine_tree"},
2095+
leaves = {"default:pine_needles"},
2096+
radius = 3,
2097+
})
2098+
else
2099+
default.register_leafdecay({
2100+
trunks = {"default:tree"},
2101+
leaves = {"default:apple", "default:leaves"},
2102+
radius = 3,
2103+
})
2104+
2105+
default.register_leafdecay({
2106+
trunks = {"default:jungletree"},
2107+
leaves = {"default:jungleleaves"},
2108+
radius = 2,
2109+
})
2110+
2111+
default.register_leafdecay({
2112+
trunks = {"default:pine_tree"},
2113+
leaves = {"default:pine_needles"},
2114+
radius = 2,
2115+
})
2116+
end
2117+
2118+
default.register_leafdecay({
2119+
trunks = {"default:acacia_tree"},
2120+
leaves = {"default:acacia_leaves"},
2121+
radius = 2,
2122+
})
2123+
2124+
default.register_leafdecay({
2125+
trunks = {"default:aspen_tree"},
2126+
leaves = {"default:aspen_leaves"},
2127+
radius = 3,
2128+
})

0 commit comments

Comments
 (0)
Please sign in to comment.