Add decoration engine
This commit still has an unexplained bug where it fails to place schematics underground, and this is to be investigated.pull/2/head
parent
24f164fc6c
commit
4c3d40fdbd
155
init.lua
155
init.lua
|
@ -704,12 +704,13 @@ function internal.generate_caves(data, minp, maxp)
|
||||||
)
|
)
|
||||||
|
|
||||||
local air = minetest.get_content_id("air")
|
local air = minetest.get_content_id("air")
|
||||||
|
local schems = {}
|
||||||
|
|
||||||
-- Place blocks where necessary
|
-- Place blocks where necessary
|
||||||
internal.iter_3d_area(bminp, bmaxp, function (i, pos)
|
internal.iter_3d_area(bminp, bmaxp, function (i, pos)
|
||||||
|
|
||||||
|
local vi = vmanip:pos_to_index(pos)
|
||||||
local function place(name)
|
local function place(name)
|
||||||
local vi = vmanip:pos_to_index(pos)
|
|
||||||
|
|
||||||
if vmanip:get_index(vi) == air then
|
if vmanip:get_index(vi) == air then
|
||||||
elseif type(name) == "string" then
|
elseif type(name) == "string" then
|
||||||
|
@ -726,14 +727,6 @@ function internal.generate_caves(data, minp, maxp)
|
||||||
elseif nt == internal.node_types.stick_edge then
|
elseif nt == internal.node_types.stick_edge then
|
||||||
elseif nt == internal.node_types.air then
|
elseif nt == internal.node_types.air then
|
||||||
place("air")
|
place("air")
|
||||||
elseif nt == internal.node_types.floor_deco then
|
|
||||||
for _, deco in ipairs(noordstar_caves.registered_decorations) do
|
|
||||||
if deco.place_on ~= "floor" then
|
|
||||||
elseif math.random() > deco.fill_ratio then
|
|
||||||
else
|
|
||||||
-- TODO: Check for biome
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
-- Find appropriate biome
|
-- Find appropriate biome
|
||||||
local heat = heat_points:get_index(i)
|
local heat = heat_points:get_index(i)
|
||||||
|
@ -747,6 +740,32 @@ function internal.generate_caves(data, minp, maxp)
|
||||||
place(def.node_wall)
|
place(def.node_wall)
|
||||||
elseif nt == internal.node_types.ceiling then
|
elseif nt == internal.node_types.ceiling then
|
||||||
place(def.node_roof)
|
place(def.node_roof)
|
||||||
|
elseif nt == internal.node_types.floor_deco then
|
||||||
|
local schem_placed = false
|
||||||
|
|
||||||
|
if not schem_placed then
|
||||||
|
-- Prevent decorations from spawning in the air
|
||||||
|
if vmanip:get_index(vi) == air then
|
||||||
|
schem_placed = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not schem_placed then
|
||||||
|
for _, deco in ipairs(noordstar_caves.registered_decorations) do
|
||||||
|
if deco.place_on ~= "floor" then
|
||||||
|
elseif math.random() > deco.fill_ratio then
|
||||||
|
elseif not internal.is_deco_biome(deco, def.name) then
|
||||||
|
else
|
||||||
|
table.insert(schems, { pos = pos, deco = deco })
|
||||||
|
schem_placed = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not schem_placed then
|
||||||
|
place(def.node_dust or "air")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
error(
|
error(
|
||||||
table.concat(
|
table.concat(
|
||||||
|
@ -763,7 +782,7 @@ function internal.generate_caves(data, minp, maxp)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return vmanip.arr
|
return vmanip.arr, schems
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get the noise params for the cave biome temperature.
|
-- Get the noise params for the cave biome temperature.
|
||||||
|
@ -799,6 +818,23 @@ function internal.is_cave_node(noise, vastness)
|
||||||
return noise > 1 - vastness
|
return noise > 1 - vastness
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Return whether a given decoration definition can spawn in a given biome name
|
||||||
|
function internal.is_deco_biome(def, biome_name)
|
||||||
|
if type(def.biomes) == "nil" then
|
||||||
|
return true
|
||||||
|
elseif type(def.biomes) == "string" then
|
||||||
|
return def.biomes == biome_name
|
||||||
|
elseif type(def.biomes) == "table" then
|
||||||
|
for _, name in pairs(def.biomes) do
|
||||||
|
if name == biome_name then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
-- Return a bool whether a position is within a given volume
|
-- Return a bool whether a position is within a given volume
|
||||||
function internal.is_valid_pos(pos, minp, maxp)
|
function internal.is_valid_pos(pos, minp, maxp)
|
||||||
if minp.x <= pos.x and pos.x <= maxp.x then
|
if minp.x <= pos.x and pos.x <= maxp.x then
|
||||||
|
@ -869,6 +905,80 @@ end
|
||||||
-- minetest.chat_send_all(os.time() .. " - " .. text)
|
-- minetest.chat_send_all(os.time() .. " - " .. text)
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
|
-- Place a table full of schematics into the world
|
||||||
|
function internal.place_schematics(schems)
|
||||||
|
for _, schem in ipairs(schems) do
|
||||||
|
local pos = schem.pos
|
||||||
|
local deco = schem.deco
|
||||||
|
|
||||||
|
if deco.deco_type == "simple" then
|
||||||
|
local h_min = deco.height
|
||||||
|
local h_max = math.max(deco.height_max, deco.height)
|
||||||
|
local dy = deco.place_offset_y - 1
|
||||||
|
|
||||||
|
if deco.place_on == "floor" then
|
||||||
|
for y = 1, math.random(h_min, h_max), 1 do
|
||||||
|
|
||||||
|
minetest.set_node(
|
||||||
|
{ x = pos.x, y = pos.y + y + dy, z = pos.z },
|
||||||
|
{ name = deco.decoration }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
elseif deco.place_on == "ceiling" then
|
||||||
|
for y = 1, math.random(h_min, h_max), 1 do
|
||||||
|
|
||||||
|
minetest.set_node(
|
||||||
|
{ x = pos.x, y = pos.y - y - dy, z = pos.z },
|
||||||
|
{ name = deco.decoration }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("Unknown place_on parameter `" .. deco.place_on .. "` for simple decoration!")
|
||||||
|
end
|
||||||
|
elseif deco.deco_type == "schematic" then
|
||||||
|
local name = deco.schematic
|
||||||
|
local force_placement = true
|
||||||
|
if string.find("force_placement", deco.flags) then
|
||||||
|
force_placement = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if deco.place_on == "floor" then
|
||||||
|
local n = minetest.place_schematic(
|
||||||
|
pos, name, deco.rotation, deco.replacements,
|
||||||
|
force_placement, deco.flags
|
||||||
|
)
|
||||||
|
|
||||||
|
if type(n) == "nil" then
|
||||||
|
minetest.chat_send_all("Squeak could not load!")
|
||||||
|
else
|
||||||
|
minetest.chat_send_all("Placed a Squeak!")
|
||||||
|
if not tpd_yet then
|
||||||
|
minetest.get_player_by_name("singleplayer"):move_to(pos)
|
||||||
|
tpd_yet = true
|
||||||
|
minetest.chat_send_all(internal.pos_to_str(pos))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif deco.place_on == "ceiling" then
|
||||||
|
-- Aim to place schematic against the ceiling, not through it
|
||||||
|
local h = minetest.read_schematic(name).size.y
|
||||||
|
local c_pos = { x = pos.x, y = pos.y - h, z = pos.z }
|
||||||
|
if string.find("place_center_y", deco.flags) then
|
||||||
|
c_pos = pos
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.place_schematic(
|
||||||
|
pos, name, deco.rotation, deco.replacements,
|
||||||
|
force_placement, deco.flags
|
||||||
|
)
|
||||||
|
else
|
||||||
|
error("Unknown place_on parameter `" .. deco.place_on .. "` for simple decoration!")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("Unknown decoration type `" .. deco.deco_type .. "`")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Helper function to convert a set of coordinates to a readable string
|
-- Helper function to convert a set of coordinates to a readable string
|
||||||
function internal.pos_to_str(pos)
|
function internal.pos_to_str(pos)
|
||||||
return "(" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. " )"
|
return "(" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. " )"
|
||||||
|
@ -1090,13 +1200,17 @@ end
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||||
|
math.randomseed(blockseed)
|
||||||
|
|
||||||
local vm = minetest.get_mapgen_object("voxelmanip")
|
local vm = minetest.get_mapgen_object("voxelmanip")
|
||||||
local data = vm:get_data()
|
local data = vm:get_data()
|
||||||
|
|
||||||
data = internal.generate_caves(data, minp, maxp)
|
data, schems = internal.generate_caves(data, minp, maxp)
|
||||||
|
|
||||||
vm:set_data(data)
|
vm:set_data(data)
|
||||||
vm:write_to_map()
|
vm:write_to_map()
|
||||||
|
|
||||||
|
internal.place_schematics(schems)
|
||||||
end)
|
end)
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@ -1202,6 +1316,7 @@ noordstar_caves.register_biome({
|
||||||
node_floor = "mcl_core:crying_obsidian",
|
node_floor = "mcl_core:crying_obsidian",
|
||||||
node_wall = "mcl_core:sand",
|
node_wall = "mcl_core:sand",
|
||||||
node_roof = "mcl_ocean:sea_lantern",
|
node_roof = "mcl_ocean:sea_lantern",
|
||||||
|
node_dust = "mcl_core:snow",
|
||||||
heat_point = 0,
|
heat_point = 0,
|
||||||
humidity_point = 0,
|
humidity_point = 0,
|
||||||
})
|
})
|
||||||
|
@ -1213,3 +1328,21 @@ noordstar_caves.register_biome({
|
||||||
heat_point = 100,
|
heat_point = 100,
|
||||||
humidity_point = 100,
|
humidity_point = 100,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
noordstar_caves.register_decoration({
|
||||||
|
deco_type = "simple",
|
||||||
|
place_on = "floor",
|
||||||
|
fill_ratio = 0.01,
|
||||||
|
decoration = "mcl_core:cactus",
|
||||||
|
height = 3,
|
||||||
|
height_max = 8,
|
||||||
|
biomes = { "test" },
|
||||||
|
})
|
||||||
|
noordstar_caves.register_decoration({
|
||||||
|
deco_type = "schematic",
|
||||||
|
place_on = "floor",
|
||||||
|
fill_ratio = 0.005,
|
||||||
|
schematic = "test.mts",
|
||||||
|
rotation = "random",
|
||||||
|
place_offset_y = 5,
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue