function ebiometrees.grow_closure(nextstage) local function growtree(pos) minetest.set_node(pos, {name=nextstage}) end return growtree end function ebiometrees.where_to_grow_trunk_closure(grow_preferences, leaves_name) local function where_to_grow_trunk(pos) for _, directions in ipairs(grow_preferences) do table.shuffle(directions) local candidate_dir = directions[1] local candidate = vector.copy(pos):add(candidate_dir) local node = minetest.get_node_or_nil(candidate) corner1 = pos:add({x=-1, y=-1, z=-1}):add(candidate_dir:multiply(2)) corner2 = pos:add({x= 1, y= 1, z= 1}):add(candidate_dir:multiply(2)) local spacious, _ = minetest.find_nodes_in_area( corner1, corner2, {"group:treetrunk", "group:dirt" } ) if node and node.name == leaves_name and #spacious == 0 then return candidate end end end return where_to_grow_trunk end function ebiometrees.grow_trunk_closure(trunk_terminal_name, grow_preferences, leaves_name, grow_limit) local function grow_trunk(pos) local meta = minetest.get_meta(pos) if meta:get_int("ebiometrees:distance") > grow_limit then return end local where = ebiometrees.where_to_grow_trunk_closure(grow_preferences, leaves_name) local there = where(pos) if there then minetest.set_node(there, {name=trunk_terminal_name}) local newmeta = minetest.get_meta(there) newmeta:set_int("ebiometrees:distance", meta:get_int("ebiometrees:distance")+1) meta:set_int("ebiometrees:distance", meta:get_int("ebiometrees:distance")+1) end end return grow_trunk end function ebiometrees.grow_leaves_closure(leaves_name) local function grow_leaves(pos) local free_node = minetest.find_node_near(pos, 1, "air") if free_node then minetest.set_node(free_node, {name=leaves_name}) end return true end return grow_leaves end function ebiometrees.tree_timer_lifecycle_closure(tree_name) leaves_name = tree_name.."_leaves" terminal_name = tree_name.."_trunk_growing_terminal" nextstage = tree_name.."_trunk_normal_terminal" grow_preferences = ebiometrees.registered_trees[tree_name]["growth_preferences"] age_max = ebiometrees.registered_trees[tree_name]["age_max"] grow_limit = ebiometrees.registered_trees[tree_name]["growth_limit"] local grow_trunk = ebiometrees.grow_trunk_closure(terminal_name, grow_preferences, leaves_name, grow_limit) local grow_leaves = ebiometrees.grow_leaves_closure(leaves_name) function tree_timer_lifecycle(pos) local meta = minetest.get_meta(pos) meta:set_int("ebiometrees:age", meta:get_int("ebiometrees:age")+1) grow_trunk(pos) grow_leaves(pos) if nextstage then if meta:get_int("ebiometrees:age") > age_max then minetest.set_node(pos, {name=nextstage}) end end return true end return tree_timer_lifecycle end