Mapgen: Add Inner-Edge Detection

Showroom: Add Inner-Edge Opening Logic
master
benrob0329 2020-01-30 23:12:10 -05:00
parent fb26f15e27
commit 150a497359
2 changed files with 74 additions and 28 deletions

View File

@ -10,7 +10,10 @@ minetest.after(0, function()
pn = minetest.get_perlin(0, 1, 0, 1) pn = minetest.get_perlin(0, 1, 0, 1)
end) end)
local function split(r, min, max, val, bd) -- Store functions in a table so that they're all in scope of each other without being made global
local bsp = {}
function bsp.split(r, min, max, val, bd)
local div = min + bd + math.floor((max - min + 1 - bd * 2) * r) local div = min + bd + math.floor((max - min + 1 - bd * 2) * r)
if max - min <= 1 then if max - min <= 1 then
div = max div = max
@ -21,43 +24,73 @@ local function split(r, min, max, val, bd)
return div, max return div, max
end end
local function pick_department(options, x_min, x_max, z_min, z_max, x, z) function bsp.pick_department(options, x_min, x_max, z_min, z_max, x, z, check_inner)
local department = options.departments[util.bound_perlin(pn, #options.departments, x_min, 2, z_min)] local department = options.departments[util.bound_perlin(pn, #options.departments, x_min, 2, z_min)]
local edges = {w = x <= x_min, e = x >= x_max, s = z <= z_min, n = z >= z_max} local edges = {w = x <= x_min, e = x >= x_max, s = z <= z_min, n = z >= z_max}
edges.inner = {w = false, e = false, n = false, s = false}
-- Check for inner edges
if check_inner then
if edges.n then
local adjacent_dept, _ = bsp.get_department(options, x, z+1, false)
if adjacent_dept.name == department.name then
edges.inner.n = true
end
end
if edges.s then
local adjacent_dept, _ = bsp.get_department(options, x, z-1, false)
if adjacent_dept.name == department.name then
edges.inner.s = true
end
end
if edges.e then
local adjacent_dept, _ = bsp.get_department(options, x+1, z, false)
if adjacent_dept.name == department.name then
edges.inner.e = true
end
end
if edges.w then
local adjacent_dept, _ = bsp.get_department(options, x-1, z, false)
if adjacent_dept.name == department.name then
edges.inner.w = true
end
end
end
return department, edges return department, edges
end end
local function subdivide(options, x_min, x_max, z_min, z_max, x, z) function bsp.subdivide(options, x_min, x_max, z_min, z_max, x, z, check_inner)
local width = x_max - x_min + 1 local width = x_max - x_min + 1
local height = z_max - z_min + 1 local height = z_max - z_min + 1
if (width > options.max_size) or (height > options.max_size) or (util.tail_perlin(pn, x_min, 0, z_min) == 1) then if (width > options.max_size) or (height > options.max_size) or (util.tail_perlin(pn, x_min, 0, z_min) == 1) then
if height > width then if height > width then
local z_min2, z_max2 = split(util.tail_perlin(pn, x_min, 1, z_min), z_min, z_max, z, options.min_size) local z_min2, z_max2 = bsp.split(util.tail_perlin(pn, x_min, 1, z_min), z_min, z_max, z, options.min_size)
local height2 = z_max2 - z_min2 + 1 local height2 = z_max2 - z_min2 + 1
if (height2 < options.min_size) or ((height - height2) < options.min_size) then if (height2 < options.min_size) or ((height - height2) < options.min_size) then
return pick_department(options, x_min, x_max, z_min, z_max, x, z) return bsp.pick_department(options, x_min, x_max, z_min, z_max, x, z, check_inner)
end end
return subdivide(options, x_min, x_max, z_min2, z_max2, x, z) return bsp.subdivide(options, x_min, x_max, z_min2, z_max2, x, z, check_inner)
else else
local x_min2, x_max2 = split(util.tail_perlin(pn, x_min, 1, z_min), x_min, x_max, x, options.min_size) local x_min2, x_max2 = bsp.split(util.tail_perlin(pn, x_min, 1, z_min), x_min, x_max, x, options.min_size)
local width2 = x_max2 - x_min2 + 1 local width2 = x_max2 - x_min2 + 1
if (width2 < options.min_size) or ((width - width2) < options.min_size) then if (width2 < options.min_size) or ((width - width2) < options.min_size) then
return pick_department(options, x_min, x_max, z_min, z_max, x, z) return bsp.pick_department(options, x_min, x_max, z_min, z_max, x, z, check_inner)
end end
return subdivide(options, x_min2, x_max2, z_min, z_max, x, z) return bsp.subdivide(options, x_min2, x_max2, z_min, z_max, x, z, check_inner)
end end
end end
return pick_department(options, x_min, x_max, z_min, z_max, x, z) return bsp.pick_department(options, x_min, x_max, z_min, z_max, x, z, check_inner)
end end
local function get_department(options, x, z) function bsp.get_department(options, x, z, check_inner)
return subdivide(options, -4096, 4095, -4096, 4095, x, z) return bsp.subdivide(options, -4096, 4095, -4096, 4095, x, z, check_inner)
end end
minetest.register_on_generated(function(minp, maxp, seed) minetest.register_on_generated(function(minp, maxp, seed)
@ -67,7 +100,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
for x = minp.x, maxp.x, 16 do for x = minp.x, maxp.x, 16 do
local mapblock_x = x / 16 local mapblock_x = x / 16
local mapblock_z = z / 16 local mapblock_z = z / 16
local department, edges = get_department(ikea.mapgen_options, mapblock_x, mapblock_z) local department, edges = bsp.get_department(ikea.mapgen_options, mapblock_x, mapblock_z, true)
local schem, context = department.get_schematic(edges, x, z) local schem, context = department.get_schematic(edges, x, z)
minetest.place_schematic_on_vmanip(vm, {x = x, y = 0, z = z}, schem, 0, nil, true, "") minetest.place_schematic_on_vmanip(vm, {x = x, y = 0, z = z}, schem, 0, nil, true, "")

View File

@ -41,24 +41,37 @@ function schems.get_outer(Perlin, edges, x, z)
end end
-- Doorways -- Doorways
if edges.s then if place_opening(x) then
if place_opening(x) then if edges.s then
schematic.fill_area(schem, "air", {x=6,y=0,z=0}, {x=9,y=4,z=0}) if edges.inner.s then
schematic.fill_area(schem, "air", {x=3,y=0,z=0}, {x=13,y=4,z=0})
else
schematic.fill_area(schem, "air", {x=6,y=0,z=0}, {x=9,y=4,z=0})
end
end
if edges.n then
if edges.inner.n then
schematic.fill_area(schem, "air", {x=3,y=0,z=15}, {x=13,y=4,z=15})
else
schematic.fill_area(schem, "air", {x=6,y=0,z=15}, {x=9,y=4,z=15})
end
end end
end end
if edges.n then
if place_opening(x) then if place_opening(z) then
schematic.fill_area(schem, "air", {x=6,y=0,z=15}, {x=9,y=4,z=15}) if edges.e then
if edges.inner.e then
schematic.fill_area(schem, "air", {x=15,y=0,z=0}, {x=15,y=4,z=10})
else
schematic.fill_area(schem, "air", {x=15,y=0,z=3}, {x=15,y=4,z=6})
end
end end
end if edges.w then
if edges.e then if edges.inner.w then
if place_opening(z) then schematic.fill_area(schem, "air", {x=0,y=0,z=0}, {x=0,y=4,z=10})
schematic.fill_area(schem, "air", {x=15,y=0,z=3}, {x=15,y=4,z=6}) else
end schematic.fill_area(schem, "air", {x=0,y=0,z=3}, {x=0,y=4,z=6})
end end
if edges.w then
if place_opening(z) then
schematic.fill_area(schem, "air", {x=0,y=0,z=3}, {x=0,y=4,z=6})
end end
end end