forked from minetest-mods/nether
Move dungeon excavation functions to separate file
This commit is contained in:
parent
87f0ea7a51
commit
b30272d2dd
218
mapgen.lua
218
mapgen.lua
@ -68,7 +68,8 @@ if minetest.read_schematic == nil then
|
|||||||
error("This " .. nether.modname .. " mapgen requires Minetest v5.1 or greater, use mapgen_nobiomes.lua instead.", 0)
|
error("This " .. nether.modname .. " mapgen requires Minetest v5.1 or greater, use mapgen_nobiomes.lua instead.", 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Load helper functions for generating the mantle / center region
|
-- Load mapgen helper functions for specialized areas of the mapgen
|
||||||
|
dofile(nether.path .. "/mapgen_dungeons.lua")
|
||||||
dofile(nether.path .. "/mapgen_mantle.lua")
|
dofile(nether.path .. "/mapgen_mantle.lua")
|
||||||
|
|
||||||
|
|
||||||
@ -281,206 +282,11 @@ local dbuf = {}
|
|||||||
local c_air = minetest.get_content_id("air")
|
local c_air = minetest.get_content_id("air")
|
||||||
local c_netherrack = minetest.get_content_id("nether:rack")
|
local c_netherrack = minetest.get_content_id("nether:rack")
|
||||||
local c_netherrack_deep = minetest.get_content_id("nether:rack_deep")
|
local c_netherrack_deep = minetest.get_content_id("nether:rack_deep")
|
||||||
local c_dungeonbrick = minetest.get_content_id("nether:brick")
|
|
||||||
local c_dungeonbrick_alt = minetest.get_content_id("nether:brick_cracked")
|
|
||||||
local c_netherbrick_slab = minetest.get_content_id("stairs:slab_nether_brick")
|
|
||||||
local c_netherfence = minetest.get_content_id("nether:fence_nether_brick")
|
|
||||||
local c_glowstone = minetest.get_content_id("nether:glowstone")
|
|
||||||
local c_lava_source = minetest.get_content_id("default:lava_source")
|
|
||||||
local c_lavasea_source = minetest.get_content_id("nether:lava_source") -- same as lava but with staggered animation to look better as an ocean
|
local c_lavasea_source = minetest.get_content_id("nether:lava_source") -- same as lava but with staggered animation to look better as an ocean
|
||||||
local c_lava_crust = minetest.get_content_id("nether:lava_crust")
|
local c_lava_crust = minetest.get_content_id("nether:lava_crust")
|
||||||
local c_native_mapgen = minetest.get_content_id("nether:native_mapgen")
|
local c_native_mapgen = minetest.get_content_id("nether:native_mapgen")
|
||||||
|
|
||||||
|
|
||||||
-- Dungeon excavation functions
|
|
||||||
|
|
||||||
function is_dungeon_brick(node_id)
|
|
||||||
return node_id == c_dungeonbrick or node_id == c_dungeonbrick_alt
|
|
||||||
end
|
|
||||||
|
|
||||||
function build_dungeon_room_list(data, area)
|
|
||||||
|
|
||||||
local result = {}
|
|
||||||
|
|
||||||
-- Unfortunately gennotify only returns dungeon rooms, not corridors.
|
|
||||||
-- We don't need to check for temples because only dungeons are generated in biomes
|
|
||||||
-- that define their own dungeon nodes.
|
|
||||||
local gennotify = minetest.get_mapgen_object("gennotify")
|
|
||||||
local roomLocations = gennotify["dungeon"] or {}
|
|
||||||
|
|
||||||
-- Excavation should still know to stop if a cave or corridor has removed the dungeon wall.
|
|
||||||
-- See MapgenBasic::generateDungeons in mapgen.cpp for max room sizes.
|
|
||||||
local maxRoomSize = 18
|
|
||||||
local maxRoomRadius = math.ceil(maxRoomSize / 2)
|
|
||||||
|
|
||||||
local xStride, yStride, zStride = 1, area.ystride, area.zstride
|
|
||||||
local minEdge, maxEdge = area.MinEdge, area.MaxEdge
|
|
||||||
|
|
||||||
for _, roomPos in ipairs(roomLocations) do
|
|
||||||
|
|
||||||
if area:containsp(roomPos) then -- this safety check does not appear to be necessary, but lets make it explicit
|
|
||||||
|
|
||||||
local room_vi = area:indexp(roomPos)
|
|
||||||
--data[room_vi] = minetest.get_content_id("default:torch") -- debug
|
|
||||||
|
|
||||||
local startPos = vector.new(roomPos)
|
|
||||||
if roomPos.y + 1 <= maxEdge.y and data[room_vi + yStride] == c_air then
|
|
||||||
-- The roomPos coords given by gennotify are at floor level, but whenever possible we
|
|
||||||
-- want to be performing searches a node higher than floor level to avoids dungeon chests.
|
|
||||||
startPos.y = startPos.y + 1
|
|
||||||
room_vi = area:indexp(startPos)
|
|
||||||
end
|
|
||||||
|
|
||||||
local bound_min_x = math_max(minEdge.x, roomPos.x - maxRoomRadius)
|
|
||||||
local bound_min_y = math_max(minEdge.y, roomPos.y - 1) -- room coords given by gennotify are on the floor
|
|
||||||
local bound_min_z = math_max(minEdge.z, roomPos.z - maxRoomRadius)
|
|
||||||
|
|
||||||
local bound_max_x = math_min(maxEdge.x, roomPos.x + maxRoomRadius)
|
|
||||||
local bound_max_y = math_min(maxEdge.y, roomPos.y + maxRoomSize) -- room coords given by gennotify are on the floor
|
|
||||||
local bound_max_z = math_min(maxEdge.z, roomPos.z + maxRoomRadius)
|
|
||||||
|
|
||||||
local room_min = vector.new(startPos)
|
|
||||||
local room_max = vector.new(startPos)
|
|
||||||
|
|
||||||
local vi = room_vi
|
|
||||||
while room_max.y < bound_max_y and data[vi + yStride] == c_air do
|
|
||||||
room_max.y = room_max.y + 1
|
|
||||||
vi = vi + yStride
|
|
||||||
end
|
|
||||||
|
|
||||||
vi = room_vi
|
|
||||||
while room_min.y > bound_min_y and data[vi - yStride] == c_air do
|
|
||||||
room_min.y = room_min.y - 1
|
|
||||||
vi = vi - yStride
|
|
||||||
end
|
|
||||||
|
|
||||||
vi = room_vi
|
|
||||||
while room_max.z < bound_max_z and data[vi + zStride] == c_air do
|
|
||||||
room_max.z = room_max.z + 1
|
|
||||||
vi = vi + zStride
|
|
||||||
end
|
|
||||||
|
|
||||||
vi = room_vi
|
|
||||||
while room_min.z > bound_min_z and data[vi - zStride] == c_air do
|
|
||||||
room_min.z = room_min.z - 1
|
|
||||||
vi = vi - zStride
|
|
||||||
end
|
|
||||||
|
|
||||||
vi = room_vi
|
|
||||||
while room_max.x < bound_max_x and data[vi + xStride] == c_air do
|
|
||||||
room_max.x = room_max.x + 1
|
|
||||||
vi = vi + xStride
|
|
||||||
end
|
|
||||||
|
|
||||||
vi = room_vi
|
|
||||||
while room_min.x > bound_min_x and data[vi - xStride] == c_air do
|
|
||||||
room_min.x = room_min.x - 1
|
|
||||||
vi = vi - xStride
|
|
||||||
end
|
|
||||||
|
|
||||||
local roomInfo = vector.new(roomPos)
|
|
||||||
roomInfo.minp = room_min
|
|
||||||
roomInfo.maxp = room_max
|
|
||||||
result[#result + 1] = roomInfo
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return result;
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Only partially excavates dungeons, the rest is left as an exercise for the player ;)
|
|
||||||
-- (Corridors and the parts of rooms which extend beyond the emerge boundary will remain filled)
|
|
||||||
function excavate_dungeons(data, area, rooms)
|
|
||||||
|
|
||||||
local vi, node_id
|
|
||||||
|
|
||||||
-- any air from the native mapgen has been replaced by netherrack, but
|
|
||||||
-- we don't want this inside dungeons, so fill dungeon rooms with air
|
|
||||||
for _, roomInfo in ipairs(rooms) do
|
|
||||||
|
|
||||||
local room_min = roomInfo.minp
|
|
||||||
local room_max = roomInfo.maxp
|
|
||||||
|
|
||||||
for z = room_min.z, room_max.z do
|
|
||||||
for y = room_min.y, room_max.y do
|
|
||||||
vi = area:index(room_min.x, y, z)
|
|
||||||
for x = room_min.x, room_max.x do
|
|
||||||
node_id = data[vi]
|
|
||||||
if node_id == c_netherrack or node_id == c_netherrack_deep then data[vi] = c_air end
|
|
||||||
vi = vi + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Since we already know where all the rooms and their walls are, and have all the nodes stored
|
|
||||||
-- in a voxelmanip already, we may as well add a little Nether flair to the dungeons found here.
|
|
||||||
function decorate_dungeons(data, area, rooms)
|
|
||||||
|
|
||||||
local xStride, yStride, zStride = 1, area.ystride, area.zstride
|
|
||||||
local minEdge, maxEdge = area.MinEdge, area.MaxEdge
|
|
||||||
|
|
||||||
for _, roomInfo in ipairs(rooms) do
|
|
||||||
|
|
||||||
local room_min, room_max = roomInfo.minp, roomInfo.maxp
|
|
||||||
local room_size = vector.distance(room_min, room_max)
|
|
||||||
|
|
||||||
if room_size > 10 then
|
|
||||||
local room_seed = roomInfo.x + 3 * roomInfo.z + 13 * roomInfo.y
|
|
||||||
local window_y = roomInfo.y + math_min(2, room_max.y - roomInfo.y - 1)
|
|
||||||
|
|
||||||
if room_seed % 3 == 0 and room_max.y < maxEdge.y then
|
|
||||||
-- Glowstone chandelier (feel free to replace with a fancy schematic)
|
|
||||||
local vi = area:index(roomInfo.x, room_max.y + 1, roomInfo.z)
|
|
||||||
if is_dungeon_brick(data[vi]) then data[vi] = c_glowstone end
|
|
||||||
|
|
||||||
elseif room_seed % 4 == 0 and room_min.y > minEdge.y
|
|
||||||
and room_min.x > minEdge.x and room_max.x < maxEdge.x
|
|
||||||
and room_min.z > minEdge.z and room_max.z < maxEdge.z then
|
|
||||||
-- lava well (feel free to replace with a fancy schematic)
|
|
||||||
local vi = area:index(roomInfo.x, room_min.y, roomInfo.z)
|
|
||||||
if is_dungeon_brick(data[vi - yStride]) then
|
|
||||||
data[vi - yStride] = c_lava_source
|
|
||||||
if data[vi - zStride] == c_air then data[vi - zStride] = c_netherbrick_slab end
|
|
||||||
if data[vi + zStride] == c_air then data[vi + zStride] = c_netherbrick_slab end
|
|
||||||
if data[vi - xStride] == c_air then data[vi - xStride] = c_netherbrick_slab end
|
|
||||||
if data[vi + xStride] == c_air then data[vi + xStride] = c_netherbrick_slab end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Barred windows
|
|
||||||
if room_seed % 7 < 5 and room_max.x - room_min.x >= 4 and room_max.z - room_min.z >= 4
|
|
||||||
and window_y >= minEdge.y and window_y + 1 <= maxEdge.y
|
|
||||||
and room_min.x > minEdge.x and room_max.x < maxEdge.x
|
|
||||||
and room_min.z > minEdge.z and room_max.z < maxEdge.z then
|
|
||||||
--data[area:indexp(roomInfo)] = minetest.get_content_id("default:mese_post_light") -- debug
|
|
||||||
|
|
||||||
-- Until whisper glass is added, every window will be made of netherbrick fence (rather
|
|
||||||
-- than material depending on room_seed)
|
|
||||||
local window_node = c_netherfence
|
|
||||||
|
|
||||||
local vi_min = area:index(room_min.x - 1, window_y, roomInfo.z)
|
|
||||||
local vi_max = area:index(room_max.x + 1, window_y, roomInfo.z)
|
|
||||||
local locations = {-zStride, zStride, -zStride + yStride, zStride + yStride}
|
|
||||||
for _, offset in ipairs(locations) do
|
|
||||||
if is_dungeon_brick(data[vi_min + offset]) then data[vi_min + offset] = window_node end
|
|
||||||
if is_dungeon_brick(data[vi_max + offset]) then data[vi_max + offset] = window_node end
|
|
||||||
end
|
|
||||||
vi_min = area:index(roomInfo.x, window_y, room_min.z - 1)
|
|
||||||
vi_max = area:index(roomInfo.x, window_y, room_max.z + 1)
|
|
||||||
locations = {-xStride, xStride, -xStride + yStride, xStride + yStride}
|
|
||||||
for _, offset in ipairs(locations) do
|
|
||||||
if is_dungeon_brick(data[vi_min + offset]) then data[vi_min + offset] = window_node end
|
|
||||||
if is_dungeon_brick(data[vi_max + offset]) then data[vi_max + offset] = window_node end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Weeds on the floor once Nether weeds are added
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local yblmin = NETHER_FLOOR + BLEND * 2
|
local yblmin = NETHER_FLOOR + BLEND * 2
|
||||||
local yblmax = NETHER_CEILING - BLEND * 2
|
local yblmax = NETHER_CEILING - BLEND * 2
|
||||||
@ -539,18 +345,17 @@ local function on_generated(minp, maxp, seed)
|
|||||||
nobj_cave = nobj_cave or minetest.get_perlin_map(mapgen.np_cave, chulens)
|
nobj_cave = nobj_cave or minetest.get_perlin_map(mapgen.np_cave, chulens)
|
||||||
local nvals_cave = nobj_cave:get_3d_map_flat(minp, nbuf_cave)
|
local nvals_cave = nobj_cave:get_3d_map_flat(minp, nbuf_cave)
|
||||||
|
|
||||||
local dungeonRooms = build_dungeon_room_list(data, area)
|
local dungeonRooms = mapgen.build_dungeon_room_list(data, area) -- function from mapgen_dungeons.lua
|
||||||
local abs_cave_noise, abs_cave_noise_adjusted
|
local abs_cave_noise, abs_cave_noise_adjusted
|
||||||
|
|
||||||
local contains_nether = false
|
local contains_nether = false
|
||||||
local contains_shell = false
|
|
||||||
local contains_mantle = false
|
local contains_mantle = false
|
||||||
local contains_ocean = false
|
local contains_ocean = false
|
||||||
|
|
||||||
|
|
||||||
for y = y0, y1 do -- Y loop first to minimise tcave & lava-sea calculations
|
for y = y0, y1 do -- Y loop first to minimise tcave & lava-sea calculations
|
||||||
|
|
||||||
local sea_level, cavern_limit_distance = mapgen.find_nearest_lava_sealevel(y) -- function provided by mapgen_mantle.lua
|
local sea_level, cavern_limit_distance = mapgen.find_nearest_lava_sealevel(y) -- function from mapgen_mantle.lua
|
||||||
local above_lavasea = y > sea_level
|
local above_lavasea = y > sea_level
|
||||||
local below_lavasea = y < sea_level
|
local below_lavasea = y < sea_level
|
||||||
|
|
||||||
@ -609,7 +414,6 @@ local function on_generated(minp, maxp, seed)
|
|||||||
else
|
else
|
||||||
-- the shell seperating the mantle from the rest of the nether...
|
-- the shell seperating the mantle from the rest of the nether...
|
||||||
data[vi] = c_netherrack -- excavate_dungeons() will mostly reverse this inside dungeons
|
data[vi] = c_netherrack -- excavate_dungeons() will mostly reverse this inside dungeons
|
||||||
contains_shell = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -633,12 +437,12 @@ local function on_generated(minp, maxp, seed)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if contains_mantle or contains_ocean then
|
if contains_mantle or contains_ocean then
|
||||||
mapgen.add_basalt_columns(data, area, minp, maxp) -- function provided by mapgen_mantle.lua
|
mapgen.add_basalt_columns(data, area, minp, maxp) -- function from mapgen_mantle.lua
|
||||||
end
|
end
|
||||||
|
|
||||||
if contains_nether and contains_mantle then
|
if contains_nether and contains_mantle then
|
||||||
tunnelCandidate_count = tunnelCandidate_count + 1
|
tunnelCandidate_count = tunnelCandidate_count + 1
|
||||||
local success = mapgen.excavate_tunnel_to_center_of_the_nether(data, area, nvals_cave, minp, maxp) -- function provided by mapgen_mantle.lua
|
local success = mapgen.excavate_tunnel_to_center_of_the_nether(data, area, nvals_cave, minp, maxp) -- function from mapgen_mantle.lua
|
||||||
if success then tunnel_count = tunnel_count + 1 end
|
if success then tunnel_count = tunnel_count + 1 end
|
||||||
end
|
end
|
||||||
total_chunk_count = total_chunk_count + 1
|
total_chunk_count = total_chunk_count + 1
|
||||||
@ -655,8 +459,8 @@ local function on_generated(minp, maxp, seed)
|
|||||||
|
|
||||||
-- any air from the native mapgen has been replaced by netherrack, but we
|
-- any air from the native mapgen has been replaced by netherrack, but we
|
||||||
-- don't want netherrack inside dungeons, so fill known dungeon rooms with air.
|
-- don't want netherrack inside dungeons, so fill known dungeon rooms with air.
|
||||||
excavate_dungeons(data, area, dungeonRooms)
|
mapgen.excavate_dungeons(data, area, dungeonRooms) -- function from mapgen_dungeons.lua
|
||||||
decorate_dungeons(data, area, dungeonRooms)
|
mapgen.decorate_dungeons(data, area, dungeonRooms) -- function from mapgen_dungeons.lua
|
||||||
|
|
||||||
vm:set_data(data)
|
vm:set_data(data)
|
||||||
|
|
||||||
@ -705,8 +509,4 @@ function nether.find_nether_ground_y(target_x, target_z, start_y, player_name)
|
|||||||
return math_max(start_y, NETHER_FLOOR + BLEND) -- Fallback
|
return math_max(start_y, NETHER_FLOOR + BLEND) -- Fallback
|
||||||
end
|
end
|
||||||
|
|
||||||
-- We don't need to be gen-notified of temples because only dungeons will be generated
|
|
||||||
-- if a biome defines the dungeon nodes
|
|
||||||
minetest.set_gen_notify({dungeon = true})
|
|
||||||
|
|
||||||
minetest.register_on_generated(on_generated)
|
minetest.register_on_generated(on_generated)
|
238
mapgen_dungeons.lua
Normal file
238
mapgen_dungeons.lua
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
Nether mod for minetest
|
||||||
|
|
||||||
|
Helper functions for excavating and decorating dungeons, in a
|
||||||
|
separate file to keep the size of mapgen.lua manageable.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2021 Treer
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
]]--
|
||||||
|
|
||||||
|
|
||||||
|
-- We don't need to be gen-notified of temples because only dungeons will be generated
|
||||||
|
-- if a biome defines the dungeon nodes
|
||||||
|
minetest.set_gen_notify({dungeon = true})
|
||||||
|
|
||||||
|
|
||||||
|
-- Content ids
|
||||||
|
|
||||||
|
local c_air = minetest.get_content_id("air")
|
||||||
|
local c_netherrack = minetest.get_content_id("nether:rack")
|
||||||
|
local c_netherrack_deep = minetest.get_content_id("nether:rack_deep")
|
||||||
|
local c_dungeonbrick = minetest.get_content_id("nether:brick")
|
||||||
|
local c_dungeonbrick_alt = minetest.get_content_id("nether:brick_cracked")
|
||||||
|
local c_netherbrick_slab = minetest.get_content_id("stairs:slab_nether_brick")
|
||||||
|
local c_netherfence = minetest.get_content_id("nether:fence_nether_brick")
|
||||||
|
local c_glowstone = minetest.get_content_id("nether:glowstone")
|
||||||
|
local c_lava_source = minetest.get_content_id("default:lava_source")
|
||||||
|
|
||||||
|
-- Misc math functions
|
||||||
|
|
||||||
|
-- avoid needing table lookups each time a common math function is invoked
|
||||||
|
local math_max, math_min = math.max, math.min
|
||||||
|
|
||||||
|
|
||||||
|
-- Dungeon excavation functions
|
||||||
|
|
||||||
|
function is_dungeon_brick(node_id)
|
||||||
|
return node_id == c_dungeonbrick or node_id == c_dungeonbrick_alt
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
nether.mapgen.build_dungeon_room_list = function(data, area)
|
||||||
|
|
||||||
|
local result = {}
|
||||||
|
|
||||||
|
-- Unfortunately gennotify only returns dungeon rooms, not corridors.
|
||||||
|
-- We don't need to check for temples because only dungeons are generated in biomes
|
||||||
|
-- that define their own dungeon nodes.
|
||||||
|
local gennotify = minetest.get_mapgen_object("gennotify")
|
||||||
|
local roomLocations = gennotify["dungeon"] or {}
|
||||||
|
|
||||||
|
-- Excavation should still know to stop if a cave or corridor has removed the dungeon wall.
|
||||||
|
-- See MapgenBasic::generateDungeons in mapgen.cpp for max room sizes.
|
||||||
|
local maxRoomSize = 18
|
||||||
|
local maxRoomRadius = math.ceil(maxRoomSize / 2)
|
||||||
|
|
||||||
|
local xStride, yStride, zStride = 1, area.ystride, area.zstride
|
||||||
|
local minEdge, maxEdge = area.MinEdge, area.MaxEdge
|
||||||
|
|
||||||
|
for _, roomPos in ipairs(roomLocations) do
|
||||||
|
|
||||||
|
if area:containsp(roomPos) then -- this safety check does not appear to be necessary, but lets make it explicit
|
||||||
|
|
||||||
|
local room_vi = area:indexp(roomPos)
|
||||||
|
--data[room_vi] = minetest.get_content_id("default:torch") -- debug
|
||||||
|
|
||||||
|
local startPos = vector.new(roomPos)
|
||||||
|
if roomPos.y + 1 <= maxEdge.y and data[room_vi + yStride] == c_air then
|
||||||
|
-- The roomPos coords given by gennotify are at floor level, but whenever possible we
|
||||||
|
-- want to be performing searches a node higher than floor level to avoids dungeon chests.
|
||||||
|
startPos.y = startPos.y + 1
|
||||||
|
room_vi = area:indexp(startPos)
|
||||||
|
end
|
||||||
|
|
||||||
|
local bound_min_x = math_max(minEdge.x, roomPos.x - maxRoomRadius)
|
||||||
|
local bound_min_y = math_max(minEdge.y, roomPos.y - 1) -- room coords given by gennotify are on the floor
|
||||||
|
local bound_min_z = math_max(minEdge.z, roomPos.z - maxRoomRadius)
|
||||||
|
|
||||||
|
local bound_max_x = math_min(maxEdge.x, roomPos.x + maxRoomRadius)
|
||||||
|
local bound_max_y = math_min(maxEdge.y, roomPos.y + maxRoomSize) -- room coords given by gennotify are on the floor
|
||||||
|
local bound_max_z = math_min(maxEdge.z, roomPos.z + maxRoomRadius)
|
||||||
|
|
||||||
|
local room_min = vector.new(startPos)
|
||||||
|
local room_max = vector.new(startPos)
|
||||||
|
|
||||||
|
local vi = room_vi
|
||||||
|
while room_max.y < bound_max_y and data[vi + yStride] == c_air do
|
||||||
|
room_max.y = room_max.y + 1
|
||||||
|
vi = vi + yStride
|
||||||
|
end
|
||||||
|
|
||||||
|
vi = room_vi
|
||||||
|
while room_min.y > bound_min_y and data[vi - yStride] == c_air do
|
||||||
|
room_min.y = room_min.y - 1
|
||||||
|
vi = vi - yStride
|
||||||
|
end
|
||||||
|
|
||||||
|
vi = room_vi
|
||||||
|
while room_max.z < bound_max_z and data[vi + zStride] == c_air do
|
||||||
|
room_max.z = room_max.z + 1
|
||||||
|
vi = vi + zStride
|
||||||
|
end
|
||||||
|
|
||||||
|
vi = room_vi
|
||||||
|
while room_min.z > bound_min_z and data[vi - zStride] == c_air do
|
||||||
|
room_min.z = room_min.z - 1
|
||||||
|
vi = vi - zStride
|
||||||
|
end
|
||||||
|
|
||||||
|
vi = room_vi
|
||||||
|
while room_max.x < bound_max_x and data[vi + xStride] == c_air do
|
||||||
|
room_max.x = room_max.x + 1
|
||||||
|
vi = vi + xStride
|
||||||
|
end
|
||||||
|
|
||||||
|
vi = room_vi
|
||||||
|
while room_min.x > bound_min_x and data[vi - xStride] == c_air do
|
||||||
|
room_min.x = room_min.x - 1
|
||||||
|
vi = vi - xStride
|
||||||
|
end
|
||||||
|
|
||||||
|
local roomInfo = vector.new(roomPos)
|
||||||
|
roomInfo.minp = room_min
|
||||||
|
roomInfo.maxp = room_max
|
||||||
|
result[#result + 1] = roomInfo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Only partially excavates dungeons, the rest is left as an exercise for the player ;)
|
||||||
|
-- (Corridors and the parts of rooms which extend beyond the emerge boundary will remain filled)
|
||||||
|
nether.mapgen.excavate_dungeons = function(data, area, rooms)
|
||||||
|
|
||||||
|
local vi, node_id
|
||||||
|
|
||||||
|
-- any air from the native mapgen has been replaced by netherrack, but
|
||||||
|
-- we don't want this inside dungeons, so fill dungeon rooms with air
|
||||||
|
for _, roomInfo in ipairs(rooms) do
|
||||||
|
|
||||||
|
local room_min = roomInfo.minp
|
||||||
|
local room_max = roomInfo.maxp
|
||||||
|
|
||||||
|
for z = room_min.z, room_max.z do
|
||||||
|
for y = room_min.y, room_max.y do
|
||||||
|
vi = area:index(room_min.x, y, z)
|
||||||
|
for x = room_min.x, room_max.x do
|
||||||
|
node_id = data[vi]
|
||||||
|
if node_id == c_netherrack or node_id == c_netherrack_deep then data[vi] = c_air end
|
||||||
|
vi = vi + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Since we already know where all the rooms and their walls are, and have all the nodes stored
|
||||||
|
-- in a voxelmanip already, we may as well add a little Nether flair to the dungeons found here.
|
||||||
|
nether.mapgen.decorate_dungeons = function(data, area, rooms)
|
||||||
|
|
||||||
|
local xStride, yStride, zStride = 1, area.ystride, area.zstride
|
||||||
|
local minEdge, maxEdge = area.MinEdge, area.MaxEdge
|
||||||
|
|
||||||
|
for _, roomInfo in ipairs(rooms) do
|
||||||
|
|
||||||
|
local room_min, room_max = roomInfo.minp, roomInfo.maxp
|
||||||
|
local room_size = vector.distance(room_min, room_max)
|
||||||
|
|
||||||
|
if room_size > 10 then
|
||||||
|
local room_seed = roomInfo.x + 3 * roomInfo.z + 13 * roomInfo.y
|
||||||
|
local window_y = roomInfo.y + math_min(2, room_max.y - roomInfo.y - 1)
|
||||||
|
|
||||||
|
if room_seed % 3 == 0 and room_max.y < maxEdge.y then
|
||||||
|
-- Glowstone chandelier (feel free to replace with a fancy schematic)
|
||||||
|
local vi = area:index(roomInfo.x, room_max.y + 1, roomInfo.z)
|
||||||
|
if is_dungeon_brick(data[vi]) then data[vi] = c_glowstone end
|
||||||
|
|
||||||
|
elseif room_seed % 4 == 0 and room_min.y > minEdge.y
|
||||||
|
and room_min.x > minEdge.x and room_max.x < maxEdge.x
|
||||||
|
and room_min.z > minEdge.z and room_max.z < maxEdge.z then
|
||||||
|
-- lava well (feel free to replace with a fancy schematic)
|
||||||
|
local vi = area:index(roomInfo.x, room_min.y, roomInfo.z)
|
||||||
|
if is_dungeon_brick(data[vi - yStride]) then
|
||||||
|
data[vi - yStride] = c_lava_source
|
||||||
|
if data[vi - zStride] == c_air then data[vi - zStride] = c_netherbrick_slab end
|
||||||
|
if data[vi + zStride] == c_air then data[vi + zStride] = c_netherbrick_slab end
|
||||||
|
if data[vi - xStride] == c_air then data[vi - xStride] = c_netherbrick_slab end
|
||||||
|
if data[vi + xStride] == c_air then data[vi + xStride] = c_netherbrick_slab end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Barred windows
|
||||||
|
if room_seed % 7 < 5 and room_max.x - room_min.x >= 4 and room_max.z - room_min.z >= 4
|
||||||
|
and window_y >= minEdge.y and window_y + 1 <= maxEdge.y
|
||||||
|
and room_min.x > minEdge.x and room_max.x < maxEdge.x
|
||||||
|
and room_min.z > minEdge.z and room_max.z < maxEdge.z then
|
||||||
|
--data[area:indexp(roomInfo)] = minetest.get_content_id("default:mese_post_light") -- debug
|
||||||
|
|
||||||
|
-- Until whisper glass is added, every window will be made of netherbrick fence (rather
|
||||||
|
-- than material depending on room_seed)
|
||||||
|
local window_node = c_netherfence
|
||||||
|
|
||||||
|
local vi_min = area:index(room_min.x - 1, window_y, roomInfo.z)
|
||||||
|
local vi_max = area:index(room_max.x + 1, window_y, roomInfo.z)
|
||||||
|
local locations = {-zStride, zStride, -zStride + yStride, zStride + yStride}
|
||||||
|
for _, offset in ipairs(locations) do
|
||||||
|
if is_dungeon_brick(data[vi_min + offset]) then data[vi_min + offset] = window_node end
|
||||||
|
if is_dungeon_brick(data[vi_max + offset]) then data[vi_max + offset] = window_node end
|
||||||
|
end
|
||||||
|
vi_min = area:index(roomInfo.x, window_y, room_min.z - 1)
|
||||||
|
vi_max = area:index(roomInfo.x, window_y, room_max.z + 1)
|
||||||
|
locations = {-xStride, xStride, -xStride + yStride, xStride + yStride}
|
||||||
|
for _, offset in ipairs(locations) do
|
||||||
|
if is_dungeon_brick(data[vi_min + offset]) then data[vi_min + offset] = window_node end
|
||||||
|
if is_dungeon_brick(data[vi_max + offset]) then data[vi_max + offset] = window_node end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Weeds on the floor once Nether weeds are added
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user