improved soil and snow generation, more efficient mapgen

This commit is contained in:
FaceDeer 2018-11-08 01:19:26 -07:00
parent 1ce466428f
commit 6ccb319dae

@ -12,20 +12,22 @@ local slope_max = 1.5 -- above 1.5 and the mountain becomes more of a shield vol
local chunk_size = 1000 local chunk_size = 1000
local snow_line = 120 -- above this elevation snow is added to the dirt type local snow_line = 120 -- above this elevation snow is added to the dirt type
local snow_border = 15 -- transitional zone where there's dirt with snow on it
local c_air = minetest.get_content_id("air") local c_air = minetest.get_content_id("air")
local c_lava = minetest.get_content_id("default:lava_source") local c_lava = minetest.get_content_id("default:lava_source")
local c_water = minetest.get_content_id("default:water_source") local c_water = minetest.get_content_id("default:water_source")
--local c_stone = minetest.get_content_id("default:stone")
local c_lining = minetest.get_content_id("default:obsidian") local c_lining = minetest.get_content_id("default:obsidian")
local c_hot_lining = minetest.get_content_id("default:obsidian") local c_hot_lining = minetest.get_content_id("default:obsidian")
local c_cone = minetest.get_content_id("default:stone") local c_cone = minetest.get_content_id("default:stone")
local c_ash = minetest.get_content_id("default:gravel") local c_ash = minetest.get_content_id("default:gravel")
local c_soil = minetest.get_content_id("default:dirt_with_grass") local c_soil = minetest.get_content_id("default:dirt")
local c_soil_grass = minetest.get_content_id("default:dirt_with_grass")
local c_soil_snow = minetest.get_content_id("default:dirt_with_snow") local c_soil_snow = minetest.get_content_id("default:dirt_with_snow")
local c_snow = minetest.get_content_id("default:snow") local c_snow = minetest.get_content_id("default:snow")
local c_snow_block = minetest.get_content_id("default:snowblock")
local c_underwater_soil = minetest.get_content_id("default:sand") local c_underwater_soil = minetest.get_content_id("default:sand")
local c_plug = minetest.get_content_id("default:obsidian") local c_plug = minetest.get_content_id("default:obsidian")
@ -87,31 +89,32 @@ minetest.register_on_generated(function(minp, maxp, seed)
if minp.y > depth_maxpeak or maxp.y < depth_root then if minp.y > depth_maxpeak or maxp.y < depth_root then
return return
end end
local volcano = get_volcano(minp)
local depth_peak = volcano.depth_peak
local base_radius = (depth_peak - depth_maxwidth) * volcano.slope + radius_lining
local sidelen = maxp.x - minp.x + 1 --length of a mapblock
-- early out if the volcano is too far away to matter
if vector.distance(volcano.location, {x=minp.x+sidelen/2, y=0, z=minp.z+sidelen/2}) > base_radius * 2.5 then
return
end
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
vm:get_data(data) vm:get_data(data)
local minx = minp.x
local minz = minp.z
local sidelen = maxp.x - minp.x + 1 --length of a mapblock
local chunk_lengths = {x = sidelen, y = sidelen, z = sidelen} --table of chunk edges local chunk_lengths = {x = sidelen, y = sidelen, z = sidelen} --table of chunk edges
nobj_perlin = nobj_perlin or minetest.get_perlin_map(perlin_params, chunk_lengths) nobj_perlin = nobj_perlin or minetest.get_perlin_map(perlin_params, chunk_lengths)
local nvals_perlin = nobj_perlin:get3dMap_flat(minp, nvals_perlin_buffer) -- switch to get_3d_map_flat for minetest v0.5 local nvals_perlin = nobj_perlin:get3dMap_flat(minp, nvals_perlin_buffer) -- switch to get_3d_map_flat for minetest v0.5
local noise_area = VoxelArea:new{MinEdge=minp, MaxEdge=maxp} local noise_area = VoxelArea:new{MinEdge=minp, MaxEdge=maxp}
local noise_iterator = noise_area:iterp(minp, maxp) local noise_iterator = noise_area:iterp(minp, maxp)
local volcano = get_volcano(minp)
--minetest.debug(dump(volcano))
local x_coord = volcano.location.x local x_coord = volcano.location.x
local z_coord = volcano.location.z local z_coord = volcano.location.z
local depth_lava = volcano.depth_lava local depth_lava = volcano.depth_lava
local depth_peak = volcano.depth_peak
local caldera = volcano.caldera local caldera = volcano.caldera
local base_radius = (depth_peak - depth_maxwidth) * volcano.slope + radius_lining
local state = volcano.state local state = volcano.state
@ -121,19 +124,20 @@ minetest.register_on_generated(function(minp, maxp, seed)
local distance_perturbation = (nvals_perlin[vi3d]+1)*10 local distance_perturbation = (nvals_perlin[vi3d]+1)*10
local distance = vector.distance({x=x, y=y, z=z}, {x=x_coord, y=y, z=z_coord}) - distance_perturbation local distance = vector.distance({x=x, y=y, z=z}, {x=x_coord, y=y, z=z_coord}) - distance_perturbation
if distance > base_radius * 2.5 then
return
end
local dirtstuff local dirtstuff
local replace_soil = false -- determines if the soil type should be replaced with c_soil if there's layers on top of it
if state < 0.5 then if state < 0.5 then
if y < water_level then if y < water_level then
dirtstuff = c_underwater_soil dirtstuff = c_underwater_soil
elseif y < snow_line then elseif y < snow_line then
dirtstuff = c_soil dirtstuff = c_soil_grass
else replace_soil = true
elseif y < snow_line + snow_border then
dirtstuff = c_soil_snow dirtstuff = c_soil_snow
replace_soil = true
else
dirtstuff = c_snow_block
end end
else else
dirtstuff = c_ash dirtstuff = c_ash
@ -188,8 +192,13 @@ minetest.register_on_generated(function(minp, maxp, seed)
data[vi] = c_cone data[vi] = c_cone
elseif distance < current_elevation * -volcano.slope + base_radius + nvals_perlin[vi3d]*-4 then elseif distance < current_elevation * -volcano.slope + base_radius + nvals_perlin[vi3d]*-4 then
data[vi] = dirtstuff data[vi] = dirtstuff
if replace_soil and data[vi - area.ystride] == dirtstuff then
data[vi - area.ystride] = c_soil -- soil underneath a layer of other soil shouldn't have grass on top
end
if y >= snow_line then if y >= snow_line then
data[vi + area.ystride] = c_snow -- generation advances in a positive y direction so this should be safe if data[vi + area.ystride] == c_air then
data[vi + area.ystride] = c_snow -- generation advances in a positive y direction so this will be overwritten if more solid stuff is placed above
end
end end
end end
end end