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 schems = {}
|
||||
|
||||
-- Place blocks where necessary
|
||||
internal.iter_3d_area(bminp, bmaxp, function (i, pos)
|
||||
|
||||
local function place(name)
|
||||
local vi = vmanip:pos_to_index(pos)
|
||||
local function place(name)
|
||||
|
||||
if vmanip:get_index(vi) == air 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.air then
|
||||
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
|
||||
-- Find appropriate biome
|
||||
local heat = heat_points:get_index(i)
|
||||
|
@ -747,6 +740,32 @@ function internal.generate_caves(data, minp, maxp)
|
|||
place(def.node_wall)
|
||||
elseif nt == internal.node_types.ceiling then
|
||||
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
|
||||
error(
|
||||
table.concat(
|
||||
|
@ -763,7 +782,7 @@ function internal.generate_caves(data, minp, maxp)
|
|||
end
|
||||
end)
|
||||
|
||||
return vmanip.arr
|
||||
return vmanip.arr, schems
|
||||
end
|
||||
|
||||
-- Get the noise params for the cave biome temperature.
|
||||
|
@ -799,6 +818,23 @@ function internal.is_cave_node(noise, vastness)
|
|||
return noise > 1 - vastness
|
||||
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
|
||||
function internal.is_valid_pos(pos, minp, maxp)
|
||||
if minp.x <= pos.x and pos.x <= maxp.x then
|
||||
|
@ -869,6 +905,80 @@ end
|
|||
-- minetest.chat_send_all(os.time() .. " - " .. text)
|
||||
-- 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
|
||||
function internal.pos_to_str(pos)
|
||||
return "(" .. pos.x .. ", " .. pos.y .. ", " .. pos.z .. " )"
|
||||
|
@ -1090,13 +1200,17 @@ end
|
|||
-------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||
math.randomseed(blockseed)
|
||||
|
||||
local vm = minetest.get_mapgen_object("voxelmanip")
|
||||
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:write_to_map()
|
||||
|
||||
internal.place_schematics(schems)
|
||||
end)
|
||||
-------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -1202,6 +1316,7 @@ noordstar_caves.register_biome({
|
|||
node_floor = "mcl_core:crying_obsidian",
|
||||
node_wall = "mcl_core:sand",
|
||||
node_roof = "mcl_ocean:sea_lantern",
|
||||
node_dust = "mcl_core:snow",
|
||||
heat_point = 0,
|
||||
humidity_point = 0,
|
||||
})
|
||||
|
@ -1213,3 +1328,21 @@ noordstar_caves.register_biome({
|
|||
heat_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