--Identify content ID's of nodes local c_dirt_with_grass = minetest.get_content_id("default:dirt_with_grass") local c_snow = minetest.get_content_id("default:snow") local c_snow_block = minetest.get_content_id("default:snowblock") local c_dirt_with_snow = minetest.get_content_id("default:dirt_with_snow") local c_air = minetest.get_content_id("air") local c_ignore = minetest.get_content_id("ignore") local c_stone = minetest.get_content_id("default:stone") local c_dry_shrub = minetest.get_content_id("default:dry_shrub") local c_leaves = minetest.get_content_id("default:leaves") local c_jungleleaves = minetest.get_content_id("default:jungleleaves") local c_junglegrass = minetest.get_content_id("default:junglegrass") local c_ice = minetest.get_content_id("default:ice") local c_water = minetest.get_content_id("default:water_source") local c_papyrus = minetest.get_content_id("default:papyrus") local c_sand = minetest.get_content_id("default:sand") --Snow biomes are found at 0.53 and greater perlin noise. minetest.register_on_generated(function(minp, maxp, seed) --if maxp.y >= -10 and maxp.y > snow.min_height then --Start timer local t1 = os.clock() local in_biome = false --Load Voxel Manipulator local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local a = VoxelArea:new{ MinEdge={x=emin.x, y=emin.y, z=emin.z}, MaxEdge={x=emax.x, y=emax.y, z=emax.z}, } local data = vm:get_data() local debug = snow.debug local min_height = snow.min_height --Should make things a bit faster. local env = minetest.env -- Assume X and Z lengths are equal local divlen = 16 local divs = (maxp.x-minp.x)+1; local x0 = minp.x local z0 = minp.z local x1 = maxp.x local z1 = maxp.z --Get map specific perlin noise. local perlin1 = env:get_perlin(112,3, 0.5, 150) --Speed hack: checks the corners and middle of the chunk for "snow biome". --[[if not ( perlin1:get2d( {x=x0, y=z0} ) > 0.53 ) --top left and not ( perlin1:get2d( { x = x0 + ( (x1-x0)/2), y=z0 } ) > 0.53 )--top middle and not (perlin1:get2d({x=x1, y=z1}) > 0.53) --bottom right and not (perlin1:get2d({x=x1, y=z0+((z1-z0)/2)}) > 0.53) --right middle and not (perlin1:get2d({x=x0, y=z1}) > 0.53) --bottom left and not (perlin1:get2d({x=x1, y=z0}) > 0.53) --top right and not (perlin1:get2d({x=x0+((x1-x0)/2), y=z1}) > 0.53) --left middle and not (perlin1:get2d({x=(x1-x0)/2, y=(z1-z0)/2}) > 0.53) --middle and not (perlin1:get2d({x=x0, y=z1+((z1-z0)/2)}) > 0.53) then --bottom middle return end]] --Choose a biome types. local pr = PseudoRandom(seed+57) local biome --Land biomes biome = pr:next(1, 5) local snowy = biome == 1 --spawns alot of snow local plain = biome == 2 --spawns not much local alpine = biome == 3 --rocky terrain -- biome == 4 or biome == 5 -- normal biome --Water biomes biome2 = pr:next(1, 5) local cool = biome == 1 --only spawns ice on edge of water local icebergs = biome == 2 local icesheet = biome == 3 local icecave = biome == 4 local icehole = biome == 5 --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,num2) local biome, biome2 if num == 1 then biome = "snowy" elseif num == 2 then biome = "plain" elseif num == 3 then biome = "alpine" elseif num == 4 or num == 5 then biome = "normal" else biome = "unknown "..num end if num2 == 1 then biome2 = "cool" elseif num2 == 2 then biome2 = "icebergs" elseif num2 == 3 then biome2 = "icesheet" elseif num2 == 4 then biome2 = "icecave" elseif num2 == 5 then biome2 = "icehole" else biome2 = "unknown "..num end return biome, biome2 end local spawn_pine = snow.voxelmanip_pine local smooth = snow.smooth_biomes local legacy = snow.legacy --Reseed random. pr = PseudoRandom(seed+68) --[[if alpine then local 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 x = minp.x, maxp.x do for z = minp.z, maxp.z do --Check if we are in a "Snow biome" local in_biome = false local test = perlin1:get2d({x=x, y=z}) if smooth and (not snowy) and (test > 0.73 or (test > 0.43 and pr:next(0,29) > (0.73 - test) * 100 )) then in_biome = true elseif (not smooth or snowy) and test > 0.53 then in_biome = true end if in_biome then local perlin2 = env:get_perlin(322345,3, 0.5, 80) local icetype = perlin2:get2d({x=x, y=z}) local cool = icetype > 0 --only spawns ice on edge of water local icebergs = icetype > -0.2 and icetype <= 0 local icehole = icetype > -0.4 and icetype <= -0.2 local icesheet = icetype > -0.6 and icetype <= -0.4 local icecave = icetype <= -0.6 --if not plain or pr:next(1,12) == 1 then -- Find ground level (0...15) local ground_y = nil for y=maxp.y,minp.y,-1 do local n = data[a:index(x, y, z)] if n ~= c_air and n ~= c_ignore then ground_y = y break end end if ground_y then --and ground_y > min_height then -- Snowy biome stuff local node = a:index(x, ground_y, z) local abovenode = a:index(x, ground_y+1, z) local belownode = a:index(x, ground_y+2, z) if ground_y and data[node] == c_dirt_with_grass then --local veg --if legacy and mossy and pr:next(1,10) == 1 then veg = 1 end if alpine then --Gets rid of dirt data[abovenode] = c_snow for y=ground_y,-6,-1 do local stone = a:index(x, y, z) if data[stone] == "default:stone" then break else data[stone] = c_stone end end elseif (shrubs and pr:next(1,28) == 1) then --Spawns dry shrubs. data[node] = c_dirt_with_snow data[abovenode] = c_dry_shrub elseif pines and pr:next(1,36) == 1 then --Spawns pines. data[node] = c_dirt_with_snow spawn_pine({x=x, y=ground_y+1, z=z},a,data) --elseif snowy then --Spawns snow blocks. --env:add_node({x=x,y=ground_y+1,z=z}, {name="snow:snow_block"}) --data[aanode] = c_snow else --Spawns snow. data[node] = c_dirt_with_snow data[abovenode] = c_snow end elseif ground_y and data[belownode] == c_sand then --Spawns ice in sand if icy, otherwise spawns snow on top. if not icy then data[node] = c_snow else data[belownode] = c_ice end elseif ground_y and data[node] == c_leaves or data[node] == c_jungleleaves then data[abovenode] = c_snow elseif ground_y and data[node] == c_junglegrass then data[node] = c_dry_shrub elseif ground_y and data[node] == c_papyrus then for i=ground_y, ground_y-4, -1 do local papyrus = a:index(x, y, z) if data[papyrus] == c_papyrus then local papyrusabove = a:index(x, ground_y, z) data[papyrusabove] = c_snow data[papyrus] = c_snow_block end end elseif ground_y and data[node] == c_water then if not icesheet and not icecave and not icehole then --Coastal ice. local x1 = data[a:index(x+1,ground_y,z)] local z1 = data[a:index(x,ground_y,z+1)] local xz1 = data[a:index(x+1,ground_y,z+1)] local xz2 = data[a:index(x-1,ground_y,z-1)] local x2 = data[a:index(x-1,ground_y,z)] local z2 = data[a:index(x,ground_y,z-1)] local y = data[a:index(x,ground_y-1,z)] local rand = pr:next(1,4) == 1 if ((x1 and x1 ~= c_water and x1 ~= c_ice and x1 ~= c_air and x1 ~= c_ignore) or ((cool or icebergs) and x1 == c_ice and rand)) or ((z1 and z1 ~= c_water and z1 ~= c_ice and z1 ~= c_air and z1 ~= c_ignore) or ((cool or icebergs) and z1 == c_ice and rand)) or ((xz1 and xz1 ~= c_water and xz1 ~= c_ice and xz1 ~= c_air and xz1 ~= c_ignore) or ((cool or icebergs) and xz1 == c_ice and rand)) or ((xz2 and xz2 ~= c_water and xz2 ~= c_ice and xz2 ~= c_air and xz2 ~= c_ignore) or ((cool or icebergs) and xz2 == c_ice and rand)) or ((x2 and x2 ~= c_water and x2 ~= c_ice and x2 ~= c_air and x2 ~= c_ignore) or ((cool or icebergs) and x2 == c_ice and rand)) or ((z2 and z2 ~= c_water and z2 ~= c_ice and z2 ~= c_air and z2 ~= c_ignore) or ((cool or icebergs) and z2 == c_ice and rand)) or (y ~= c_water and y ~= c_ice and y ~= "air") or (pr:next(1,6) == 1 and icebergs) then data[node] = c_ice end else --Icesheets, Broken icesheet, Icecaves if (icehole and pr:next(1,10) > 1) or icecave or icesheet then data[node] = c_ice end if icecave then --Gets rid of water underneath ice for y=ground_y-1,-60,-1 do local water = a:index(x, y, z) if data[water] ~= c_water then break else data[water] = c_air end end end end end end --end end end end vm:set_data(data) vm:calc_lighting( {x=minp.x-16, y=minp.y, z=minp.z-16}, {x=maxp.x+16, y=maxp.y, z=maxp.z+16} ) vm:write_to_map(data) if debug then biome_string,biome2_string = biomeToString(biome,biome2) print(biome_string.." and "..biome2_string..": Snow Biome Genarated near x"..minp.x.." z"..minp.z) print(string.format("elapsed time: %.2fms", (os.clock() - t1) * 1000)) end --end end)