2023-10-17 08:17:13 +00:00
|
|
|
local modname = minetest.get_current_modname()
|
|
|
|
|
|
|
|
-- NODE NAMES
|
|
|
|
|
|
|
|
local sapling = modname .. ":sapling"
|
|
|
|
local log_alive = modname .. ":log_alive"
|
2023-10-17 08:23:53 +00:00
|
|
|
local leaves_growing = modname .. ":leaves_growing"
|
2023-10-17 08:17:13 +00:00
|
|
|
|
2023-10-17 14:28:58 +00:00
|
|
|
|
2023-10-17 08:17:13 +00:00
|
|
|
|
|
|
|
local function supports_sapling (name)
|
|
|
|
if name == log_alive or name == root_alive then return true end
|
|
|
|
return minetest.get_item_group(name, "dirty") > 0
|
|
|
|
end
|
|
|
|
|
2023-10-17 14:28:58 +00:00
|
|
|
-- this commented-out function will be used when roots start affecting tree growth.
|
|
|
|
--[[
|
|
|
|
local function find_first_root (pos, max_height = 8)
|
|
|
|
local pos = vector.copy(pos)
|
|
|
|
local height = 0
|
|
|
|
while height < max_height do
|
|
|
|
height = height + 1
|
|
|
|
|
|
|
|
local nodename = minetest.get_node(pos).name
|
|
|
|
|
|
|
|
if nodename == modname .. ":root_alive" then return pos end
|
|
|
|
|
|
|
|
if not blockgame.item_matches(nodename, {
|
|
|
|
modname .. ":sapling",
|
|
|
|
modname .. ":log_alive",
|
|
|
|
}) then return end
|
|
|
|
|
|
|
|
pos = pos + blockgame.vector.dirs.down
|
|
|
|
end
|
|
|
|
end
|
|
|
|
]]--
|
|
|
|
|
2023-10-17 08:17:13 +00:00
|
|
|
blockgame.register_increasing_abm({
|
|
|
|
id = modname .. ":grow_sapling",
|
|
|
|
label = "grow sapling",
|
|
|
|
nodenames = {sapling},
|
|
|
|
neighbors = {"group:dirty", log_alive},
|
|
|
|
interval = 15,
|
|
|
|
chance = 4,
|
|
|
|
rate = function (pos, node, data)
|
2023-10-17 14:28:58 +00:00
|
|
|
-- TODO: find connected living logs and leaves, and nearby light levels, and soil richness near roots, to calculate growth rate.
|
2023-10-17 08:17:13 +00:00
|
|
|
return data.value + math.random(1, 99)
|
|
|
|
end,
|
|
|
|
check = function (pos, node, data)
|
|
|
|
if data.value < 200 then return false end
|
|
|
|
|
|
|
|
local below = pos + blockgame.vector.dirs.down
|
|
|
|
local below_name = minetest.get_node(below).name
|
|
|
|
if not supports_sapling(below_name) then return false end
|
|
|
|
|
|
|
|
local above = pos + blockgame.vector.dirs.up
|
|
|
|
if minetest.get_node(above).name ~= "air" then return false end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end,
|
|
|
|
action = function (pos, node, data)
|
|
|
|
-- TODO: decrease energy (`data.value`) when growing, but don't completely reset it to 0.
|
|
|
|
-- (this will require the api adding support for increasing_abm actions modifying their data.)
|
|
|
|
local above = pos + blockgame.vector.dirs.up
|
|
|
|
|
2023-10-17 14:13:54 +00:00
|
|
|
-- grow up, with a chance to stop growing.
|
2023-10-17 08:17:13 +00:00
|
|
|
if not blockgame.chance(4) then
|
|
|
|
minetest.set_node(above, {name = sapling})
|
|
|
|
end
|
|
|
|
|
2023-10-17 14:13:54 +00:00
|
|
|
local below = pos + blockgame.vector.dirs.down
|
|
|
|
-- if this tree have already grown at least once, create a log...
|
|
|
|
if blockgame.item_matches(minetest.get_node(below).name, {
|
|
|
|
modname .. ":root_alive",
|
|
|
|
modname .. ":log_alive",
|
|
|
|
}) then
|
|
|
|
minetest.set_node(pos, {name = log_alive})
|
|
|
|
else
|
|
|
|
-- ... otherwise, create a root
|
|
|
|
minetest.set_node(pos, {name = modname .. ":root_alive"})
|
|
|
|
end
|
|
|
|
|
|
|
|
-- grow out leaves to the sides.
|
2023-10-17 08:17:13 +00:00
|
|
|
local sides = blockgame.vector.get_sides_of(pos)
|
|
|
|
for _, side in pairs(sides) do
|
2023-10-17 08:23:53 +00:00
|
|
|
blockgame.attempt_place(side, {name = leaves_growing})
|
2023-10-17 08:17:13 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
})
|