5 local random = math.random
7 local function can_grow(pos)
8 local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
12 local name_under = node_under.name
13 local is_soil = minetest.get_item_group(name_under, "soil")
20 minetest.register_abm({
21 nodenames = {"default:sapling"},
24 action = function(pos, node)
25 if not can_grow(pos) then
29 minetest.log("action", "A sapling grows into a tree at "..minetest.pos_to_string(pos))
30 default.grow_tree(pos, random(1, 4) == 1)
34 minetest.register_abm({
35 nodenames = {"default:junglesapling"},
38 action = function(pos, node)
39 if not can_grow(pos) then
43 minetest.log("action", "A jungle sapling grows into a tree at "..
44 minetest.pos_to_string(pos))
45 default.grow_jungletree(pos)
50 local c_air = minetest.get_content_id("air")
51 local c_apple = minetest.get_content_id("default:apple")
53 local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid,
54 height, size, iters, is_apple_tree)
55 local x, y, z = pos.x, pos.y, pos.z
58 for y_dist = 0, height - 1 do
59 local vi = a:index(x, y + y_dist, z)
60 if y_dist == 0 or data[vi] == c_air or data[vi] == leaves_cid then
65 -- Force leaves near the trunk
67 for y_dist = -size, 1 do
68 local vi = a:index(x - 1, y + height + y_dist, z + z_dist)
70 if data[vi] == c_air then
71 if is_apple_tree and random(1, 8) == 1 then
82 -- Randomly add leaves in 2x2x2 clusters.
84 local clust_x = x + random(-size, size - 1)
85 local clust_y = y + height + random(-size, 0)
86 local clust_z = z + random(-size, size - 1)
91 local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi)
92 if data[vi] == c_air then
93 if is_apple_tree and random(1, 8) == 1 then
106 local c_tree = minetest.get_content_id("default:tree")
107 local c_leaves = minetest.get_content_id("default:leaves")
109 function default.grow_tree(pos, is_apple_tree, bad)
111 NOTE: Tree-placing code is currently duplicated in the engine
112 and in games that have saplings; both are deprecated but not
116 error("Deprecated use of default.grow_tree")
119 local x, y, z = pos.x, pos.y, pos.z
120 local height = random(4, 5)
122 local vm = minetest.get_voxel_manip()
123 local minp, maxp = vm:read_from_map(
124 {x = pos.x - 2, y = pos.y, z = pos.z - 2},
125 {x = pos.x + 2, y = pos.y + height + 1, z = pos.z + 2}
127 local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
128 local data = vm:get_data()
130 add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree)
137 local c_jungletree = minetest.get_content_id("default:jungletree")
138 local c_jungleleaves = minetest.get_content_id("default:jungleleaves")
140 function default.grow_jungletree(pos, bad)
142 NOTE: Tree-placing code is currently duplicated in the engine
143 and in games that have saplings; both are deprecated but not
147 error("Deprecated use of default.grow_jungletree")
150 local x, y, z = pos.x, pos.y, pos.z
151 local height = random(8, 12)
153 local vm = minetest.get_voxel_manip()
154 local minp, maxp = vm:read_from_map(
155 {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3},
156 {x = pos.x + 3, y = pos.y + height + 1, z = pos.z + 3})
157 local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp})
158 local data = vm:get_data()
160 add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, height, 3, 30, false)
163 for z_dist = -1, 1 do
164 local vi_1 = a:index(x - 1, y - 1, z + z_dist)
165 local vi_2 = a:index(x - 1, y, z + z_dist)
166 for x_dist = -1, 1 do
167 if random(1, 3) >= 2 then
168 if data[vi_1] == c_air then
169 data[vi_1] = c_jungletree
170 elseif data[vi_2] == c_air then
171 data[vi_2] = c_jungletree