123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- --[[
- Nether mod for minetest
- Copyright (C) 2013 PilzAdam
- Permission to use, copy, modify, and/or distribute this software for
- any purpose with or without fee is hereby granted, provided that the
- above copyright notice and this permission notice appear in all copies.
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
- BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
- OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- ]]--
- -- Parameters
- local NETHER_CEILING = nether.DEPTH_CEILING
- local NETHER_FLOOR = nether.DEPTH_FLOOR
- local TCAVE = 0.6
- local BLEND = 128
- -- 3D noise
- local np_cave = {
- offset = 0,
- scale = 1,
- spread = {x = 384, y = 128, z = 384}, -- squashed 3:1
- seed = 59033,
- octaves = 5,
- persist = 0.7,
- lacunarity = 2.0,
- --flags = ""
- }
- -- Stuff
- local yblmin = NETHER_FLOOR + BLEND * 2
- local yblmax = NETHER_CEILING - BLEND * 2
- -- Mapgen
- dofile(nether.path .. "/mapgen_decorations.lua")
- -- Initialize noise object, localise noise and data buffers
- local nobj_cave = nil
- local nbuf_cave = nil
- local dbuf = nil
- -- Content ids
- local c_air = minetest.get_content_id("air")
- --local c_stone_with_coal = minetest.get_content_id("default:stone_with_coal")
- --local c_stone_with_iron = minetest.get_content_id("default:stone_with_iron")
- local c_stone_with_mese = minetest.get_content_id("default:stone_with_mese")
- local c_stone_with_diamond = minetest.get_content_id("default:stone_with_diamond")
- local c_stone_with_gold = minetest.get_content_id("default:stone_with_gold")
- --local c_stone_with_copper = minetest.get_content_id("default:stone_with_copper")
- local c_mese = minetest.get_content_id("default:mese")
- local c_gravel = minetest.get_content_id("default:gravel")
- local c_dirt = minetest.get_content_id("default:dirt")
- local c_sand = minetest.get_content_id("default:sand")
- local c_cobble = minetest.get_content_id("default:cobble")
- local c_mossycobble = minetest.get_content_id("default:mossycobble")
- local c_stair_cobble = minetest.get_content_id("stairs:stair_cobble")
- local c_lava_source = minetest.get_content_id("default:lava_source")
- local c_lava_flowing = minetest.get_content_id("default:lava_flowing")
- local c_water_source = minetest.get_content_id("default:water_source")
- local c_water_flowing = minetest.get_content_id("default:water_flowing")
- local c_glowstone = minetest.get_content_id("nether:glowstone")
- local c_nethersand = minetest.get_content_id("nether:sand")
- local c_netherbrick = minetest.get_content_id("nether:brick")
- local c_netherrack = minetest.get_content_id("nether:rack")
- -- On-generated function
- minetest.register_on_generated(function(minp, maxp, seed)
- if minp.y > NETHER_CEILING or maxp.y < NETHER_FLOOR then
- return
- end
- local x1 = maxp.x
- local y1 = math.min(maxp.y, NETHER_CEILING)
- local z1 = maxp.z
- local x0 = minp.x
- local y0 = math.max(minp.y, NETHER_FLOOR)
- local z0 = minp.z
- local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
- local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax}
- local data = vm:get_data(dbuf)
- local x11 = emax.x -- Limits of mapchunk plus mapblock shell
- local y11 = emax.y
- local z11 = emax.z
- local x00 = emin.x
- local y00 = emin.y
- local z00 = emin.z
- local ystride = x1 - x0 + 1
- local zstride = ystride * ystride
- local chulens = {x = ystride, y = ystride, z = ystride}
- local minposxyz = {x = x0, y = y0, z = z0}
- nobj_cave = nobj_cave or minetest.get_perlin_map(np_cave, chulens)
- local nvals_cave = nobj_cave:get3dMap_flat(minposxyz, nbuf_cave)
- for y = y00, y11 do -- Y loop first to minimise tcave calculations
- local tcave
- local in_chunk_y = false
- if y >= y0 and y <= y1 then
- tcave = TCAVE
- if y > yblmax then tcave = TCAVE + ((y - yblmax) / BLEND) ^ 2 end
- if y < yblmin then tcave = TCAVE + ((yblmin - y) / BLEND) ^ 2 end
- in_chunk_y = true
- end
- for z = z00, z11 do
- local vi = area:index(x00, y, z) -- Initial voxelmanip index
- local ni
- local in_chunk_yz = in_chunk_y and z >= z0 and z <= z1
- for x = x00, x11 do
- if in_chunk_yz and x == x0 then
- -- Initial noisemap index
- ni = (z - z0) * zstride + (y - y0) * ystride + 1
- end
- local in_chunk_yzx = in_chunk_yz and x >= x0 and x <= x1 -- In mapchunk
- local id = data[vi] -- Existing node
- -- Cave air, cave liquids and dungeons are overgenerated,
- -- convert these throughout mapchunk plus shell
- if id == c_air or -- Air and liquids to air
- id == c_lava_source or
- id == c_lava_flowing or
- id == c_water_source or
- id == c_water_flowing then
- data[vi] = c_air
- -- Dungeons are preserved so we don't need
- -- to check for cavern in the shell
- elseif id == c_cobble or -- Dungeons (preserved) to netherbrick
- id == c_mossycobble or
- id == c_stair_cobble then
- data[vi] = c_netherbrick
- end
- if in_chunk_yzx then -- In mapchunk
- if nvals_cave[ni] > tcave then -- Only excavate cavern in mapchunk
- data[vi] = c_air
- elseif id == c_mese then -- Mese block to lava
- data[vi] = c_lava_source
- elseif id == c_stone_with_gold or -- Precious ores to glowstone
- id == c_stone_with_mese or
- id == c_stone_with_diamond then
- data[vi] = c_glowstone
- elseif id == c_gravel or -- Blob ore to nethersand
- id == c_dirt or
- id == c_sand then
- data[vi] = c_nethersand
- else -- All else to netherstone
- data[vi] = c_netherrack
- end
- ni = ni + 1 -- Only increment noise index in mapchunk
- end
- vi = vi + 1
- end
- end
- end
- vm:set_data(data)
- -- avoid generating decorations on the underside of the bottom of the nether
- if minp.y > NETHER_FLOOR and maxp.y < NETHER_CEILING then minetest.generate_decorations(vm) end
- vm:set_lighting({day = 0, night = 0}, minp, maxp)
- vm:calc_lighting()
- vm:update_liquids()
- vm:write_to_map()
- end)
- -- use knowledge of the nether mapgen algorithm to return a suitable ground level for placing a portal.
- function nether.find_nether_ground_y(target_x, target_z, start_y)
- local nobj_cave_point = minetest.get_perlin(np_cave)
- local air = 0 -- Consecutive air nodes found
- for y = start_y, start_y - 4096, -1 do
- local nval_cave = nobj_cave_point:get3d({x = target_x, y = y, z = target_z})
- if nval_cave > TCAVE then -- Cavern
- air = air + 1
- else -- Not cavern, check if 4 nodes of space above
- if air >= 4 then
- -- Check volume for non-natural nodes
- local minp = {x = target_x - 1, y = y , z = target_z - 2}
- local maxp = {x = target_x + 2, y = y + 4, z = target_z + 2}
- if nether.volume_is_natural(minp, maxp) then
- return y + 1
- else -- Restart search a little lower
- nether.find_nether_ground_y(target_x, target_z, y - 16)
- end
- else -- Not enough space, reset air to zero
- air = 0
- end
- end
- end
- return start_y -- Fallback
- end
|