197 lines
4.8 KiB
Lua
197 lines
4.8 KiB
Lua
|
|
|
|
local function remap(val, min_val, max_val, min_map, max_map)
|
|
return (val-min_val)/(max_val-min_val) * (max_map-min_map) + min_map
|
|
end
|
|
|
|
local function lerp(var_a, var_b, ratio)
|
|
return (1-ratio)*var_a + (ratio*var_b)
|
|
end
|
|
|
|
-- karst height controls, if a heightmap is provided by mapgen then that is used for max height
|
|
|
|
|
|
local min_height = -2000
|
|
local fallback_max_height = 50
|
|
|
|
-- 2d, low only
|
|
local np_caverns_connector_x = {
|
|
offset = -.75,
|
|
scale = 2,
|
|
spread = {x=30, y=5, z=4},
|
|
octaves = 3,
|
|
seed = 20000,
|
|
persist = 0.4,
|
|
lacunarity = 2,
|
|
}
|
|
|
|
|
|
-- 2d, low only
|
|
local np_caverns_connector_z = {
|
|
offset = -.75, -- lowering makes
|
|
scale = 2,
|
|
spread = {x=5, y=30, z=30},
|
|
octaves = 3,
|
|
seed = 20000,
|
|
persist = 0.4,
|
|
lacunarity = 2,
|
|
}
|
|
|
|
-- 2d, low only
|
|
local np_caverns_rooms = {
|
|
offset = 1.25,
|
|
scale = 2,
|
|
spread = {x=20, y=20, z=20},
|
|
octaves = 2,
|
|
persist = .2,
|
|
lacunarity = 4,
|
|
}
|
|
|
|
-- 2d, low only, a large scale noise that prevents cavern formation in large areas
|
|
local np_caverns_region = {
|
|
offset = -.3,
|
|
scale = 1,
|
|
spread = {x=100, y=100, z=100},
|
|
octaves = 6,
|
|
persist = 0.4,
|
|
lacunarity = 1,
|
|
}
|
|
|
|
|
|
|
|
local np_caverns_modulator = {
|
|
offset = 0,
|
|
scale = 1.3,
|
|
spread = {x=120, y=25, z=120},
|
|
octaves = 4,
|
|
persist = .5,
|
|
lacunarity = 2.5,
|
|
}
|
|
|
|
|
|
local np_caverns_rooms_modulator = {
|
|
offset = 0,
|
|
scale = 1.5,
|
|
spread = {x=60, y=13, z=60},
|
|
octaves = 3,
|
|
persist = .5,
|
|
lacunarity = 2.5,
|
|
}
|
|
|
|
|
|
|
|
|
|
local c_air = minetest.get_content_id("air")
|
|
|
|
local c_stone = minetest.get_content_id("mapgen_stone")
|
|
|
|
|
|
|
|
local nobj_caverns_modulator = nil
|
|
local nvals_caverns_modulator = {}
|
|
|
|
local nobj_caverns_rooms_modulator = nil
|
|
local nvals_caverns_rooms_modulator = {}
|
|
|
|
local data = {}
|
|
|
|
|
|
minetest.register_on_generated(function(minp, maxp, seed)
|
|
|
|
local t0 = os.clock()
|
|
|
|
local heightmap = minetest.get_mapgen_object("heightmap")
|
|
|
|
|
|
local sidelen = maxp.x - minp.x + 1
|
|
|
|
local permapdims3d = {x = sidelen, y = sidelen, z = sidelen}
|
|
|
|
|
|
|
|
nobj_caverns_modulator = nobj_caverns_modulator or
|
|
minetest.get_perlin_map(np_caverns_modulator, permapdims3d)
|
|
nobj_caverns_modulator:get3dMap_flat(minp, nvals_caverns_modulator)
|
|
|
|
nobj_caverns_rooms_modulator = nobj_caverns_rooms_modulator or
|
|
minetest.get_perlin_map(np_caverns_rooms_modulator, permapdims3d)
|
|
nobj_caverns_rooms_modulator:get3dMap_flat(minp, nvals_caverns_rooms_modulator)
|
|
|
|
|
|
local nvals_caverns_connector_x = minetest.get_perlin_map(np_caverns_connector_x, permapdims3d):get2dMap_flat({x=minp.x, y=minp.z})
|
|
local nvals_caverns_connector_z = minetest.get_perlin_map(np_caverns_connector_z, permapdims3d):get2dMap_flat({x=minp.x, y=minp.z})
|
|
local nvals_caverns_caverns_rooms = minetest.get_perlin_map(np_caverns_rooms, permapdims3d):get2dMap_flat({x=minp.x, y=minp.z})
|
|
local nvals_caverns_region = minetest.get_perlin_map(np_caverns_region, permapdims3d):get2dMap_flat({x=minp.x, y=minp.z})
|
|
|
|
|
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
|
|
local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
|
|
|
|
vm:get_data(data)
|
|
|
|
local ni = 1
|
|
|
|
for z = minp.z, maxp.z do
|
|
for y = minp.y, maxp.y do
|
|
|
|
local vi = area:index(minp.x, y, z)
|
|
for x = minp.x, maxp.x do
|
|
local pos = vector.new(x,y,z)
|
|
local hm_i = (pos.x - minp.x + 1) + (((pos.z - minp.z)) * 80)
|
|
local height
|
|
if heightmap then
|
|
height = heightmap[hm_i]
|
|
else
|
|
height = fallback_max_height
|
|
end
|
|
|
|
|
|
|
|
local caverns_caverns_rooms = nvals_caverns_caverns_rooms[hm_i]
|
|
local caverns_region = nvals_caverns_region[hm_i]
|
|
local surface_break_adder = 1.5
|
|
|
|
|
|
|
|
if y > min_height and y < height - (surface_break_adder) + caverns_caverns_rooms and y > height - (75 + caverns_region) and caverns_region > .2 then
|
|
|
|
|
|
local caverns_connector_x = nvals_caverns_connector_x[hm_i]
|
|
local caverns_connector_z = nvals_caverns_connector_z[hm_i]
|
|
|
|
|
|
local density_caverns_modulator = nvals_caverns_modulator[ni]*.5 --+ .75
|
|
local density_caverns_rooms_modulator = nvals_caverns_rooms_modulator[ni]*.5
|
|
|
|
density_caverns_modulator = remap(density_caverns_modulator,-2,2,-20,20)
|
|
if (density_caverns_modulator < 2.8 and density_caverns_modulator > 1
|
|
and (
|
|
lerp(lerp(caverns_connector_x - .9,lerp(density_caverns_rooms_modulator,density_caverns_rooms_modulator,.8) ,.4),density_caverns_rooms_modulator,.3) > 0
|
|
or lerp(lerp(caverns_connector_z - .9,lerp(density_caverns_rooms_modulator,density_caverns_rooms_modulator,.8) ,.4),density_caverns_rooms_modulator,.3) > 0
|
|
))
|
|
or (density_caverns_modulator > 2.5
|
|
and lerp(density_caverns_rooms_modulator - .3,1-caverns_caverns_rooms -.4,.4) > 0
|
|
)
|
|
|
|
then
|
|
data[vi] = c_air
|
|
end
|
|
|
|
end
|
|
-- if math.random(1,100) == 1 then
|
|
-- minetest.chat_send_all(caverns_region)
|
|
-- end
|
|
|
|
-- Increment noise index.
|
|
ni = ni + 1
|
|
vi = vi + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
vm:set_data(data)
|
|
vm:calc_lighting()
|
|
vm:write_to_map()
|
|
vm:update_liquids()
|
|
end) |