flatgen/init_legacy.lua

143 lines
3.3 KiB
Lua

-- Fallback code in case there's already a terrain configuration file existing
-- License: CC0
local params = { ... }
local terrain_file = params[1]
-- Y position where the terrain starts to generate
local generator_start_y = params[2]
-- Default settings: grass, dirt, dirt, dirt with stone ground
local layers = {
{ "default:dirt_with_grass", 1 },
{ "default:dirt", 3 },
{ "default:stone", nil } -- nil = no limit
-- Fake ignore to generate whenever you want: { "ignore_me", 1 }
}
minetest.set_mapgen_params({
mgname = "singlenode",
water_level = -31000,
flags = "light"
})
local function readOrCreateTerrainSettings()
local file = io.open(terrain_file, "r")
if file then
-- Load existing world file
local data = minetest.deserialize(file:read("*all"))
file:close()
assert(data, "[flatgen] Can not deserialize the terrain file")
layers = data
return
end
-- Copy default params to the world file
file = io.open(terrain_file, "w")
file:write(minetest.serialize(layers))
file:close()
end
readOrCreateTerrainSettings()
minetest.after(0, function()
-- Transform node strings to content ID
for i, v in ipairs(layers) do
assert(minetest.registered_nodes[v[1]], "[flatgen] Unknown node: "..v[1])
v[1] = minetest.get_content_id(v[1])
end
end)
minetest.register_chatcommand("regenerate", {
description = "Regenerates a <size>^3 nodes around you",
params = "<size>",
privs = {server=true},
func = function(name, param)
local size = tonumber(param) or 0
if size < 10 then
return false, "Please submit a size number >= 10"
end
size = math.floor(size / 2)
local player = minetest.get_player_by_name(name)
local pos = vector.round(player:getpos())
flatgen_generate(
vector.subtract(pos, size),
vector.add(pos, size),
0, true
)
return true, "Done!"
end
})
local c_air = minetest.get_content_id("air")
function flatgen_getNode(y, regenerate)
if y > generator_start_y then
return c_air
end
local depth = generator_start_y
for i, v in ipairs(layers) do
if not v[2] or depth - v[2] < y then
return v[1]
end
depth = depth - v[2]
end
return regenerate and c_air --or nil
end
function flatgen_generate(minp, maxp, seed, regenerate)
if minp.y > generator_start_y then
return -- Area outside of the generation area
end
if not flatgen_getNode(maxp.y) then
return -- No node defined for that position or below
end
local vm, emin, emax
if regenerate then -- Load regular VManip to regenerate area
vm = minetest.get_voxel_manip()
emin, emax = vm:read_from_map(minp, maxp)
else -- Load VManip from map generator
vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
end
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
for z = minp.z, maxp.z do
for y = minp.y, maxp.y do
local vi = area:index(minp.x, y, z)
local node = flatgen_getNode(y, regenerate)
for x = minp.x, maxp.x do
if node then
data[vi] = node
end
vi = vi + 1
end
end
end
vm:set_data(data)
if not regenerate then
vm:set_lighting({day=0, night=0})
end
vm:calc_lighting()
vm:write_to_map(data)
if regenerate then
vm:update_map()
end
end
table.insert(minetest.registered_on_generateds, 1, flatgen_generate)
minetest.register_node(":ignore_me", {
description = "You hacker you!",
tiles = {"default_cloud.png"},
paramtype = "light",
sunlight_propagates = true,
pointable = false,
drop = "",
})