--Makes pine tree function snow.make_pine(pos,snow) local env = minetest.env local perlin1 = env:get_perlin(112,3, 0.5, 150) --Clear ground. for x=-1,1 do for z=-1,1 do if env:get_node({x=pos.x+x,y=pos.y,z=pos.z+z}).name == "snow:snow" then env:remove_node({x=pos.x+x,y=pos.y,z=pos.z+z}) end end end --Make tree. for i=0, 4 do local env = minetest.env if i==1 or i==2 then for x=-1,1 do for z=-1,1 do local x = pos.x + x local z = pos.z + z env:add_node({x=x,y=pos.y+i,z=z},{name="snow:needles"}) if snow and x ~= 0 and z ~= 0 and perlin1:get2d({x=x,y=z}) > 0.53 then env:add_node({x=x,y=pos.y+i+1,z=z},{name="snow:snow"}) end end end end if i==3 or i==4 then local x = pos.x local y = pos.y+i local z = pos.z env:add_node({x=x+1,y=y,z=z},{name="snow:needles"}) env:add_node({x=x-1,y=y,z=z},{name="snow:needles"}) env:add_node({x=x,y=y,z=z+1},{name="snow:needles"}) env:add_node({x=x,y=y,z=z-1},{name="snow:needles"}) if snow then if perlin1:get2d({x=x+1,y=z}) > 0.53 then env:add_node({x=x+1,y=y+1,z=z},{name="snow:snow"}) end if perlin1:get2d({x=x+1,y=z}) > 0.53 then env:add_node({x=x-1,y=y+1,z=z},{name="snow:snow"}) end if perlin1:get2d({x=x,y=z+1}) > 0.53 then env:add_node({x=x,y=y+1,z=z+1},{name="snow:snow"}) end if perlin1:get2d({x=x,y=z-1}) > 0.53 then env:add_node({x=x,y=y+1,z=z-1},{name="snow:snow"}) end end end env:add_node({x=pos.x,y=pos.y+i,z=pos.z},{name="default:tree"}) end env:add_node({x=pos.x,y=pos.y+5,z=pos.z},{name="snow:needles"}) env:add_node({x=pos.x,y=pos.y+6,z=pos.z},{name="snow:needles"}) if snow and perlin1:get2d({x=pos.x,y=pos.z}) > 0.53 then env:add_node({x=pos.x,y=pos.y+7,z=pos.z},{name="snow:snow"}) end end --Snow biomes are found at 0.53 and greater perlin noise. minetest.register_on_generated(function(minp, maxp, seed) if maxp.y >= -10 then local debug = snow.debug --Should make things a bit faster. local env = minetest.env --Get map specific perlin local perlin1 = env:get_perlin(112,3, 0.5, 150) -- Assume X and Z lengths are equal local divlen = 16 local divs = (maxp.x-minp.x); local x0 = minp.x local z0 = minp.z local x1 = maxp.x local z1 = maxp.z --Speed hack: checks the corners and middle of the chunk for "snow biome". if not (perlin1:get2d({x=x0, y=z0}) > 0.53) and not (perlin1:get2d({x=x1, y=z1}) > 0.53) and not (perlin1:get2d({x=x0, y=z1}) > 0.53) and not (perlin1:get2d({x=x1, y=z0}) > 0.53) and not (perlin1:get2d({x=(x1-x0)/2, y=(z1-z0)/2}) > 0.53) then return end --Choose a biome type. local pr = PseudoRandom(seed+57) local biome = pr:next(1, 12) local icebergs = biome == 2 local icesheet = biome == 3 local alpine = biome == 11 or biome == 12 --rocky terrain local cool = biome == 9 or biome == 10 --only spawns ice on edge of water local icecave = biome == 5 local icehole = biome == 6 --icesheet with holes --Misc biome settings. local icy = pr:next(1, 2) == 2 --If enabled spawns ice in sand instead of snow blocks. local mossy = pr:next(1,2) == 1 --Spawns moss in snow. local shrubs = pr:next(1,2) == 1 --Spawns dry shrubs in snow. local pines = pr:next(1,2) == 1 --spawns pines. --Debugging function local biomeToString = function(num) if num == 1 or num == 7 or num == 8 or num == 4 then return "normal" elseif num == 2 then return "icebergs" elseif num == 3 then return "icesheet" elseif num == 5 then return "icecave" elseif num == 9 or num == 10 then return "cool" elseif num == 6 then return "icehole" elseif num == 11 or num == 12 then return "alpine" else return "unknown "..num end end local make_pine = snow.make_pine local smooth = snow.smooth --Reseed random. pr = PseudoRandom(seed+68) if alpine then trees = env:find_nodes_in_area(minp, maxp, {"default:leaves","default:tree"}) for i,v in pairs(trees) do env:remove_node(v) end end --Loop through chunk. for j=0,divs do for i=0,divs do local x = x0+i local z = z0+j --Check if we are in a "Snow biome" local in_biome = false local test = perlin1:get2d({x=x, y=z}) if smooth and (test > 0.73 or (test > 0.43 and pr:next(0,29) > (0.73 - test) * 100 )) then in_biome = true elseif not smooth and test > 0.53 then in_biome = true end if in_biome then -- Find ground level (0...15) local ground_y = nil for y=maxp.y,minp.y+1,-1 do if env:get_node({x=x,y=y,z=z}).name ~= "air" then ground_y = y break end end -- Snowy biome stuff local node = env:get_node({x=x,y=ground_y,z=z}) if ground_y and node.name == "default:dirt_with_grass" then local veg if mossy and pr:next(1,10) == 1 then veg = 1 end if alpine then --Gets rid of dirt env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow",param2=veg}) for y=ground_y,-6,-1 do if env:get_node({x=x,y=y,z=z}) and env:get_node({x=x,y=y,z=z}).name == "default:stone" then break else env:add_node({x=x,y=y,z=z},{name="default:stone"}) end end elseif shrubs and pr:next(1,28) == 1 then --Spawns dry shrubs. env:add_node({x=x,y=ground_y,z=z}, {name="snow:dirt_with_snow"}) env:add_node({x=x,y=ground_y+1,z=z}, {name="default:dry_shrub"}) elseif pines and pr:next(1,36) == 1 then --Spawns pines. env:add_node({x=x,y=ground_y,z=z}, {name="default:dirt_with_grass"}) make_pine({x=x,y=ground_y+1,z=z},true) else --Spawns snow. env:add_node({x=x,y=ground_y,z=z}, {name="snow:dirt_with_snow"}) env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow",param2=veg}) end elseif ground_y and node.name == "default:sand" then --Spawns ice in sand if icy, otherwise spawns snow on top. if not icy then env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"}) env:add_node({x=x,y=ground_y,z=z}, {name="snow:snow_block"}) else env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"}) end elseif ground_y and env:get_node({x=x,y=ground_y,z=z}).name == "default:leaves" then env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"}) elseif ground_y and env:get_node({x=x,y=ground_y,z=z}).name == "default:papyrus" then for i=ground_y, ground_y-4, -1 do if env:get_node({x=x,y=i,z=z}).name == "default:papyrus" then env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow"}) env:add_node({x=x,y=i,z=z}, {name="snow:snow_block", param2=2}) end end elseif ground_y and node.name == "default:water_source" then if not icesheet and not icecave and not icehole then --Coastal ice. local x1 = env:get_node({x=x+1,y=ground_y,z=z}).name local z1 = env:get_node({x=x,y=ground_y,z=z+1}).name local xz1 = env:get_node({x=x+1,y=ground_y,z=z+1}).name local xz2 = env:get_node({x=x-1,y=ground_y,z=z-1}).name local x2 = env:get_node({x=x-1,y=ground_y,z=z}).name local z2 = env:get_node({x=x,y=ground_y,z=z-1}).name local y = env:get_node({x=x,y=ground_y-1,z=z}).name local rand = pr:next(1,4) == 1 if ((x1 and x1 ~= "default:water_source" and x1 ~= "snow:ice" and x1 ~= "air" and x1 ~= "ignore") or ((cool or icebergs) and x1 == "snow:ice" and rand)) or ((z1 and z1 ~= "default:water_source" and z1 ~= "snow:ice" and z1 ~= "air" and z1 ~= "ignore") or ((cool or icebergs) and z1 == "snow:ice" and rand)) or ((xz1 and xz1 ~= "default:water_source" and xz1 ~= "snow:ice" and xz1 ~= "air"and xz1 ~= "ignore") or ((cool or icebergs) and xz1 == "snow:ice" and rand)) or ((xz2 and xz2 ~= "default:water_source" and xz2 ~= "snow:ice" and xz2 ~= "air"and xz2 ~= "ignore") or ((cool or icebergs) and xz2 == "snow:ice" and rand)) or ((x2 and x2 ~= "default:water_source" and x2 ~= "snow:ice" and x2 ~= "air" and x2 ~= "ignore") or ((cool or icebergs) and x2 == "snow:ice" and rand)) or ((z2 and z2 ~= "default:water_source" and z2 ~= "snow:ice" and z2 ~= "air" and z2 ~= "ignore") or ((cool or icebergs) and z2 == "snow:ice" and rand)) or (y ~= "default:water_source" and y ~= "snow:ice" and y ~= "air") or (pr:next(1,6) == 1 and icebergs) then env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"}) end else --Icesheets, Broken icesheet, Icecaves if (icehole and pr:next(1,10) > 1) or icecave or icesheet then env:add_node({x=x,y=ground_y,z=z}, {name="snow:ice"}) end if icecave then --Gets rid of water underneath ice for y=ground_y-1,-60,-1 do if env:get_node({x=x,y=y,z=z}) and env:get_node({x=x,y=y,z=z}).name ~= "default:water_source" then break else env:remove_node({x=x,y=y,z=z}) end end end end elseif ground_y and node.name == "snow:snow" and node.name ~= "snow:ice" then --Abort genaration. local name = env:get_node({x=x,y=ground_y-1,z=z}).name if name ~= "default:leaves" and name ~= "snow:needles" then if debug then print(biomeToString(biome)..": snow found ABORTED!") end return end end end end end if debug then print(biomeToString(biome)..": Snow Biome Genarated near x"..minp.x.." z"..minp.z) end end end )