Add decoration engine
This commit still has an unexplained bug where it fails to place schematics underground, and this is to be investigated.
parent
5005ae7d32
commit
39406abfaf
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 vi = vmanip:pos_to_index(pos)
|
||||
local function place(name)
|
||||
local vi = vmanip:pos_to_index(pos)
|
||||
|
||||
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