forked from minetest/minetest_game
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.
This commit is contained in:
parent
37dd910747
commit
60e5b299af
36
game_api.txt
36
game_api.txt
@ -658,20 +658,36 @@ default.player_get_animation(player)
|
|||||||
Leafdecay
|
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`
|
If `param2` of any registered node is ~= 0, the node will always be
|
||||||
the node can be without decaying.
|
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 function `default.after_place_leaves` can be set as
|
||||||
the player places a node of that kind, you will want to set `param2 = 1` or so.
|
`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`
|
If the node is in the `leafdecay_drop` group then it will always be
|
||||||
to set param2 to 1 if the player places the node (should not be used for nodes
|
dropped as an item.
|
||||||
that use param2 otherwise (e.g. facedir)).
|
|
||||||
|
`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
|
Dyes
|
||||||
----
|
----
|
||||||
|
@ -325,47 +325,64 @@ default.after_place_leaves = function(pos, placer, itemstack, pointed_thing)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Leafdecay ABM
|
-- 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
|
||||||
|
|
||||||
minetest.register_abm({
|
local function leafdecay_on_timer(pos, def)
|
||||||
label = "Leaf decay",
|
if minetest.find_node_near(pos, def.radius, def.trunks) then
|
||||||
nodenames = {"group:leafdecay"},
|
return false
|
||||||
neighbors = {"air"},
|
|
||||||
interval = 2,
|
|
||||||
chance = 10,
|
|
||||||
catch_up = false,
|
|
||||||
|
|
||||||
action = function(pos, node, _, _)
|
|
||||||
-- Check if leaf is placed
|
|
||||||
if node.param2 ~= 0 then
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local rad = minetest.registered_nodes[node.name].groups.leafdecay
|
local node = minetest.get_node(pos)
|
||||||
-- Assume ignore is a trunk, to make this
|
local drops = minetest.get_node_drops(node.name)
|
||||||
-- work at the border of a loaded area
|
for _, item in ipairs(drops) do
|
||||||
if minetest.find_node_near(pos, rad, {"ignore", "group:tree"}) then
|
local is_leaf
|
||||||
return
|
for _, v in pairs(def.leaves) do
|
||||||
|
if v == item then
|
||||||
|
is_leaf = true
|
||||||
end
|
end
|
||||||
-- Drop stuff
|
end
|
||||||
local itemstacks = minetest.get_node_drops(node.name)
|
if minetest.get_item_group(item, "leafdecay_drop") ~= 0 or
|
||||||
for _, itemname in ipairs(itemstacks) do
|
not is_leaf then
|
||||||
if itemname ~= node.name or
|
minetest.add_item({
|
||||||
minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then
|
|
||||||
local p_drop = {
|
|
||||||
x = pos.x - 0.5 + math.random(),
|
x = pos.x - 0.5 + math.random(),
|
||||||
y = pos.y - 0.5 + math.random(),
|
y = pos.y - 0.5 + math.random(),
|
||||||
z = pos.z - 0.5 + math.random(),
|
z = pos.z - 0.5 + math.random(),
|
||||||
}
|
}, item)
|
||||||
minetest.add_item(p_drop, itemname)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Remove node
|
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
minetest.check_for_falling(pos)
|
minetest.check_for_falling(pos)
|
||||||
end
|
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
|
-- Convert dirt to something that fits the environment
|
||||||
|
@ -2072,3 +2072,57 @@ minetest.register_node("default:cloud", {
|
|||||||
sounds = default.node_sound_defaults(),
|
sounds = default.node_sound_defaults(),
|
||||||
groups = {not_in_creative_inventory = 1},
|
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,
|
||||||
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user