-- =================================================================== local random = math.random local safe_register_alias = ocutil.safe_register_alias -- =================================================================== local disable_lumberjack = minetest.setting_getbool ("disable_lumberjack" ) local enable_default_apple = minetest.setting_getbool ("enable_default_apple" ) local enable_slow_leaves = minetest.setting_getbool ("enable_slow_leaves" ) local enable_wonder = minetest.setting_getbool ("enable_wonder" ) -- =================================================================== local SAPLING_DEFAULT_GROW_CHANCE = 2 local SAPLING_DEFAULT_GROW_INTERVAL = 50 local SAPLING_DEFAULT_DROP_CHANCE = 20 if enable_wonder then SAPLING_DEFAULT_GROW_CHANCE = 2 SAPLING_DEFAULT_GROW_INTERVAL = 50 end -- =================================================================== local sapling_grow_chance = ocutil.numsetting ("sapling_grow_chance" ) local sapling_grow_interval = ocutil.numsetting ("sapling_grow_interval" ) local sapling_drop_chance = ocutil.numsetting ("sapling_drop_chance" ) -- =================================================================== if sapling_grow_chance == nil or sapling_grow_chance == 0 then sapling_grow_chance = SAPLING_DEFAULT_GROW_CHANCE end if sapling_grow_interval == nil or sapling_grow_interval == 0 then sapling_grow_interval = SAPLING_DEFAULT_GROW_INTERVAL end if sapling_drop_chance == nil or sapling_drop_chance == 0 then sapling_drop_chance = SAPLING_DEFAULT_DROP_CHANCE end -- =================================================================== minetest.register_node ("default:tree", { description = "Tree", tiles = { "default_tree_top.png" , "default_tree_top.png" , "default_tree.png" , } , paramtype2 = "facedir", is_ground_content = false, groups = { tree=1 , choppy=2 , oddly_breakable_by_hand=1, flammable=2 } , sounds = default.node_sound_wood_defaults() , on_place = minetest.rotate_node , workbench = true , }) -- =================================================================== default.goir = minetest.get_objects_inside_radius default.delete_nearby_coderfruit = function (pos) local objs = default.goir (pos, 2) for n = 1, #objs do if not objs [n]:is_player() then local obj = objs [n]:get_luaentity() if obj and obj.name and ocutil.starts_with (obj.name, "coderfruit:entity_") then objs [n]:remove() end end end end -- =================================================================== default.delete_leaves_chain = function (pos, nodename_sapling) local leaflist = {} local nextlist = {} local depth = 0 table.insert (leaflist, pos) default.delete_nearby_coderfruit (pos) while #leaflist > 0 and depth < 2 do for _,dpos in ipairs (leaflist) do local isdone isdone = false while not isdone do local lpos = minetest.find_node_near (dpos, 2, { "group:leaves" }) if lpos == nil then isdone = true else table.insert (nextlist, lpos) minetest.remove_node (lpos) default.delete_nearby_coderfruit (lpos) local rn = random (1, sapling_drop_chance) if rn == 1 then minetest.add_item (lpos, nodename_sapling) end end end isdone = false while not isdone do local lpos = minetest.find_node_near (dpos, 3, { "group:nodefruit" }) if lpos == nil then isdone = true else minetest.remove_node (lpos) end end end leaflist = nextlist nextlist = {} depth = depth + 1 end end -- =================================================================== default.drop_tree_column = function (pos, nodename_sapling) local del_node = minetest.get_node (pos) if del_node == nil then return end if del_node.name ~= "air" then return end local uppos = ocutil.clone_table (pos) local is_done = false while not is_done do uppos.y = uppos.y + 1 local upnode = minetest.get_node (uppos) if upnode == nil then return end local upname = upnode.name if upname:gsub ("wood" , "") ~= upname or upname:gsub ("_top" , "") ~= upname or upname:gsub ("trunk" , "") ~= upname or upname:gsub ("leaves" , "") ~= upname or upname:gsub ("needles" , "") ~= upname then is_done = true elseif upname == "air" then if uppos.y - pos.y > 10 then return end else return end end if uppos.y - pos.y < 1 then ocutil.log ("[default] Internal error: drop tree column") return end local cppos = ocutil.clone_table (pos) while true do local upnode = minetest.get_node (uppos) if upnode == nil then return end local upname = upnode.name if upname:gsub ("wood" , "") ~= upname or upname:gsub ("_top" , "") ~= upname or upname:gsub ("trunk" , "") ~= upname or upname:gsub ("leaves" , "") ~= upname or upname:gsub ("needles" , "") ~= upname then minetest.add_node (cppos, { name = upname }) minetest.remove_node (uppos) default.delete_leaves_chain (uppos, nodename_sapling) cppos.y = cppos.y + 1 uppos.y = uppos.y + 1 else return end end end -- =================================================================== local function register_alttree (basetype, uctype) local nodebase_sapling = basetype .. "_sapling" local nodename_sapling = "default:" .. nodebase_sapling local pngimage_sapling = "default_" .. nodebase_sapling .. ".png" local groups = { dig_immediate=3, flammable=2 } if basetype == "wonderhouse" then groups ["not_in_creative_inventory"] = 1 end minetest.register_node (nodename_sapling, { description = uctype .. " Tree Sapling" , drawtype = "plantlike" , groups = groups , paramtype = "light" , sounds = default.node_sound_defaults() , walkable = false , tiles = { pngimage_sapling } , inventory_image = pngimage_sapling , wield_image = pngimage_sapling , }) if basetype == "christmine" then return end if basetype == "scifi1" then return end if basetype == "scifi2" then return end if basetype == "wonderhouse" then return end local nodebase_tree = basetype .. "_tree" local nodename_tree = "default:" .. nodebase_tree local nodebase_trunk = basetype .. "_trunk" local nodename_trunk = "default:" .. nodebase_trunk local pngimage_trunk = "default_" .. nodebase_trunk .. ".png" local pngimage_top = "default_" .. basetype .. "_top.png" minetest.register_node (nodename_trunk, { description = uctype .. "Tree Trunk" , sounds = default.node_sound_wood_defaults() , tiles = { pngimage_top , pngimage_top , pngimage_trunk } , groups = { tree=1, snappy=1, choppy=2, oddly_breakable_by_hand=1 , flammable=2 } , after_dig_node = function (pos, oldnode) if disable_lumberjack then return end pos = ocutil.clone_table (pos) default.delete_leaves_chain (pos, nodename_sapling) for xi=-2,2 do for yi=0,3 do for zi=-2,2 do local npos = { x = pos.x + xi , y = pos.y + (yi * 2) , z = pos.z + zi , } default.drop_tree_column (npos, nodename_sapling) end end end end }) safe_register_alias (nodename_tree, nodename_trunk) local nodebase_leaves = basetype .. "_leaves" local nodename_leaves = "default:" .. nodebase_leaves local pngimage_leaves = "default_" .. nodebase_leaves .. ".png" local leaf_groups = { snappy = 3 , leafdecay = 3 , flammable = 2 , leaves = 1 } if basetype == "palm" or basetype == "date_palm" then leaf_groups = { snappy = 3 , flammable = 2 } end local dtleaves = "glasslike" if enable_slow_leaves then dtleaves = "allfaces_optional" end local description = uctype .. " Leaves" local visual_scale = 1 if basetype == "pine" then description = "Pine Needles" visual_scale = 1.3 end minetest.register_node (nodename_leaves , { description = description , drawtype = dtleaves , groups = leaf_groups , paramtype = "light" , sounds = default.node_sound_leaves_defaults() , tiles = { pngimage_leaves } , visual_scale = visual_scale , after_place_node = default.after_place_leaves , drop = { max_items = 1 , items = { { items = { nodename_sapling } , rarity = 20 } , { items = { nodename_leaves } } , } } , }) local nodebase_wood = basetype .. "_wood" local nodename_wood = "default:" .. nodebase_wood local pngimage_wood = "default_" .. nodebase_wood .. ".png" local param_wood = { description = uctype .. " Tree Wood" , is_ground_content = false , sounds = default.node_sound_wood_defaults() , tiles = { pngimage_wood } , groups = { snappy=1, choppy=2, oddly_breakable_by_hand=2 , flammable=3, wood=1 } , } if basetype == "acacia" or basetype == "aspen" or basetype == "jungle" or basetype == "pine" then param_wood.workbench = true end minetest.register_node (nodename_wood, param_wood) local planks = "default:" .. basetype .. "_planks" minetest.register_alias (planks, nodename_wood) minetest.register_craft ({ type = "shapeless" , output = nodename_wood .. " 4" , recipe = { nodename_trunk } , }) minetest.register_craft ({ type = "fuel" , recipe = nodename_sapling , burntime = 10 , }) end -- =================================================================== register_alttree ("acacia" , "Acacia" ) register_alttree ("aspen" , "Aspen" ) register_alttree ("axinite" , "Axinite" ) register_alttree ("beech" , "Beech" ) register_alttree ("big_apple" , "Big Apple" ) register_alttree ("birch" , "Birch" ) register_alttree ("cedar" , "Cedar" ) register_alttree ("cherry" , "Cherry" ) register_alttree ("christmine" , "Christmine" ) register_alttree ("conifer" , "Conifer" ) register_alttree ("date_palm" , "Date Palm" ) register_alttree ("iroko" , "Iroko" ) register_alttree ("fir" , "Fir" ) register_alttree ("jungle" , "Jungle" ) register_alttree ("lemon" , "Lemon" ) register_alttree ("maple" , "Maple" ) register_alttree ("oak" , "Oak" ) register_alttree ("palm" , "Palm" ) register_alttree ("pine" , "Pine" ) register_alttree ("poplar" , "Poplar" ) register_alttree ("rubber" , "Rubber" ) register_alttree ("scifi1" , "SciFi1" ) register_alttree ("scifi2" , "SciFi2" ) register_alttree ("sequoia" , "Sequoia" ) register_alttree ("spruce" , "Spruce" ) register_alttree ("willow" , "Willow" ) register_alttree ("wonderhouse" , "Wonderhouse" ) -- =================================================================== local function register_alttreefruit (basename, desc, vscale, selbox) local pngimage = "default_" .. basename .. ".png" minetest.register_node ("default:" .. basename, { description = desc , drawtype = "plantlike" , is_ground_content = false , paramtype = "light" , sunlight_propagates = true , sounds = default.node_sound_defaults() , visual_scale = vscale , walkable = false , tiles = { pngimage } , inventory_image = pngimage .. "^[transformR180" , wield_image = pngimage .. "^[transformR180" , selection_box = { type = "fixed" , fixed = selbox , } , groups = { fleshy = 3 , dig_immediate = 3 , flammable = 2 , attached_node = 1 , nodefruit = 1 , -- RJK: This part isn't advisable: -- leafdecay = 1, leafdecay_drop = 1 } , }) end -- ================================================================= -- Alt-Tree Fruit. -- These are obsolete and will be superseded by ne w fruit types in -- CoderFruit. register_alttreefruit ("coconut" , "Coconut" , 0.8, { -0.2, -0.5, -0.2, 0.2, 0, 0.2 }) register_alttreefruit ("date" , "Date" , 0.8, { -0.2, -0.5, -0.2, 0.2, 0, 0.2 }) register_alttreefruit ("fir_cone" , "Fir Cone" , 0.8, { -0.2, -0.5, -0.2, 0.2, 0, 0.2 }) register_alttreefruit ("spruce_cone" , "Spruce Cone" , 0.8, { -0.2, -0.5, -0.2, 0.2, 0, 0.2 }) -- =================================================================== function default.can_grow (pos, lax) local node_under = minetest.get_node_or_nil ({x = pos.x, y = pos.y - 1, z = pos.z}) if not node_under then return false end local nm = node_under.name local ok = false if (minetest.get_item_group (nm, "soil")) then ok = true end if lax == true then if (minetest.get_item_group (nm, "sand" )) then ok = true end if (minetest.get_item_group (nm, "stone" )) then ok = true end end if ok == false then return false end if not lax then local light_level = minetest.get_node_light (pos) if not light_level or light_level < 13 then return false end end return true end -- =================================================================== 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 -- =================================================================== function default.sapling_to_tree (pos, param) if param.mtsfile == nil then return end local force_flag = param.force_flag local orient = param.orient local pos_delta = param.pos_delta local path = minetest.get_modpath ("default") .. "/schematics/" .. param.mtsfile minetest.add_node (pos, { name = "air" }) if force_flag == nil then force_flag = false end if orient == nil then orient = "0" end local ppos = { x = pos.x + pos_delta.x , y = pos.y + pos_delta.y , z = pos.z + pos_delta.z , } minetest.place_schematic (ppos, path, orient, nil, force_flag) end -- =================================================================== tree_mparam = {} -- =================================================================== tree_mparam ["default:acacia_sapling" ] = { mtsfile = "acacia_tree_from_sapling.mts" , orient = "random" , pos_delta = { x=-4, y=-1, z=-4 } , } tree_mparam ["default:aspen_sapling" ] = { mtsfile = "aspen_tree_from_sapling.mts" , pos_delta = { x=-2, y=-1, z=-2 } , } tree_mparam ["default:beech_sapling" ] = { mtsfile = "beech_tree.mts" , pos_delta = { x=-4, y=0, z=-4 } , } tree_mparam ["default:big_apple_sapling" ] = { mtsfile = "big_apple_tree.mts" , pos_delta = { x=-8, y=0, z=-8 } , } tree_mparam ["default:birch_sapling" ] = { mtsfile = "birch_tree.mts" , pos_delta = { x=-7, y=0, z=-7 } , } tree_mparam ["default:cedar_sapling" ] = { mtsfile = "cedar_tree.mts" , pos_delta = { x=-9, y=0, z=-6 } , } tree_mparam ["default:cherry_sapling" ] = { mtsfile = "cherry_tree.mts" , pos_delta = { x=-4, y=0, z=-4 } , } tree_mparam ["default:christmine_sapling" ] = { mtsfile = "christmine_tree.mts" , pos_delta = { x=-13, y=0, z=-13 } , } tree_mparam ["default:conifer_sapling" ] = { mtsfile = "conifer_tree.mts" , pos_delta = { x=-3, y=0, z=-3 } , } tree_mparam ["default:date_palm_sapling" ] = { mtsfile = "date_palm_tree.mts" , pos_delta = { x=-9, y=0, z=-10 } , } tree_mparam ["default:fir_sapling" ] = { mtsfile = "fir_tree.mts" , pos_delta = { x=-6, y=0, z=-6 } , } tree_mparam ["default:iroko_sapling" ] = { mtsfile = "iroko_tree.mts" , pos_delta = { x=-5, y=0, z=-5 } , } -- "jungle" tree is a special case that doesn't have an entry in this -- list. tree_mparam ["default:lemon_sapling" ] = { mtsfile = "lemon_tree.mts" , pos_delta = { x=-2, y=0, z=-2 } , } tree_mparam ["default:maple_sapling" ] = { mtsfile = "maple_tree.mts" , pos_delta = { x=-3, y=0, z=-3 } , } tree_mparam ["default:oak_sapling" ] = { mtsfile = "oak_tree.mts" , pos_delta = { x=-13, y=0, z=-14 } , } tree_mparam ["default:palm_sapling" ] = { mtsfile = "palm_tree.mts" , pos_delta = { x=-6, y=0, z=-3 } , } tree_mparam ["default:poplar_sapling" ] = { mtsfile = "poplar_tree.mts" , pos_delta = { x=-2, y=0, z=-2 } , } tree_mparam ["default:rubber_sapling" ] = { mtsfile = "rubber_tree.mts" , pos_delta = { x=-7, y=0, z=-8 } , } tree_mparam ["default:sequoia_sapling" ] = { mtsfile = "sequoia_tree.mts" , pos_delta = { x=-7, y=0, z=-8 } , } tree_mparam ["default:spruce_sapling" ] = { mtsfile = "spruce_tree.mts" , pos_delta = { x=-8, y=0, z=-9 } , } tree_mparam ["default:willow_sapling" ] = { mtsfile = "willow_tree.mts" , pos_delta = { x=-11, y=0, z=-11 } , } tree_mparam ["default:wonderhouse_sapling" ] = { force_flag = true , mtsfile = "wonderhouse_tree.mts" , pos_delta = { x=-5, y=-1, z=-7 } , } -- =================================================================== local sapling_nodenames = { "default:junglesapling" , "default:pine_sapling" , "default:sapling" , "default:scifi1_sapling" , "default:scifi2_sapling" , } for k,v in pairs (tree_mparam) do table.insert (sapling_nodenames, k) end -- =================================================================== minetest.register_abm ({ nodenames = sapling_nodenames , catch_up = false , chance = sapling_grow_chance , interval = sapling_grow_interval , action = function (pos, node) local lax = false if node.name == "default:scifi1_sapling" or node.name == "default:scifi2_sapling" or node.name == "default:wonderhouse_sapling" then lax = true end if not default.can_grow (pos, lax) then return end local mapgen = minetest.get_mapgen_params().mgname local mparam = tree_mparam [node.name] if mparam ~= nil then default.sapling_to_tree (pos, mparam) return end if node.name == "default:sapling" then if mapgen == "v6" then default.grow_tree (pos, random (1, 4) == 1) else -- grow_new_apple_tree default.sapling_to_tree (pos, { mtsfile = "apple_tree_from_sapling.mts" , pos_delta = { x=-2, y=-1, z=-2 } , }) end elseif node.name == "default:junglesapling" then if mapgen == "v6" then default.grow_jungle_tree (pos) else -- grow_new_jungle_tree default.sapling_to_tree (pos, { mtsfile = "jungle_tree_from_sapling.mts" , orient = "random" , pos_delta = { x=-2, y=-1, z=-2 } , }) end elseif node.name == "default:scifi1_sapling" then default.grow_new_scifi1_tree (pos) elseif node.name == "default:scifi2_sapling" then default.grow_new_scifi2_tree (pos) elseif node.name == "default:pine_sapling" then local snow = is_snow_nearby (pos) if mapgen == "v6" then default.grow_pine_tree (pos, snow) elseif snow then default.sapling_to_tree (pos, { mtsfile = "snowy_pine_tree_from_sapling.mts" , orient = "random" , pos_delta = { x=-2, y=-1, z=-2 } , }) else default.sapling_to_tree (pos, { mtsfile = "pine_tree_from_sapling.mts" , pos_delta = { x=-2, y=-1, z=-2 } , }) end end end }) -- =================================================================== -- -- Tree generation -- Apple tree and jungle tree trunk and leaves function local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid, height, size, iters, is_apple_tree) local x, y, z = pos.x, pos.y, pos.z local c_air = minetest.get_content_id("air") local c_ignore = minetest.get_content_id("ignore") local c_apple = minetest.get_content_id("default:apple") -- Trunk data[a:index(x, y, z)] = tree_cid -- Force-place lowest trunk node to replace sapling for yy = y + 1, y + height - 1 do local vi = a:index(x, yy, z) local node_id = data[vi] if node_id == c_air or node_id == c_ignore or node_id == leaves_cid then data[vi] = tree_cid end end -- Force leaves near the trunk for z_dist = -1, 1 do for y_dist = -size, 1 do local vi = a:index(x - 1, y + height + y_dist, z + z_dist) for x_dist = -1, 1 do if data[vi] == c_air or data[vi] == c_ignore then if is_apple_tree and enable_default_apple and random (1, 8) == 1 then data[vi] = c_apple else data[vi] = leaves_cid end end vi = vi + 1 end end end -- Randomly add leaves in 2x2x2 clusters. for i = 1, iters do local clust_x = x + random(-size, size - 1) local clust_y = y + height + random(-size, 0) local clust_z = z + random(-size, size - 1) for xi = 0, 1 do for yi = 0, 1 do for zi = 0, 1 do local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi) if data[vi] == c_air or data[vi] == c_ignore then if is_apple_tree and enable_default_apple and random (1, 8) == 1 then data[vi] = c_apple else data[vi] = leaves_cid end end end end end end end -- Apple tree function default.grow_tree (pos, is_apple_tree, bad) --[[ NOTE: Tree-placing code is currently duplicated in the engine and in games that have saplings; both are deprecated but not replaced yet --]] if bad then error("Deprecated use of default.grow_tree") end local x, y, z = pos.x, pos.y, pos.z local height = random(4, 5) local c_tree = minetest.get_content_id("default:tree") local c_leaves = minetest.get_content_id("default:leaves") local vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( {x = pos.x - 2, y = pos.y, z = pos.z - 2}, {x = pos.x + 2, y = pos.y + height + 1, z = pos.z + 2} ) local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) local data = vm:get_data() add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree) vm:set_data(data) vm:write_to_map() vm:update_map() end -- Jungle tree function default.grow_jungle_tree(pos, bad) --[[ NOTE: Jungletree-placing code is currently duplicated in the engine and in games that have saplings; both are deprecated but not replaced yet --]] if bad then error("Deprecated use of default.grow_jungle_tree") end local x, y, z = pos.x, pos.y, pos.z local height = random(8, 12) local c_air = minetest.get_content_id("air") local c_ignore = minetest.get_content_id("ignore") local c_jungletree = minetest.get_content_id("default:jungletree") local c_jungleleaves = minetest.get_content_id("default:jungleleaves") local vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3}, {x = pos.x + 3, y = pos.y + height + 1, z = pos.z + 3} ) 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) -- Roots for z_dist = -1, 1 do local vi_1 = a:index(x - 1, y - 1, z + z_dist) local vi_2 = a:index(x - 1, y, z + z_dist) for x_dist = -1, 1 do if random(1, 3) >= 2 then if data[vi_1] == c_air or data[vi_1] == c_ignore then data[vi_1] = c_jungletree elseif data[vi_2] == c_air or data[vi_2] == c_ignore then data[vi_2] = c_jungletree end end vi_1 = vi_1 + 1 vi_2 = vi_2 + 1 end end vm:set_data(data) vm:write_to_map() vm:update_map() end -- Pine tree from mg mapgen mod, design by sfan5, pointy top added by paramat local function add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) local node_id = data[vi] if node_id == c_air or node_id == c_ignore or node_id == c_snow then data[vi] = c_pine_needles end end local function add_snow(data, vi, c_air, c_ignore, c_snow) local node_id = data[vi] if node_id == c_air or node_id == c_ignore then data[vi] = c_snow end end 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 local c_air = minetest.get_content_id("air") local c_ignore = minetest.get_content_id("ignore") 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 vm = minetest.get_voxel_manip() local minp, maxp = vm:read_from_map( {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() -- Upper branches layer local dev = 3 for yy = maxy - 1, maxy + 1 do for zz = z - dev, z + dev do local vi = a:index(x - dev, yy, zz) local via = a:index(x - dev, yy + 1, zz) for xx = x - dev, x + dev do if random() < 0.95 - dev * 0.05 then add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) if snow then add_snow(data, via, c_air, c_ignore, c_snow) end end vi = vi + 1 via = via + 1 end end dev = dev - 1 end -- Centre top nodes add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, c_pine_needles) add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow, c_pine_needles) -- Paramat added a pointy top node if snow then add_snow(data, a:index(x, maxy + 3, z), c_air, c_ignore, c_snow) end -- Lower branches layer local my = 0 for i = 1, 20 do -- Random 2x2 squares of needles local xi = x + random(-3, 2) local yy = maxy + random(-6, -5) local zi = z + random(-3, 2) if yy > my then my = yy end for zz = zi, zi+1 do local vi = a:index(xi, yy, zz) local via = a:index(xi, yy + 1, zz) for xx = xi, xi + 1 do add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) if snow then add_snow(data, via, c_air, c_ignore, c_snow) end vi = vi + 1 via = via + 1 end end end local dev = 2 for yy = my + 1, my + 2 do for zz = z - dev, z + dev do local vi = a:index(x - dev, yy, zz) local via = a:index(x - dev, yy + 1, zz) for xx = x - dev, x + dev do if random() < 0.95 - dev * 0.05 then add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) if snow then add_snow(data, via, c_air, c_ignore, c_snow) end end vi = vi + 1 via = via + 1 end end dev = dev - 1 end -- Trunk -- 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] if node_id == c_air or node_id == c_ignore or node_id == c_pine_needles or node_id == c_snow then data[vi] = c_pine_tree end end vm:set_data(data) vm:write_to_map() vm:update_map() end -- =================================================================== function default.grow_new_scifi1_tree (pos) local path = minetest.get_modpath ("default") .. "/schematics/scifi1_tree.we" minetest.add_node (pos, { name = "air" }) ocutil.loadwe ({ x = pos.x, y = pos.y, z = pos.z } , path) end -- =================================================================== function default.grow_new_scifi2_tree (pos) local path = minetest.get_modpath ("default") .. "/schematics/scifi2_tree.we" minetest.add_node (pos, { name = "air" }) ocutil.loadwe ({ x = pos.x, y = pos.y, z = pos.z } , path) end -- =================================================================== if not enable_default_apple then minetest.register_abm ({ nodenames = { "default:apple" } , interval = 30 , chance = 1 , catch_up = false , action = function (pos, node) minetest.remove_node (pos) end , }) end -- =================================================================== function default.sapling_on_place(itemstack, placer, pointed_thing, sapling_name, minp_relative, maxp_relative, interval) -- Position of sapling local pos = pointed_thing.under local node = minetest.get_node_or_nil(pos) local pdef = node and minetest.registered_nodes[node.name] if pdef and pdef.on_rightclick and not (placer and placer:is_player() and placer:get_player_control().sneak) then return pdef.on_rightclick(pos, node, placer, itemstack, pointed_thing) end if not pdef or not pdef.buildable_to then pos = pointed_thing.above node = minetest.get_node_or_nil(pos) pdef = node and minetest.registered_nodes[node.name] if not pdef or not pdef.buildable_to then return itemstack end end local player_name = placer and placer:get_player_name() or "" -- Check sapling position for protection if minetest.is_protected(pos, player_name) then minetest.record_protection_violation(pos, player_name) return itemstack end -- Check tree volume for protection if minetest.is_area_protected( vector.add(pos, minp_relative), vector.add(pos, maxp_relative), player_name, interval) then minetest.record_protection_violation(pos, player_name) -- Print extra information to explain minetest.chat_send_player(player_name, itemstack:get_definition().description .. " will intersect protection " .. "on growth") return itemstack end minetest.log("action", player_name .. " places node " .. sapling_name .. " at " .. minetest.pos_to_string(pos)) local take_item = not (creative and creative.is_enabled_for and creative.is_enabled_for(player_name)) local newnode = {name = sapling_name} local ndef = minetest.registered_nodes[sapling_name] minetest.set_node(pos, newnode) -- Run callback if ndef and ndef.after_place_node then -- Deepcopy place_to and pointed_thing because callback can modify it if ndef.after_place_node(table.copy(pos), placer, itemstack, table.copy(pointed_thing)) then take_item = false end end -- Run script hook for _, callback in ipairs(minetest.registered_on_placenodes) do -- Deepcopy pos, node and pointed_thing because callback can modify them if callback(table.copy(pos), table.copy(newnode), placer, table.copy(node or {}), itemstack, table.copy(pointed_thing)) then take_item = false end end if take_item then itemstack:take_item() end return itemstack end -- =================================================================== safe_register_alias ("default:pine_needles" , "default:pine_leaves" ) safe_register_alias ("default:pinetree" , "default:pine_trunk" ) safe_register_alias ("default:jungleleaves" , "default:jungle_leaves" ) safe_register_alias ("default:junglesapling" , "default:jungle_sapling" ) safe_register_alias ("default:jungletree" , "default:jungle_trunk" ) safe_register_alias ("default:junglewood" , "default:jungle_wood" ) -- =================================================================== -- End of file.