blockgame/mods/bg_tree/grow_sapling.lua

90 lines
2.6 KiB
Lua
Raw Normal View History

local modname = minetest.get_current_modname()
-- NODE NAMES
local sapling = modname .. ":sapling"
local log_alive = modname .. ":log_alive"
local leaves_growing = modname .. ":leaves_growing"
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
-- 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
]]--
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)
-- TODO: find connected living logs and leaves, and nearby light levels, and soil richness near roots, to calculate growth rate.
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
-- grow up, with a chance to stop growing.
if not blockgame.chance(4) then
minetest.set_node(above, {name = sapling})
end
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.
local sides = blockgame.vector.get_sides_of(pos)
for _, side in pairs(sides) do
blockgame.attempt_place(side, {name = leaves_growing})
end
end,
})