96 lines
2.4 KiB
Lua
96 lines
2.4 KiB
Lua
local modname = minetest.get_current_modname()
|
|
local api = blockgame.tree
|
|
local vec = blockgame.vector
|
|
|
|
-- NODE NAMES
|
|
|
|
local log = modname .. ":log"
|
|
local log_alive = modname .. ":log_alive"
|
|
local leaves = modname .. ":leaves"
|
|
local leaves_alive = modname .. ":leaves_alive"
|
|
local root = modname .. ":root"
|
|
|
|
-- END OF NODE NAMES
|
|
-- LOCALS CACHE
|
|
|
|
local all_sides_except_up = blockgame.shallow_copy_table(blockgame.vector.dirs)
|
|
all_sides_except_up.up = nil
|
|
|
|
-- END OF LOCALS CACHE
|
|
|
|
|
|
|
|
local function extend_leaves_from (pos)
|
|
local side = vec.random_side()
|
|
blockgame.attempt_place(pos + side, {name = leaves_alive})
|
|
end
|
|
|
|
|
|
local function spread_roots_from (source)
|
|
local root_pos = blockgame.random_walk({
|
|
pos = source,
|
|
check = function (pos)
|
|
local name = minetest.get_node(pos).name
|
|
if name == log_alive then return true end
|
|
if name == root then return true end
|
|
return false
|
|
end,
|
|
neighborhood = all_sides_except_up,
|
|
})
|
|
if not root_pos then return false end
|
|
|
|
|
|
local root_node = minetest.get_node(root_pos)
|
|
|
|
if minetest.get_node(root_pos + blockgame.vector.dirs.up).name == log_alive then
|
|
minetest.set_node(root_pos, {name = root})
|
|
return true
|
|
end
|
|
|
|
local side = blockgame.random_element(all_sides_except_up)
|
|
local target_pos = root_pos + side
|
|
if blockgame.chance(2) then target_pos = vec.get_below(root_pos) end
|
|
|
|
if minetest.get_item_group(minetest.get_node(target_pos), "dirty") then
|
|
return minetest.set_node(target_pos, {name = root})
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
blockgame.register_abm({
|
|
label = "sapling grow",
|
|
nodenames = {"bg_tree:sapling"},
|
|
neighbors = {"group:dirty", log_alive},
|
|
interval = 15,
|
|
chance = 4,
|
|
action = function (pos, node, active_object_count, active_object_count_wider)
|
|
local below = vec.get_below(pos)
|
|
|
|
if blockgame.chance(4) then
|
|
local root_source = api.find_bottom_log(pos, 8)
|
|
if root_source ~= nil then
|
|
spread_roots_from(root_source + blockgame.vector.dirs.down)
|
|
end
|
|
end
|
|
|
|
if blockgame.chance(2) then
|
|
extend_leaves_from(pos)
|
|
end
|
|
|
|
if blockgame.chance(2) then
|
|
local side = vec.random_side()
|
|
local target = pos + side
|
|
|
|
blockgame.attempt_place(target, {name = log_alive})
|
|
end
|
|
|
|
if blockgame.chance(4) then
|
|
minetest.set_node(pos, {name = log_alive})
|
|
|
|
if minetest.get_node(below).name == log_alive and blockgame.chance(4) then return end
|
|
|
|
blockgame.attempt_place(pos + vector.new(0, 1, 0), {name = modname .. ":sapling"})
|
|
end
|
|
end,
|
|
})
|