init.lua 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. local function remap(val, min_val, max_val, min_map, max_map)
  2. return (val-min_val)/(max_val-min_val) * (max_map-min_map) + min_map
  3. end
  4. local function lerp(var_a, var_b, ratio)
  5. return (1-ratio)*var_a + (ratio*var_b)
  6. end
  7. -- karst height controls, if a heightmap is provided by mapgen then that is used for max height
  8. local min_height = -2000
  9. local fallback_max_height = 50
  10. -- 2d, low only
  11. local np_caverns_connector_x = {
  12. offset = -.75,
  13. scale = 2,
  14. spread = {x=30, y=5, z=4},
  15. octaves = 3,
  16. seed = 20000,
  17. persist = 0.4,
  18. lacunarity = 2,
  19. }
  20. -- 2d, low only
  21. local np_caverns_connector_z = {
  22. offset = -.75, -- lowering makes
  23. scale = 2,
  24. spread = {x=5, y=30, z=30},
  25. octaves = 3,
  26. seed = 20000,
  27. persist = 0.4,
  28. lacunarity = 2,
  29. }
  30. -- 2d, low only
  31. local np_caverns_rooms = {
  32. offset = 1.25,
  33. scale = 2,
  34. spread = {x=20, y=20, z=20},
  35. octaves = 2,
  36. persist = .2,
  37. lacunarity = 4,
  38. }
  39. -- 2d, low only, a large scale noise that prevents cavern formation in large areas
  40. local np_caverns_region = {
  41. offset = -.3,
  42. scale = 1,
  43. spread = {x=100, y=100, z=100},
  44. octaves = 6,
  45. persist = 0.4,
  46. lacunarity = 1,
  47. }
  48. local np_caverns_modulator = {
  49. offset = 0,
  50. scale = 1.3,
  51. spread = {x=120, y=25, z=120},
  52. octaves = 4,
  53. persist = .5,
  54. lacunarity = 2.5,
  55. }
  56. local np_caverns_rooms_modulator = {
  57. offset = 0,
  58. scale = 1.5,
  59. spread = {x=60, y=13, z=60},
  60. octaves = 3,
  61. persist = .5,
  62. lacunarity = 2.5,
  63. }
  64. local c_air = minetest.get_content_id("air")
  65. local c_stone = minetest.get_content_id("mapgen_stone")
  66. local nobj_caverns_modulator = nil
  67. local nvals_caverns_modulator = {}
  68. local nobj_caverns_rooms_modulator = nil
  69. local nvals_caverns_rooms_modulator = {}
  70. local data = {}
  71. minetest.register_on_generated(function(minp, maxp, seed)
  72. local t0 = os.clock()
  73. local heightmap = minetest.get_mapgen_object("heightmap")
  74. local sidelen = maxp.x - minp.x + 1
  75. local permapdims3d = {x = sidelen, y = sidelen, z = sidelen}
  76. nobj_caverns_modulator = nobj_caverns_modulator or
  77. minetest.get_perlin_map(np_caverns_modulator, permapdims3d)
  78. nobj_caverns_modulator:get_3d_map_flat(minp, nvals_caverns_modulator)
  79. nobj_caverns_rooms_modulator = nobj_caverns_rooms_modulator or
  80. minetest.get_perlin_map(np_caverns_rooms_modulator, permapdims3d)
  81. nobj_caverns_rooms_modulator:get_3d_map_flat(minp, nvals_caverns_rooms_modulator)
  82. local nvals_caverns_connector_x = minetest.get_perlin_map(np_caverns_connector_x, permapdims3d):get_2d_map_flat({x=minp.x, y=minp.z})
  83. local nvals_caverns_connector_z = minetest.get_perlin_map(np_caverns_connector_z, permapdims3d):get_2d_map_flat({x=minp.x, y=minp.z})
  84. local nvals_caverns_caverns_rooms = minetest.get_perlin_map(np_caverns_rooms, permapdims3d):get_2d_map_flat({x=minp.x, y=minp.z})
  85. local nvals_caverns_region = minetest.get_perlin_map(np_caverns_region, permapdims3d):get_2d_map_flat({x=minp.x, y=minp.z})
  86. local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
  87. local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
  88. vm:get_data(data)
  89. local ni = 1
  90. for z = minp.z, maxp.z do
  91. for y = minp.y, maxp.y do
  92. local vi = area:index(minp.x, y, z)
  93. for x = minp.x, maxp.x do
  94. local pos = vector.new(x,y,z)
  95. local hm_i = (pos.x - minp.x + 1) + (((pos.z - minp.z)) * 80)
  96. local height
  97. if heightmap then
  98. height = heightmap[hm_i]
  99. else
  100. height = fallback_max_height
  101. end
  102. local caverns_caverns_rooms = nvals_caverns_caverns_rooms[hm_i]
  103. local caverns_region = nvals_caverns_region[hm_i]
  104. local surface_break_adder = 1.5
  105. if y > min_height and y < height - (surface_break_adder) + caverns_caverns_rooms and y > height - (75 + caverns_region) and caverns_region > .2 then
  106. local caverns_connector_x = nvals_caverns_connector_x[hm_i]
  107. local caverns_connector_z = nvals_caverns_connector_z[hm_i]
  108. local density_caverns_modulator = nvals_caverns_modulator[ni]*.5 --+ .75
  109. local density_caverns_rooms_modulator = nvals_caverns_rooms_modulator[ni]*.5
  110. density_caverns_modulator = remap(density_caverns_modulator,-2,2,-20,20)
  111. if (density_caverns_modulator < 2.8 and density_caverns_modulator > 1
  112. and (
  113. lerp(lerp(caverns_connector_x - .9,lerp(density_caverns_rooms_modulator,density_caverns_rooms_modulator,.8) ,.4),density_caverns_rooms_modulator,.3) > 0
  114. or lerp(lerp(caverns_connector_z - .9,lerp(density_caverns_rooms_modulator,density_caverns_rooms_modulator,.8) ,.4),density_caverns_rooms_modulator,.3) > 0
  115. ))
  116. or (density_caverns_modulator > 2.5
  117. and lerp(density_caverns_rooms_modulator - .3,1-caverns_caverns_rooms -.4,.4) > 0
  118. )
  119. then
  120. data[vi] = c_air
  121. end
  122. end
  123. -- if math.random(1,100) == 1 then
  124. -- minetest.chat_send_all(caverns_region)
  125. -- end
  126. -- Increment noise index.
  127. ni = ni + 1
  128. vi = vi + 1
  129. end
  130. end
  131. end
  132. vm:set_data(data)
  133. vm:calc_lighting()
  134. vm:write_to_map()
  135. vm:update_liquids()
  136. end)