mapgen_nobiomes.lua 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. --[[
  2. Nether mod for minetest
  3. "mapgen_nobiomes.lua" is the legacy version of the mapgen, only used
  4. in older versions of Minetest or in v6 worlds.
  5. "mapgen.lua" is the modern biomes-based Nether mapgen, which
  6. requires Minetest v5.1 or greater
  7. Copyright (C) 2013 PilzAdam
  8. Permission to use, copy, modify, and/or distribute this software for
  9. any purpose with or without fee is hereby granted, provided that the
  10. above copyright notice and this permission notice appear in all copies.
  11. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  12. WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  13. WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
  14. BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
  15. OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  16. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  17. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  18. SOFTWARE.
  19. ]]--
  20. -- Parameters
  21. local NETHER_CEILING = nether.DEPTH_CEILING
  22. local NETHER_FLOOR = nether.DEPTH_FLOOR
  23. local TCAVE = 0.6
  24. local BLEND = 128
  25. -- 3D noise
  26. local np_cave = {
  27. offset = 0,
  28. scale = 1,
  29. spread = {x = 384, y = 128, z = 384}, -- squashed 3:1
  30. seed = 59033,
  31. octaves = 5,
  32. persist = 0.7,
  33. lacunarity = 2.0,
  34. --flags = ""
  35. }
  36. -- Stuff
  37. local yblmin = NETHER_FLOOR + BLEND * 2
  38. local yblmax = NETHER_CEILING - BLEND * 2
  39. -- Mapgen
  40. dofile(nether.path .. "/mapgen_decorations.lua")
  41. -- Initialize noise object, localise noise and data buffers
  42. local nobj_cave = nil
  43. local nbuf_cave = {}
  44. local dbuf = {}
  45. -- Content ids
  46. local c_air = minetest.get_content_id("air")
  47. --local c_stone_with_coal = minetest.get_content_id("default:stone_with_coal")
  48. --local c_stone_with_iron = minetest.get_content_id("default:stone_with_iron")
  49. local c_stone_with_mese = minetest.get_content_id("default:stone_with_mese")
  50. local c_stone_with_diamond = minetest.get_content_id("default:stone_with_diamond")
  51. local c_stone_with_gold = minetest.get_content_id("default:stone_with_gold")
  52. --local c_stone_with_copper = minetest.get_content_id("default:stone_with_copper")
  53. local c_mese = minetest.get_content_id("default:mese")
  54. local c_gravel = minetest.get_content_id("default:gravel")
  55. local c_dirt = minetest.get_content_id("default:dirt")
  56. local c_sand = minetest.get_content_id("default:sand")
  57. local c_cobble = minetest.get_content_id("default:cobble")
  58. local c_mossycobble = minetest.get_content_id("default:mossycobble")
  59. local c_stair_cobble = minetest.get_content_id("stairs:stair_cobble")
  60. local c_lava_source = minetest.get_content_id("default:lava_source")
  61. local c_lava_flowing = minetest.get_content_id("default:lava_flowing")
  62. local c_water_source = minetest.get_content_id("default:water_source")
  63. local c_water_flowing = minetest.get_content_id("default:water_flowing")
  64. local c_glowstone = minetest.get_content_id("nether:glowstone")
  65. local c_nethersand = minetest.get_content_id("nether:sand")
  66. local c_netherbrick = minetest.get_content_id("nether:brick")
  67. local c_netherrack = minetest.get_content_id("nether:rack")
  68. -- On-generated function
  69. minetest.register_on_generated(function(minp, maxp, seed)
  70. if minp.y > NETHER_CEILING or maxp.y < NETHER_FLOOR then
  71. return
  72. end
  73. local x1 = maxp.x
  74. local y1 = math.min(maxp.y, NETHER_CEILING)
  75. local z1 = maxp.z
  76. local x0 = minp.x
  77. local y0 = math.max(minp.y, NETHER_FLOOR)
  78. local z0 = minp.z
  79. local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
  80. local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
  81. local data = vm:get_data(dbuf)
  82. local x11 = emax.x -- Limits of mapchunk plus mapblock shell
  83. local y11 = emax.y
  84. local z11 = emax.z
  85. local x00 = emin.x
  86. local y00 = emin.y
  87. local z00 = emin.z
  88. local ystride = x1 - x0 + 1
  89. local zstride = ystride * ystride
  90. local chulens = {x = ystride, y = ystride, z = ystride}
  91. local minposxyz = {x = x0, y = y0, z = z0}
  92. nobj_cave = nobj_cave or minetest.get_perlin_map(np_cave, chulens)
  93. local nvals_cave = nobj_cave:get_3d_map_flat(minposxyz, nbuf_cave)
  94. for y = y00, y11 do -- Y loop first to minimise tcave calculations
  95. local tcave
  96. local in_chunk_y = false
  97. if y >= y0 and y <= y1 then
  98. tcave = TCAVE
  99. if y > yblmax then tcave = TCAVE + ((y - yblmax) / BLEND) ^ 2 end
  100. if y < yblmin then tcave = TCAVE + ((yblmin - y) / BLEND) ^ 2 end
  101. in_chunk_y = true
  102. end
  103. for z = z00, z11 do
  104. local vi = area:index(x00, y, z) -- Initial voxelmanip index
  105. local ni
  106. local in_chunk_yz = in_chunk_y and z >= z0 and z <= z1
  107. for x = x00, x11 do
  108. if in_chunk_yz and x == x0 then
  109. -- Initial noisemap index
  110. ni = (z - z0) * zstride + (y - y0) * ystride + 1
  111. end
  112. local in_chunk_yzx = in_chunk_yz and x >= x0 and x <= x1 -- In mapchunk
  113. local id = data[vi] -- Existing node
  114. -- Cave air, cave liquids and dungeons are overgenerated,
  115. -- convert these throughout mapchunk plus shell
  116. if id == c_air or -- Air and liquids to air
  117. id == c_lava_source or
  118. id == c_lava_flowing or
  119. id == c_water_source or
  120. id == c_water_flowing then
  121. data[vi] = c_air
  122. -- Dungeons are preserved so we don't need
  123. -- to check for cavern in the shell
  124. elseif id == c_cobble or -- Dungeons (preserved) to netherbrick
  125. id == c_mossycobble or
  126. id == c_stair_cobble then
  127. data[vi] = c_netherbrick
  128. end
  129. if in_chunk_yzx then -- In mapchunk
  130. if nvals_cave[ni] > tcave then -- Only excavate cavern in mapchunk
  131. data[vi] = c_air
  132. elseif id == c_mese then -- Mese block to lava
  133. data[vi] = c_lava_source
  134. elseif id == c_stone_with_gold or -- Precious ores to glowstone
  135. id == c_stone_with_mese or
  136. id == c_stone_with_diamond then
  137. data[vi] = c_glowstone
  138. elseif id == c_gravel or -- Blob ore to nethersand
  139. id == c_dirt or
  140. id == c_sand then
  141. data[vi] = c_nethersand
  142. else -- All else to netherstone
  143. data[vi] = c_netherrack
  144. end
  145. ni = ni + 1 -- Only increment noise index in mapchunk
  146. end
  147. vi = vi + 1
  148. end
  149. end
  150. end
  151. vm:set_data(data)
  152. minetest.generate_decorations(vm)
  153. vm:set_lighting({day = 0, night = 0}, minp, maxp)
  154. vm:calc_lighting()
  155. vm:update_liquids()
  156. vm:write_to_map()
  157. end)
  158. -- use knowledge of the nether mapgen algorithm to return a suitable ground level for placing a portal.
  159. -- player_name is optional, allowing a player to spawn a remote portal in their own protected areas.
  160. function nether.find_nether_ground_y(target_x, target_z, start_y, player_name)
  161. local nobj_cave_point = minetest.get_perlin(np_cave)
  162. local air = 0 -- Consecutive air nodes found
  163. local minp_schem, maxp_schem = nether.get_schematic_volume({x = target_x, y = 0, z = target_z}, nil, "nether_portal")
  164. local minp = {x = minp_schem.x, y = 0, z = minp_schem.z}
  165. local maxp = {x = maxp_schem.x, y = 0, z = maxp_schem.z}
  166. for y = start_y, math.max(NETHER_FLOOR + BLEND, start_y - 4096), -1 do
  167. local nval_cave = nobj_cave_point:get_3d({x = target_x, y = y, z = target_z})
  168. if nval_cave > TCAVE then -- Cavern
  169. air = air + 1
  170. else -- Not cavern, check if 4 nodes of space above
  171. if air >= 4 then
  172. local portal_y = y + 1
  173. -- Check volume for non-natural nodes
  174. minp.y = minp_schem.y + portal_y
  175. maxp.y = maxp_schem.y + portal_y
  176. if nether.volume_is_natural_and_unprotected(minp, maxp, player_name) then
  177. return portal_y
  178. else -- Restart search a little lower
  179. nether.find_nether_ground_y(target_x, target_z, y - 16, player_name)
  180. end
  181. else -- Not enough space, reset air to zero
  182. air = 0
  183. end
  184. end
  185. end
  186. return math.max(start_y, NETHER_FLOOR + BLEND) -- Fallback
  187. end