mirror of
https://github.com/minetest-mods/nether.git
synced 2024-11-12 21:40:37 +01:00
Improve dungeons
* clears netherrack from dungeon stairways * Adds pillars or mezzanine floors to large rooms * slightly more careful with window placement * glowstone sometimes added behind in windows
This commit is contained in:
parent
b30272d2dd
commit
bafa4e8ea1
|
@ -68,7 +68,7 @@ if minetest.read_schematic == nil then
|
|||
error("This " .. nether.modname .. " mapgen requires Minetest v5.1 or greater, use mapgen_nobiomes.lua instead.", 0)
|
||||
end
|
||||
|
||||
-- Load mapgen helper functions for specialized areas of the mapgen
|
||||
-- Load specialty helper functions
|
||||
dofile(nether.path .. "/mapgen_dungeons.lua")
|
||||
dofile(nether.path .. "/mapgen_mantle.lua")
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
Nether mod for minetest
|
||||
|
||||
Helper functions for excavating and decorating dungeons, in a
|
||||
separate file to keep the size of mapgen.lua manageable.
|
||||
All the Dungeon related functions used by the biomes-based mapgen are here.
|
||||
|
||||
|
||||
Copyright (C) 2021 Treer
|
||||
|
@ -39,8 +38,10 @@ 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_glowstone_deep = minetest.get_content_id("nether:glowstone_deep")
|
||||
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
|
||||
|
@ -54,6 +55,7 @@ function is_dungeon_brick(node_id)
|
|||
end
|
||||
|
||||
|
||||
|
||||
nether.mapgen.build_dungeon_room_list = function(data, area)
|
||||
|
||||
local result = {}
|
||||
|
@ -168,6 +170,21 @@ nether.mapgen.excavate_dungeons = function(data, area, rooms)
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- clear netherrack from dungeon stairways
|
||||
if #rooms > 0 then
|
||||
local stairPositions = minetest.find_nodes_in_area(area.MinEdge, area.MaxEdge, minetest.registered_biomes["nether_caverns"].node_dungeon_stair)
|
||||
for _, stairPos in ipairs(stairPositions) do
|
||||
vi = area:indexp(stairPos)
|
||||
for i = 1, 4 do
|
||||
if stairPos.y + i > area.MaxEdge.y then break end
|
||||
vi = vi + area.ystride
|
||||
node_id = data[vi]
|
||||
-- searching forward of the stairs could also be done
|
||||
if node_id == c_netherrack or node_id == c_netherrack_deep then data[vi] = c_air end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Since we already know where all the rooms and their walls are, and have all the nodes stored
|
||||
|
@ -185,6 +202,8 @@ nether.mapgen.decorate_dungeons = function(data, area, rooms)
|
|||
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)
|
||||
local roomWidth = room_max.x - room_min.x + 1
|
||||
local roomLength = room_max.z - room_min.z + 1
|
||||
|
||||
if room_seed % 3 == 0 and room_max.y < maxEdge.y then
|
||||
-- Glowstone chandelier (feel free to replace with a fancy schematic)
|
||||
|
@ -206,29 +225,105 @@ nether.mapgen.decorate_dungeons = function(data, area, rooms)
|
|||
end
|
||||
|
||||
-- Barred windows
|
||||
if room_seed % 7 < 5 and room_max.x - room_min.x >= 4 and room_max.z - room_min.z >= 4
|
||||
if room_seed % 7 < 5 and roomWidth >= 5 and roomLength >= 5
|
||||
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
|
||||
|
||||
-- Can't use glass panes because they need the param data set.
|
||||
-- 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
|
||||
--if c_netherglass ~= nil and room_seed % 20 >= 12 then window_node = c_crystallight end
|
||||
|
||||
local function placeWindow(vi, viOutsideOffset, windowNo)
|
||||
if is_dungeon_brick(data[vi]) and is_dungeon_brick(data[vi + yStride]) then
|
||||
data[vi] = window_node
|
||||
|
||||
if room_seed % 19 == windowNo then
|
||||
-- place a glowstone light behind the window
|
||||
local node_id = data[vi + viOutsideOffset]
|
||||
if node_id == c_netherrack then
|
||||
data[vi + viOutsideOffset] = c_glowstone
|
||||
elseif node_id == c_netherrack_deep then
|
||||
data[vi + viOutsideOffset] = c_glowstone_deep
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
for i, offset in ipairs(locations) do
|
||||
placeWindow(vi_min + offset, -1, i)
|
||||
placeWindow(vi_max + offset, 1, i + #locations)
|
||||
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
|
||||
for i, offset in ipairs(locations) do
|
||||
placeWindow(vi_min + offset, -zStride, i + #locations * 2)
|
||||
placeWindow(vi_max + offset, zStride, i + #locations * 3)
|
||||
end
|
||||
end
|
||||
|
||||
-- pillars or mezzanine floor
|
||||
if room_seed % 43 > 10 and roomWidth >= 6 and roomLength >= 6 then
|
||||
|
||||
local pillar_vi = {}
|
||||
local pillarHeight = 0
|
||||
local wallDist = 1 + math.floor((roomWidth + roomLength) / 14)
|
||||
|
||||
local roomHeight = room_max.y - room_min.y
|
||||
if roomHeight >= 7 then
|
||||
-- mezzanine floor
|
||||
local mezzMax = {
|
||||
x = room_min.x + math.floor(roomWidth / 7 * 4),
|
||||
y = room_min.y + math.floor(roomHeight / 5 * 3),
|
||||
z = room_max.z
|
||||
}
|
||||
|
||||
pillarHeight = mezzMax.y - room_min.y - 1
|
||||
pillar_vi = {
|
||||
area:index(mezzMax.x, room_min.y, room_min.z + wallDist),
|
||||
area:index(mezzMax.x, room_min.y, room_max.z - wallDist),
|
||||
}
|
||||
|
||||
if is_dungeon_brick(data[pillar_vi[1] - yStride]) and is_dungeon_brick(data[pillar_vi[2] - yStride]) then
|
||||
-- The floor of the dungeon looks like it exists (i.e. not erased by nether
|
||||
-- cavern), so add the mezzanine floor
|
||||
for z = 0, roomLength - 1 do
|
||||
local vi = area:index(room_min.x, mezzMax.y, room_min.z + z)
|
||||
for x = room_min.x, mezzMax.x do
|
||||
if data[vi] == c_air then data[vi] = c_dungeonbrick end
|
||||
vi = vi + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif roomHeight >= 4 then
|
||||
-- 4 pillars
|
||||
pillarHeight = roomHeight
|
||||
pillar_vi = {
|
||||
area:index(room_min.x + wallDist, room_min.y, room_min.z + wallDist),
|
||||
area:index(room_min.x + wallDist, room_min.y, room_max.z - wallDist),
|
||||
area:index(room_max.x - wallDist, room_min.y, room_min.z + wallDist),
|
||||
area:index(room_max.x - wallDist, room_min.y, room_max.z - wallDist)
|
||||
}
|
||||
end
|
||||
|
||||
for i = #pillar_vi, 1, -1 do
|
||||
if not is_dungeon_brick(data[pillar_vi[i] - yStride]) then
|
||||
-- there's no dungeon floor under this pillar so skip it, it's probably been cut away by nether cavern.
|
||||
table.remove(pillar_vi, i)
|
||||
end
|
||||
end
|
||||
for y = 0, pillarHeight do
|
||||
for _, vi in ipairs(pillar_vi) do
|
||||
if data[vi + y * yStride] == c_air then data[vi + y * yStride] = c_dungeonbrick end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user