diff --git a/mods/default/schematics/snowy_pine_tree_from_sapling.mts b/mods/default/schematics/snowy_pine_tree_from_sapling.mts new file mode 100644 index 00000000..0692049a Binary files /dev/null and b/mods/default/schematics/snowy_pine_tree_from_sapling.mts differ diff --git a/mods/default/trees.lua b/mods/default/trees.lua index 48718e5d..c93fdabc 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -1,10 +1,10 @@ +local random = math.random + -- -- Grow trees from saplings -- --- 'Can grow' function - -local random = math.random +-- 'can grow' function function default.can_grow(pos) local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) @@ -24,6 +24,39 @@ function default.can_grow(pos) end +-- 'is snow nearby' function + +local function is_snow_nearby(pos) + local x, y, z = pos.x, pos.y, pos.z + local c_snow = minetest.get_content_id("default:snow") + local c_snowblock = minetest.get_content_id("default:snowblock") + local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow") + + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = x - 1, y = y - 1, z = z - 1}, + {x = x + 1, y = y + 1, z = z + 1} + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + for yy = y - 1, y + 1 do + for zz = z - 1, z + 1 do + local vi = a:index(x - 1, yy, zz) + for xx = x - 1, x + 1 do + local nodid = data[vi] + if nodid == c_snow or nodid == c_snowblock or nodid == c_dirtsnow then + return true + end + vi = vi + 1 + end + end + end + + return false +end + + -- Sapling ABM minetest.register_abm({ @@ -57,8 +90,11 @@ minetest.register_abm({ elseif node.name == "default:pine_sapling" then minetest.log("action", "A pine sapling grows into a tree at ".. minetest.pos_to_string(pos)) + local snow = is_snow_nearby(pos) if mapgen == "v6" then - default.grow_pine_tree(pos) + default.grow_pine_tree(pos, snow) + elseif snow then + default.grow_new_snowy_pine_tree(pos) else default.grow_new_pine_tree(pos) end @@ -199,7 +235,8 @@ function default.grow_jungle_tree(pos, bad) local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) local data = vm:get_data() - add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, height, 3, 30, false) + add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, + height, 3, 30, false) -- Roots for z_dist = -1, 1 do @@ -240,7 +277,7 @@ local function add_snow(data, vi, c_air, c_ignore, c_snow) end end -function default.grow_pine_tree(pos) +function default.grow_pine_tree(pos, snow) local x, y, z = pos.x, pos.y, pos.z local maxy = y + random(9, 13) -- Trunk top @@ -249,32 +286,15 @@ function default.grow_pine_tree(pos) local c_pine_tree = minetest.get_content_id("default:pine_tree") local c_pine_needles = minetest.get_content_id("default:pine_needles") local c_snow = minetest.get_content_id("default:snow") - local c_snowblock = minetest.get_content_id("default:snowblock") - local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow") local vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( - {x = x - 3, y = y - 1, z = z - 3}, + {x = x - 3, y = y, z = z - 3}, {x = x + 3, y = maxy + 3, z = z + 3} ) local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) local data = vm:get_data() - -- Scan for snow nodes near sapling to enable snow on branches - local snow = false - for yy = y - 1, y + 1 do - for zz = z - 1, z + 1 do - local vi = a:index(x - 1, yy, zz) - for xx = x - 1, x + 1 do - local nodid = data[vi] - if nodid == c_snow or nodid == c_snowblock or nodid == c_dirtsnow then - snow = true - end - vi = vi + 1 - end - end - end - -- Upper branches layer local dev = 3 for yy = maxy - 1, maxy + 1 do @@ -350,7 +370,8 @@ function default.grow_pine_tree(pos) end -- Trunk - data[a:index(x, y, z)] = c_pine_tree -- Force-place lowest trunk node to replace sapling + -- Force-place lowest trunk node to replace sapling + data[a:index(x, y, z)] = c_pine_tree for yy = y + 1, maxy do local vi = a:index(x, yy, z) local node_id = data[vi] @@ -369,42 +390,57 @@ end -- New apple tree function default.grow_new_apple_tree(pos) - local path = minetest.get_modpath("default") .. "/schematics/apple_tree_from_sapling.mts" + local path = minetest.get_modpath("default") .. + "/schematics/apple_tree_from_sapling.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, - path, 0, nil, false) + path, "0", nil, false) end -- New jungle tree function default.grow_new_jungle_tree(pos) - local path = minetest.get_modpath("default") .. "/schematics/jungle_tree_from_sapling.mts" + local path = minetest.get_modpath("default") .. + "/schematics/jungle_tree_from_sapling.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, - path, 0, nil, false) + path, "0", nil, false) end -- New pine tree function default.grow_new_pine_tree(pos) - local path = minetest.get_modpath("default") .. "/schematics/pine_tree_from_sapling.mts" + local path = minetest.get_modpath("default") .. + "/schematics/pine_tree_from_sapling.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, - path, 0, nil, false) + path, "0", nil, false) +end + + +-- New snowy pine tree + +function default.grow_new_snowy_pine_tree(pos) + local path = minetest.get_modpath("default") .. + "/schematics/snowy_pine_tree_from_sapling.mts" + minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, + path, "random", nil, false) end -- New acacia tree function default.grow_new_acacia_tree(pos) - local path = minetest.get_modpath("default") .. "/schematics/acacia_tree_from_sapling.mts" + local path = minetest.get_modpath("default") .. + "/schematics/acacia_tree_from_sapling.mts" minetest.place_schematic({x = pos.x - 4, y = pos.y - 1, z = pos.z - 4}, - path, random, nil, false) + path, "random", nil, false) end -- New aspen tree function default.grow_new_aspen_tree(pos) - local path = minetest.get_modpath("default") .. "/schematics/aspen_tree_from_sapling.mts" + local path = minetest.get_modpath("default") .. + "/schematics/aspen_tree_from_sapling.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, - path, 0, nil, false) + path, "0", nil, false) end