diff --git a/.luacheckrc b/.luacheckrc index d999c36..3664db6 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -9,7 +9,7 @@ globals = { read_globals = { string = {fields = {"split"}}, - table = {fields = {"copy", "getn"}}, + table = {fields = {"copy", "getn", "shuffle"}}, -- Builtin "vector", "ItemStack", diff --git a/mods/ebiometrees/sapling.lua b/mods/ebiometrees/sapling.lua index 7249fcc..34ca57b 100644 --- a/mods/ebiometrees/sapling.lua +++ b/mods/ebiometrees/sapling.lua @@ -1,8 +1,13 @@ ebiometrees = {} +ebiometrees.directions = { + up = vector.new( 0, 1, 0), + down = vector.new( 0, -1, 0), + north = vector.new( 0, 0, 1), + east = vector.new( 1, 0, 0), + south = vector.new( 0, 0, -1), + west = vector.new(-1, 0, 0) +} -function ebiometrees.is_leaves_can_grow_here(pos) - return false -end function ebiometrees.grow_closure(nextstage) local function growtree(pos) @@ -11,7 +16,38 @@ function ebiometrees.grow_closure(nextstage) return growtree end -function ebiometrees.leaves_grower(leaves_name) +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) + if node and node.name == leaves_name + then + return candidate + end + end + end + return where_to_grow_trunk +end + +function ebiometrees.grow_trunk_closure(trunk_terminal_name, grow_preferences, leaves_name) + local function grow_trunk(pos) + 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}) + 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 @@ -23,6 +59,27 @@ function ebiometrees.leaves_grower(leaves_name) return grow_leaves end + +function ebiometrees.tree_grower(leaves_name, grow_preferences, terminal_name, nextstage, age_max) + local grow_trunk = ebiometrees.grow_trunk_closure(terminal_name, grow_preferences, leaves_name) + local grow_leaves = ebiometrees.grow_leaves_closure(leaves_name) + local function grow_tree(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 grow_tree +end + function ebiometrees.root_sapling(pos) minetest.set_node(pos, {name="ebiome:oak_sprout"}) return false diff --git a/mods/ebiometrees/tree.lua b/mods/ebiometrees/tree.lua index e6515c9..be0b012 100644 --- a/mods/ebiometrees/tree.lua +++ b/mods/ebiometrees/tree.lua @@ -1,5 +1,8 @@ local function growth_timer(pos) minetest.get_node_timer(pos):start(3) + local meta = minetest.get_meta(pos) + meta:set_int("ebiometrees:age", 0) + meta:mark_as_private("ebiometrees:age") end @@ -61,6 +64,7 @@ function ebiometrees.register_tree(modname, basename, data) -- registers corresponding trunk nodes local trunk_groups = table.copy(data.groups) trunk_groups.choppy = 2 -- TODO: customizations + trunk_groups.treetrunk = 1 local trunk_types = {"growing", "normal"} local trunk_subtypes = {"terminal", "straight", "corner", "tjunction", "t2junction", "xjunction", @@ -137,8 +141,21 @@ function ebiometrees.register_tree(modname, basename, data) } if trunk_type == "growing" then - nodespec.on_timer = ebiometrees.leaves_grower( - modname..":"..basename.."_leaves") + nodespec.on_timer = ebiometrees.tree_grower( + modname..":"..basename.."_leaves", + { + {ebiometrees.directions.up}, + { + ebiometrees.directions.north, + ebiometrees.directions.east, + ebiometrees.directions.south, + ebiometrees.directions.west + } + }, + modname..":"..basename.."_trunk_growing_terminal", + modname..":"..basename.."_trunk_normal_"..trunk_subtype, + 20 + ) end minetest.register_node( modname..":"..basename.."_trunk_"..trunk_type.."_"..trunk_subtype,