123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- 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:get_3d_map_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:get_3d_map_flat(minp, nvals_caverns_rooms_modulator)
- local nvals_caverns_connector_x = minetest.get_perlin_map(np_caverns_connector_x, permapdims3d):get_2d_map_flat({x=minp.x, y=minp.z})
- local nvals_caverns_connector_z = minetest.get_perlin_map(np_caverns_connector_z, permapdims3d):get_2d_map_flat({x=minp.x, y=minp.z})
- local nvals_caverns_caverns_rooms = minetest.get_perlin_map(np_caverns_rooms, permapdims3d):get_2d_map_flat({x=minp.x, y=minp.z})
- local nvals_caverns_region = minetest.get_perlin_map(np_caverns_region, permapdims3d):get_2d_map_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)
|