Rename mapgen API methods, fix errors

This commit is contained in:
kay27 2021-08-05 04:01:07 +04:00
parent e226d6ce45
commit 72e88f1980
12 changed files with 270 additions and 253 deletions

View File

@ -3,42 +3,13 @@
Helps to avoid problems caused by 'chunk-in-shell' feature of mapgen.cpp.
It also queues your generators to run them in proper order:
## mcl_mapgen.register_chunk_generator(chunk_callback_function, priority)
=========================================================================
Registers callback function to be called when current chunk generation is finished.
`callback_function`: chunk callback function definition:
`function(minp, maxp, seed)`:
`minp` & `maxp`: minimum and maximum chunk position;
`seed`: seed of this mapchunk;
`priority` (optional): order number - the less, the earlier,
e.g. `mcl_mapgen.priorities.BUILDINGS` or `mcl_mapgen.priorities.LARGE_BUILDINGS`
## mcl_mapgen.register_block_generator(callback_function, priority)
===================================================================
Registers callback function to be called when block (usually 16x16x16 nodes) generation is finished.
`callback_function`: block callback function definition, see below;
`priority` (optional): order number - the less, the earlier,
e.g. `mcl_mapgen.priorities.BUILDINGS` or `mcl_mapgen.priorities.LARGE_BUILDINGS`
## mcl_mapgen.register_block_generator_lvm(callback_function, priority)
=======================================================================
Registers callback function to be called when block (usually 16x16x16 nodes) generation is finished.
`vm_context` passes into callback function and should be returned back.
`callback_function`: block callback LVM function definition, see below;
`priority` (optional): order number - the less, the earlier,
e.g. `mcl_mapgen.priorities.BUILDINGS` or `mcl_mapgen.priorities.LARGE_BUILDINGS`
## mcl_mapgen.register_chunk_generator_lvm(callback_function, priority)
=======================================================================
UNSAFE! See https://git.minetest.land/MineClone2/MineClone2/issues/1395
Registers callback function to be called when current chunk generation is finished.
IT IS UNSAFE! GROUND CONTENT YOU PLACE (INCLUDING WATER AND AIR) CAN BE OVERWRITTEN BY cavegen.
ALL OTHER API FUNCTIONS ARE SAFE! USE THEM PLEASE! BUT WE NEED THIS FUNCTION STILL SOMETIMES,
WHEN WE NEED TO ACCESS MAPGEN OBJECTS like `heightmap`, `biomemap`, ETC.
`callback_function`: chunk callback LVM function definition, see below;
### mcl_mapgen.register_on_generated(callback_function, order_number)
For Minetest 5.4 it doesn't recommended to place blocks within callback function.
See https://git.minetest.land/MineClone2/MineClone2/issues/1395
`callback_function`: chunk callback LVM function definition:
`function(vm_context)`:
Function MUST RETURN `vm_context` back anyway! It will passed into next callback function from the queue.
`vm_context`: a table which already contains some LVM data if the fields, and some of them can be added right in callback function:
`vm_context`: a table which already contains some LVM data if the fields, and some of them can be added by you right in the callback function:
`vm`: curent voxel manipulator object itself;
`blockseed`: seed of this mapchunk;
`minp` & `maxp`: minimum and maximum chunk position;
@ -52,23 +23,61 @@ WHEN WE NEED TO ACCESS MAPGEN OBJECTS like `heightmap`, `biomemap`, ETC.
`lvm_param2_buffer`: static `param2` buffer pointer, used to load `data2` array;
`shadow`: set it to false to disable shadow propagation;
`heightmap`: mapgen object contanting y coordinates of ground level,
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourfels:
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - load it yourfels:
`vm_context.heightmap = vm_context.heightmap or minetest.get_mapgen_object('heightmap')`
`biomemap`: mapgen object contanting biome IDs of nodes,
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourfels:
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - load it yourfels:
`vm_context.biomemap = vm_context.biomemap or minetest.get_mapgen_object('biomemap')`
`heatmap`: mapgen object contanting temperature values of nodes,
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourfels:
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - load it yourfels:
`vm_context.heatmap = vm_context.heatmap or minetest.get_mapgen_object('heatmap')`
`humiditymap`: mapgen object contanting humidity values of nodes,
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourfels:
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - load it yourfels:
`vm_context.humiditymap = vm_context.humiditymap or minetest.get_mapgen_object('humiditymap')`
`gennotify`: mapgen object contanting mapping table of structures, see Minetest Lua API for explanation,
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourfels:
!NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - load it yourfels:
`vm_context.gennotify = vm_context.gennotify or minetest.get_mapgen_object('gennotify')`
`priority` (optional): order number - the less, the earlier,
e.g. `mcl_mapgen.priorities.BUILDINGS` or `mcl_mapgen.priorities.LARGE_BUILDINGS`
`order_number` (optional): the less, the earlier,
e.g. `mcl_mapgen.order.BUILDINGS` or `mcl_mapgen.order.LARGE_BUILDINGS`
## mcl_mapgen.get_far_node(pos)
### mcl_mapgen.register_mapgen(callback_function, order_number)
==============================================================================
Registers callback function to be called when current chunk generation is finished.
`callback_function`: callback function definition:
`function(minp, maxp, seed)`:
`minp` & `maxp`: minimum and maximum chunk position;
`seed`: seed of this mapchunk;
`order_number` (optional): the less, the earlier,
e.g. `mcl_mapgen.order.BUILDINGS` or `mcl_mapgen.order.LARGE_BUILDINGS`
### mcl_mapgen.register_mapgen_block(callback_function, order_number)
=======================================================================
Registers callback function to be called when block (usually 16x16x16 nodes) generation is finished.
`callback_function`: callback function definition:
`function(minp, maxp, seed)`:
`minp` & `maxp`: minimum and maximum block position;
`seed`: seed of this mapblock;
`order_number` (optional): the less, the earlier,
e.g. `mcl_mapgen.order.BUILDINGS` or `mcl_mapgen.order.LARGE_BUILDINGS`
### mcl_mapgen.register_mapgen_block_lvm(callback_function, order_number)
============================================================================
Registers callback function to be called when block (usually 16x16x16 nodes) generation is finished.
`vm_context` passes into callback function and should be returned back.
`callback_function`: block callback LVM function definition, see below;
`order_number` (optional): the less, the earlier,
e.g. `mcl_mapgen.order.BUILDINGS` or `mcl_mapgen.order.LARGE_BUILDINGS`
### mcl_mapgen.register_mapgen_lvm(callback_function, order_number)
============================================================================
### mcl_mapgen.get_far_node(pos)
===============================
Returns node if it is generated. Otherwise returns `{name = "ignore"}`.
## Constants:
* `mcl_mapgen.EDGE_MIN`, `mcl_mapgen.EDGE_MAX` - world edges, min & max.
* `mcl_mapgen.seed`, `mcl_mapgen.name` - mapgen seed & name.
* `mcl_mapgen.v6`, `mcl_mapgen.superflat`, `mcl_mapgen.singlenode` - is mapgen v6, superflat, singlenode.
* `mcl_mapgen.normal` is mapgen normal (not superflat or singlenode).

View File

@ -1,6 +1,6 @@
mcl_mapgen = {}
local priorities = { -- mcl_mapgen.priorities...
local order = { -- mcl_mapgen.order...
DEFAULT = 5000,
CHORUS = 100000,
BUILDINGS = 200000,
@ -43,12 +43,13 @@ local numcmax = math_max(math_floor((mapgen_limit_max - ccfmax) / mcl_mapgen.CS_
mcl_mapgen.EDGE_MIN = central_chunk_min_pos - numcmin * mcl_mapgen.CS_NODES
mcl_mapgen.EDGE_MAX = central_chunk_max_pos + numcmax * mcl_mapgen.CS_NODES
minetest_log("action", "[mcl_mapgen] World edges are: mcl_mapgen.EDGE_MIN = " .. tostring(mcl_mapgen.EDGE_MIN) .. ", mcl_mapgen.EDGE_MAX = " .. tostring(mcl_mapgen.EDGE_MAX))
minetest_log("action", "[mcl_mapgen] World edges: mcl_mapgen.EDGE_MIN = " .. tostring(mcl_mapgen.EDGE_MIN) .. ", mcl_mapgen.EDGE_MAX = " .. tostring(mcl_mapgen.EDGE_MAX))
------------------------------------------
-- Mapgen variables
local overworld, end_, nether = {}, {}, {}
mcl_mapgen.seed = minetest.get_mapgen_setting("seed")
local seed = minetest.get_mapgen_setting("seed")
mcl_mapgen.seed = seed
mcl_mapgen.name = minetest.get_mapgen_setting("mg_name")
mcl_mapgen.v6 = mcl_mapgen.name == "v6"
mcl_mapgen.superflat = mcl_mapgen.name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true"
@ -59,9 +60,8 @@ local superflat, singlenode, normal = mcl_mapgen.superflat, mcl_mapgen.singlenod
minetest_log("action", "[mcl_mapgen] Mapgen mode: " .. (normal and "normal" or (superflat and "superflat" or "singlenode")))
------------------------------------------
local lvm_block_queue, lvm_chunk_queue, node_block_queue, node_chunk_queue = {}, {}, {}, {} -- Generators' queues
local lvm, block, lvm_block, lvm_chunk, param2, nodes_block, nodes_chunk, safe_functions = 0, 0, 0, 0, 0, 0, 0, 0 -- Requirements: 0 means none; greater than 0 means 'required'
local lvm_buffer, lvm_param2_buffer = {}, {} -- Static buffer pointers
local queue_unsafe, queue_blocks_lvm, queue_lvm, queue_blocks, queue = {}, {}, {}, {}, {} -- Generators' queues
local lvm, block, queue_blocks_lvm_counter, lvm_chunk, param2, nodes_block, nodes_chunk, safe_functions = 0, 0, 0, 0, 0, 0, 0, 0 -- Requirements: 0 means none; greater than 0 means 'required'
local BS, CS = mcl_mapgen.BS, mcl_mapgen.CS -- Mapblock size (in nodes), Mapchunk size (in blocks)
local LAST_BLOCK, LAST_NODE = CS - 1, BS - 1 -- First mapblock in chunk (node in mapblock) has number 0, last has THIS number. It's for runtime optimization
local offset = mcl_mapgen.OFFSET -- Central mapchunk offset (in blocks)
@ -69,59 +69,39 @@ local CS_NODES = mcl_mapgen.CS_NODES -- 80
local CS_3D = CS * CS * CS
local DEFAULT_PRIORITY = priorities.DEFAULT
local DEFAULT_ORDER = order.DEFAULT
function mcl_mapgen.register_chunk_generator(callback_function, priority)
function mcl_mapgen.register_on_generated(callback_function, order)
queue_unsafe[#queue_unsafe+1] = {i = priority or DEFAULT_ORDER, f = callback_function}
table.sort(queue_lvm, function(a, b) return (a.i <= b.i) end)
end
function mcl_mapgen.register_mapgen(callback_function, order)
nodes_chunk = nodes_chunk + 1
safe_functions = safe_functions + 1
node_chunk_queue[nodes_chunk] = {i = priority or DEFAULT_PRIORITY, f = callback_function}
table.sort(node_chunk_queue, function(a, b) return (a.i <= b.i) end)
queue[nodes_chunk] = {i = order or DEFAULT_ORDER, f = callback_function}
table.sort(queue, function(a, b) return (a.i <= b.i) end)
end
function mcl_mapgen.register_chunk_generator_lvm(callback_function, priority)
function mcl_mapgen.register_mapgen_lvm(callback_function, order)
lvm = lvm + 1
lvm_chunk_queue[lvm_chunk] = {i = priority or DEFAULT_PRIORITY, f = callback_function}
table.sort(lvm_chunk_queue, function(a, b) return (a.i <= b.i) end)
lvm_chunk = lvm_chunk + 1
safe_functions = safe_functions + 1
queue_lvm[lvm_chunk] = {i = priority or DEFAULT_ORDER, f = callback_function}
table.sort(queue_lvm, function(a, b) return (a.i <= b.i) end)
end
function mcl_mapgen.register_block_generator(callback_function, priority)
function mcl_mapgen.register_mapgen_block(callback_function, priority)
block = block + 1
nodes_block = nodes_block + 1
safe_functions = safe_functions + 1
node_block_queue[nodes_block] = {i = priority or DEFAULT_PRIORITY, f = callback_function}
table.sort(node_block_queue, function(a, b) return (a.i <= b.i) end)
queue_blocks[nodes_block] = {i = priority or DEFAULT_ORDER, f = callback_function}
table.sort(queue_blocks, function(a, b) return (a.i <= b.i) end)
end
function mcl_mapgen.register_block_generator_lvm(callback_function, priority)
function mcl_mapgen.register_mapgen_block_lvm(callback_function, order)
block = block + 1
lvm = lvm + 1
lvm_block = lvm_block + 1
lvm_block_queue[lvm_block] = {i = priority or DEFAULT_PRIORITY, f = callback_function}
table.sort(lvm_block_queue, function(a, b) return (a.i <= b.i) end)
end
function mcl_mapgen.get_block_seed(pos, seed)
local p = pos
local x, y, z = p.x, p.y, p.z
if x<0 then x = 4294967296+x end
if y<0 then y = 4294967296+y end
if z<0 then z = 4294967296+z end
local seed = (seed or mcl_mapgen.seed or 0) % 4294967296
return (seed + (z*38134234)%4294967296 + (y*42123)%4294967296 + (x*23)%4294967296) % 4294967296
end
function mcl_mapgen.get_block_seed_2(pos, seed)
local p = pos
local seed = seed or mcl_mapgen.seed or 0
local x, y, z = p.x, p.y, p.z
if x<0 then x = 4294967296+x end
if y<0 then y = 4294967296+y end
if z<0 then z = 4294967296+z end
local n = ((1619*x)%4294967296 + (31337*y)%4294967296 + (52591*z)%4294967296 + (1013*seed)%4294967296) % 4294967296
-- n = (math_floor(n / 8192) ^ n) % 4294967296
local m = (n*n) % 4294967296
m = (m*60493) % 4294967296
m = (m+19990303) % 4294967296
return (n * m + 1376312589) % 4294967296
queue_blocks_lvm_counter =queue_blocks_lvm_counter + 1
safe_functions = safe_functions + 1
queue_blocks_lvm[queue_blocks_lvm_counter] = {order = order or DEFAULT_ORDER, callback_function = callback_function}
table.sort(queue_blocks_lvm, function(a, b) return (a.order <= b.order) end)
end
local storage = minetest.get_mod_storage()
@ -132,37 +112,44 @@ minetest.register_on_shutdown(function()
storage:set_string("mapgen_blocks", minetest.serialize(blocks))
end)
local vm_context-- here will be many references and flags, like: param2, light_data, heightmap, biomemap, heatmap, humiditymap, gennotify, write_lvm, write_param2, shadow
local vm_context -- here will be many references and flags, like: param2, light_data, heightmap, biomemap, heatmap, humiditymap, gennotify, write_lvm, write_param2, shadow
local data, data2, area
local current_blocks = {}
local current_chunks = {}
local lvm_buffer, lvm_param2_buffer = {}, {} -- Static buffer pointers
minetest.register_on_generated(function(minp, maxp, blockseed)
local minp, maxp, blockseed = minp, maxp, blockseed
minetest.register_on_generated(function(minp, maxp, chunkseed)
local minp, maxp, chunkseed = minp, maxp, chunkseed
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
minetest_log("warning", "[mcl_mapgen] New_chunk=" .. minetest_pos_to_string(minp) .. "..." .. minetest_pos_to_string(maxp) .. ", shell=" .. minetest_pos_to_string(emin) .. "..." .. minetest_pos_to_string(emax) .. ", blockseed=" .. tostring(blockseed) .. ", seed1=" .. mcl_mapgen.get_block_seed(minp) .. ", seed2=" .. mcl_mapgen.get_block_seed_2(minp))
minetest_log("warning", "[mcl_mapgen] New_chunk=" .. minetest_pos_to_string(minp) .. "..." .. minetest_pos_to_string(maxp) .. ", shell=" .. minetest_pos_to_string(emin) .. "..." .. minetest_pos_to_string(emax) .. ", chunkseed=" .. tostring(chunkseed))
if lvm > 0 then
vm_context = {lvm_param2_buffer = lvm_param2_buffer, vm = vm, emin = emin, emax = emax, minp = minp, maxp = maxp, blockseed = blockseed}
data = vm:get_data(lvm_buffer)
vm_context.data = data
area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
vm_context.area = area
end
vm_context = {
data = data,
area = area,
lvm_param2_buffer = lvm_param2_buffer,
vm = vm,
emin = emin,
emax = emax,
minp = minp,
maxp = maxp,
chunkseed = chunkseed
}
if safe_functions > 0 then
local x0, y0, z0 = minp.x, minp.y, minp.z
local bx0, by0, bz0 = math_floor(x0/BS), math_floor(y0/BS), math_floor(z0/BS)
local bx1, by1, bz1 = bx0 + LAST_BLOCK, by0 + LAST_BLOCK, bz0 + LAST_BLOCK -- only for entire chunk check
-- Keep `blockseed` in `chunks[cx][cy][cz].seed` for further safe usage:
-- Keep `chunkseed` in `chunks[cx][cy][cz].seed` for further safe usage:
local cx0, cy0, cz0 = math_floor((bx0-offset)/CS), math_floor((by0-offset)/CS), math_floor((bz0-offset)/CS)
if not chunks[cx0] then chunks[cx0] = {} end
if not chunks[cx0][cy0] then chunks[cx0][cy0] = {} end
if not chunks[cx0][cy0][cz0] then
chunks[cx0][cy0][cz0] = {seed = blockseed, counter = 0}
chunks[cx0][cy0][cz0] = {seed = chunkseed, counter = 0}
else
chunks[cx0][cy0][cz0].seed = blockseed
chunks[cx0][cy0][cz0].seed = chunkseed
end
local x1, y1, z1, x2, y2, z2 = emin.x, emin.y, emin.z, emax.x, emax.y, emax.z
@ -233,15 +220,16 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
if next(chunks[cx]) == nil then chunks[cx] = nil end
end
end
vm_context.seed = blockseed + box * 7 + boy * 243 + boz * 11931
if lvm_block > 0 then
vm_context.minp, vm_content.maxp = {x=x, y=y, z=z}, {x=x+LAST_NODE, y=y+LAST_NODE, z=z+LAST_NODE}
for _, v in pairs(lvm_block_queue) do
vm_context = v.f(vm_context)
local blockseed = seed + bx * 7 + by * 243 + bz * 11931
if queue_blocks_lvm_counter > 0 then
vm_context.blockseed = blockseed
vm_context.minp, vm_context.maxp = {x=x, y=y, z=z}, {x=x+LAST_NODE, y=y+LAST_NODE, z=z+LAST_NODE}
for _, v in pairs(queue_blocks_lvm) do
vm_context = v.callback_function(vm_context)
end
end
if nodes_block > 0 then
current_blocks[#current_blocks+1] = { minp = {x=x, y=y, z=z}, maxp = {x=pos.x+LAST_NODE, y=pos.y+LAST_NODE, z=pos.z+LAST_NODE}, seed = seed }
current_blocks[#current_blocks+1] = { minp = {x=x, y=y, z=z}, maxp = {x=x+LAST_NODE, y=y+LAST_NODE, z=z+LAST_NODE}, seed = blockseed }
end
else
blocks[bx][by][bz] = current_mapgen_block_writes
@ -259,7 +247,7 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
end
if lvm > 0 then
for _, v in pairs(lvm_chunk_queue) do
for _, v in pairs(queue_lvm) do
vm_context = v.f(vm_context)
end
if vm_context.write then
@ -279,14 +267,14 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
local x, y, z = bx * BS, by * BS, bz * BS
local minp = {x = x, y = y, z = z}
local maxp = {x = x + CS_NODES - 1, y = y + CS_NODES - 1, z = z + CS_NODES - 1}
for _, v in pairs(node_chunk_queue) do
for _, v in pairs(queue) do
v.f(minp, maxp, seed)
end
current_chunks[i] = nil
end
for i, b in pairs(current_blocks) do
for _, v in pairs(node_block_queue) do
for _, v in pairs(queue_blocks) do
v.f(b.minp, b.maxp, b.seed)
end
current_blocks[i] = nil
@ -386,11 +374,11 @@ else
end
if mcl_mapgen.name == "flat" then
if superflat then
nether.flat_nether_floor = nether.bedrock_bottom_max + 4
nether.flat_nether_ceiling = nether.bedrock_bottom_max + 52
nether.flat_floor = nether.bedrock_bottom_max + 4
nether.flat_ceiling = nether.bedrock_bottom_max + 52
else
nether.flat_nether_floor = nether.lava_max + 4
nether.flat_nether_ceiling = nether.lava_max + 52
nether.flat_floor = nether.lava_max + 4
nether.flat_ceiling = nether.lava_max + 52
end
end
@ -410,4 +398,4 @@ mcl_mapgen.overworld = overworld
mcl_mapgen.end_ = end_
mcl_mapgen.nether = nether
mcl_mapgen.priorities = priorities
mcl_mapgen.order = order

View File

@ -3990,15 +3990,15 @@ if not mcl_mapgen.singlenode then
-- Overworld decorations for v6 are handled in mcl_mapgen_core
if deco_id_chorus_plant then
mcl_mapgen.register_chunk_generator_lvm(function(c)
c.gennotify = c.gennotify or minetest.get_mapgen_object("gennotify")
local gennotify = c.gennotify
mcl_mapgen.register_mapgen_block_lvm(function(vm_context)
vm_context.gennotify = vm_context.gennotify or minetest.get_mapgen_object("gennotify")
local gennotify = vm_context.gennotify
for _, pos in pairs(gennotify["decoration#"..deco_id_chorus_plant] or {}) do
local realpos = { x = pos.x, y = pos.y + 1, z = pos.z }
minetest.after(1, mcl_end.grow_chorus_plant, realpos)
end
return c
end, mcl_mapgen.priorities.CHORUS)
return vm_context
end, mcl_mapgen.order.CHORUS)
end
end

View File

@ -1,45 +1,33 @@
local c_debris = minetest.get_content_id("mcl_nether:ancient_debris")
local c_netherrack = minetest.get_content_id("mcl_nether:netherrack")
local c_air = minetest.get_content_id("air")
local facedir = {
vector.new(0, 0, 1),
vector.new(0, 1, 0),
vector.new(1, 0, 0),
vector.new(0, 0, -1),
vector.new(0, -1, 0),
vector.new(-1, 0, 0),
}
local minetest_find_nodes_in_area = minetest.find_nodes_in_area
local minetest_get_node = minetest.get_node
local minetest_set_node = minetest.set_node
local debris_name = "mcl_nether:ancient_debris"
local netherrack_name = "mcl_nether:netherrack"
local air_name = "air"
local min, max = mcl_mapgen.nether.min, mcl_mapgen.nether.max
minetest.register_on_generated(function(minp, maxp)
if maxp.y < min or minp.y > max then
return
end
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local data = vm:get_data()
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
for idx in area:iter(minp.x, math.max(minp.y, min), minp.z, maxp.x, math.min(maxp.y, max), maxp.z) do
if data[idx] == c_debris then
local pos = area:position(idx)
local exposed = false
for _, dir in pairs(facedir) do
if data[area:indexp(vector.add(pos, dir))] == c_air then
exposed = true
break
end
end
if exposed then
data[idx] = c_netherrack
mcl_mapgen.register_mapgen_block(function(minp, maxp)
local minp = minp
local minp_y = minp.y
if minp_y > max then return end
local maxp = maxp
local maxp_y = maxp.y
if maxp_y < min then return end
local nodes = minetest_find_nodes_in_area(minp, maxp, debris_name)
if nodes then
for _, pos in pairs(nodes) do
minetest.log("warning","debris found at "..minetest.pos_to_string(pos))
local x, y, z = pos.x, pos.y, pos.z
if minetest_get_node({x = x-1, y = y, z = z}) == air_name
or minetest_get_node({x = x+1, y = y, z = z}) == air_name
or minetest_get_node({x = x, y = y-1, z = z}) == air_name
or minetest_get_node({x = x, y = y+1, z = z}) == air_name
or minetest_get_node({x = x, y = y, z = z-1}) == air_name
or minetest_get_node({x = x, y = y, z = z+1}) == air_name then
minetest_set_node(pos, netherrack_name)
minetest.log("warning","debris at "..minetest.pos_to_string(pos) .. " replaced to netherrack")
end
end
end
vm:set_data(data)
vm:calc_lighting()
vm:update_liquids()
vm:write_to_map()
end)

View File

@ -1,4 +1,4 @@
name = mcl_debrisgen
author = Fleckenstein
description = Make sure ancient debris is not generated exposed to air
depends = mcl_mapgen, mcl_mapgen_core, mcl_nether
depends = mcl_mapgen, mcl_nether

View File

@ -9,6 +9,7 @@ end
--lua locals
--minetest
local minetest_find_nodes_in_area = minetest.find_nodes_in_area
local registered_nodes = minetest.registered_nodes
local swap_node = minetest.swap_node
local set_node = minetest.set_node
@ -64,6 +65,7 @@ local surround_vectors = {
-- if calls_remaining >= 1 then return end
-- local p1, _, dim, pr = param.p1, param.p2, param.dim, param.pr
-- local check = not (param.dontcheck or false)
local m1, m2 = 0, 0
local function spawn_dungeon(p1, p2, dim, pr, dontcheck)
local x, y, z = p1.x, p1.y, p1.z
@ -72,10 +74,40 @@ local function spawn_dungeon(p1, p2, dim, pr, dontcheck)
-- Check floor and ceiling: Must be *completely* solid
local y_floor = y
local y_ceiling = y + dim.y + 1
if check then for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do
if check then
local result1, result2 = true, true
local dim_x, dim_z = dim.x, dim.z
local size = dim_z*dim_x
local time1 = minetest.get_us_time()
for i=1,100 do
for tx = x+1, x+dim_x do
for tz = z+1, z+dim_z do
if not registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable
or not registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
end end end
or not registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then
result1 = false
end
end
end
end
local time2 = minetest.get_us_time()
for i=1,100 do
if #minetest_find_nodes_in_area({x=x+1,y=y_floor,z=z+1}, {x=x+dim_z,y=y_floor,z=z+dim_z}, "group:walkabke") < size
or #minetest_find_nodes_in_area({x=x+1,y=y_floor,z=z+1}, {x=x+dim_z,y=y_floor,z=z+dim_z}, "group:walkabke") < size then
result2 = false
end
end
local time3 = minetest.get_us_time()
if result1 == result2 then
local d1, d2 = time2-time1, time3-time2
local m1 = m1 + d1
local m2 = m2 + d2
minetest.chat_send_all("m1 = " .. tostring(m1))
minetest.chat_send_all("m2 = " .. tostring(m2))
else
minetest.log("warning", "results mismatch")
end
end
-- Check for air openings (2 stacked air at ground level) in wall positions
local openings_counter = 0
@ -413,4 +445,4 @@ function mcl_dungeons.spawn_dungeon(p1, _, pr)
spawn_dungeon(p1, p2, dim, pr, true)
end
mcl_mapgen.register_chunk_generator(dungeons_nodes, mcl_mapgen.priorities.DUNGEONS)
mcl_mapgen.register_mapgen(dungeons_nodes, mcl_mapgen.order.DUNGEONS)

View File

@ -10,7 +10,7 @@ local noisemap = PerlinNoiseMap({
local c_end_stone = minetest.get_content_id("mcl_end:end_stone")
local y_offset = -2
minetest.register_on_generated(function(minp, maxp)
mcl_mapgen.register_mapgen(function(minp, maxp)
if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < -75 or minp.x > 75 or maxp.z < -75 or minp.z > 75 then
return
end

View File

@ -784,7 +784,7 @@ local function register_mgv6_decorations()
persist = 0.62,
},
y_min = 1,
y_max = mcl_vars.overworld_max,
y_max = mcl_mapgen.overworld.max,
flags = "",
})
end
@ -837,7 +837,7 @@ local function register_mgv6_decorations()
persist = 0.666
},
y_min = 1,
y_max = mcl_vars.overworld_max,
y_max = mcl_mapgen.overworld.max,
})
-- Melon
@ -875,7 +875,7 @@ local function register_mgv6_decorations()
persist = 0.6
},
y_min = 1,
y_max = mcl_vars.overworld_max,
y_max = mcl_mapgen.overworld.max,
decoration = "mcl_flowers:tallgrass",
})
minetest.register_decoration({
@ -891,7 +891,7 @@ local function register_mgv6_decorations()
persist = 0.6
},
y_min = 1,
y_max = mcl_vars.overworld_max,
y_max = mcl_mapgen.overworld.max,
decoration = "mcl_flowers:tallgrass",
})
@ -916,7 +916,7 @@ local function register_mgv6_decorations()
},
flags = "force_placement",
place_offset_y = -1,
y_min = mcl_vars.overworld_min,
y_min = mcl_mapgen.overworld.min,
y_max = 0,
decoration = "mcl_ocean:seagrass_"..mat,
})
@ -936,7 +936,7 @@ local function register_mgv6_decorations()
},
flags = "force_placement",
place_offset_y = -1,
y_min = mcl_vars.overworld_min,
y_min = mcl_mapgen.overworld.min,
y_max = -5,
decoration = "mcl_ocean:seagrass_"..mat,
})
@ -957,7 +957,7 @@ local function register_mgv6_decorations()
},
flags = "force_placement",
place_offset_y = -1,
y_min = mcl_vars.overworld_min,
y_min = mcl_mapgen.overworld.min,
y_max = -6,
decoration = "mcl_ocean:kelp_"..mat,
param2 = 16,
@ -979,7 +979,7 @@ local function register_mgv6_decorations()
},
flags = "force_placement",
place_offset_y = -1,
y_min = mcl_vars.overworld_min,
y_min = mcl_mapgen.overworld.min,
y_max = -15,
decoration = "mcl_ocean:kelp_"..mat,
param2 = 32,
@ -1017,7 +1017,7 @@ local function register_mgv6_decorations()
sidelen = 8,
fill_ratio = 0.004,
y_min = 1,
y_max = mcl_vars.overworld_max,
y_max = mcl_mapgen.overworld.max,
decoration = "mcl_flowers:tallgrass",
})
@ -1120,7 +1120,7 @@ end
local mg_flags = minetest.settings:get_flags("mg_flags")
-- Inform other mods of dungeon setting for MCL2-style dungeons
mcl_vars.mg_dungeons = mg_flags.dungeons and not superflat
mcl_vars.mg_dungeons = mcl_mapgen.dungeons
-- Disable builtin dungeons, we provide our own dungeons
mg_flags.dungeons = false
@ -1191,8 +1191,8 @@ local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length
local perlin_clay
-- Generate Clay
mcl_mapgen.register_chunk_generator_lvm(function(c)
local minp, maxp, blockseed, voxelmanip_data, voxelmanip_area, lvm_used = c.minp, c.maxp, c.blockseed, c.data, c.area, c.write or false
mcl_mapgen.register_mapgen_lvm(function(c)
local minp, maxp, blockseed, voxelmanip_data, voxelmanip_area, lvm_used = c.minp, c.maxp, c.chunkseed, c.data, c.area, c.write or false
-- TODO: Make clay generation reproducible for same seed.
if maxp.y < -5 or minp.y > 0 then
return c
@ -1799,7 +1799,7 @@ local function generate_nether_decorations(minp, maxp, seed)
-- Note: Spawned *after* the fire because of light level checks
special_deco(rack, function(bpos)
local l = minetest.get_node_light(bpos, 0.5)
if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l and l <= 12 and pr_nether:next(1,1000) <= 4 then
if bpos.y > mcl_mapgen.nether.lava_max + 6 and l and l <= 12 and pr_nether:next(1,1000) <= 4 then
-- TODO: Make mushrooms appear in groups, use Perlin noise
if pr_nether:next(1,2) == 1 then
minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"})
@ -1823,15 +1823,15 @@ end
-- Also perform some basic node replacements.
local bedrock_check
if mcl_vars.mg_bedrock_is_rough then
if mcl_mapgen.bedrock_is_rough then
function bedrock_check(pos, _, pr)
local y = pos.y
-- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer
-- This code assumes a bedrock height of 5 layers.
local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock
local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom
local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling
local diff = mcl_mapgen.overworld.bedrock_max - y -- Overworld bedrock
local ndiff1 = mcl_mapgen.nether.bedrock_bottom_max - y -- Nether bedrock, bottom
local ndiff2 = mcl_mapgen.nether.bedrock_top_max - y -- Nether bedrock, ceiling
local top
if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then
@ -1895,10 +1895,10 @@ local function set_layers(data, area, content_id, check, min, max, minp, maxp, l
end
-- Below the bedrock, generate air/void
local function basic(c)
local vm, data, emin, emax, area, minp, maxp, blockseed = c.vm, c.data, c.emin, c.emax, c.area, c.minp, c.maxp, c.blockseed
c.data2 = c.data2 or vm:get_data_param2(lvm_buffer_param2)
local data2 = c.data2
local function basic_safe(vm_context)
local vm, data, emin, emax, area, minp, maxp, chunkseed, blockseed = vm_context.vm, vm_context.data, vm_context.emin, vm_context.emax, vm_context.area, vm_context.minp, vm_context.maxp, vm_context.chunkseed, vm_context.blockseed
vm_context.data2 = vm_context.data2 or vm:get_param2_data(lvm_param2_buffer)
local data2 = vm_context.data2
local lvm_used = false
local pr = PseudoRandom(blockseed)
@ -1916,34 +1916,35 @@ local function basic(c)
-- [[ THE END: mcl_mapgen.end_.min mcl_mapgen.end_.max ]]
-- The Void above the End below the Realm barrier:
lvm_used = set_layers(data, area, c_void , nil, mcl_mapgen.end_.max +1, mcl_vars.mg_realm_barrier_overworld_end_min-1, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_void , nil, mcl_mapgen.end_.max +1, mcl_mapgen.realm_barrier_overworld_end_min-1, minp, maxp, lvm_used, pr)
-- Realm barrier between the Overworld void and the End
lvm_used = set_layers(data, area, c_realm_barrier, nil, mcl_vars.mg_realm_barrier_overworld_end_min , mcl_vars.mg_realm_barrier_overworld_end_max , minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_realm_barrier, nil, mcl_mapgen.realm_barrier_overworld_end_min , mcl_mapgen.realm_barrier_overworld_end_max , minp, maxp, lvm_used, pr)
-- The Void above Realm barrier below the Overworld:
lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_realm_barrier_overworld_end_max+1, mcl_mapgen.overworld.min -1, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_void , nil, mcl_mapgen.realm_barrier_overworld_end_max+1, mcl_mapgen.overworld.min -1, minp, maxp, lvm_used, pr)
if mg_name ~= "singlenode" then
-- Bedrock
lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_overworld_min, mcl_vars.mg_bedrock_overworld_max, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_bottom_max, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_top_min, mcl_vars.mg_bedrock_nether_top_max, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_mapgen.overworld.bedrock_min, mcl_mapgen.overworld.bedrock_max, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_mapgen.nether.bedrock_bottom_min, mcl_mapgen.nether.bedrock_bottom_max, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_mapgen.nether.bedrock_top_min, mcl_mapgen.nether.bedrock_top_max, minp, maxp, lvm_used, pr)
-- Flat Nether
if mg_name == "flat" then
lvm_used = set_layers(data, area, c_air, nil, mcl_vars.mg_flat_nether_floor, mcl_vars.mg_flat_nether_ceiling, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_air, nil, mcl_mapgen.nether.flat_floor, mcl_mapgen.nether.flat_ceiling, minp, maxp, lvm_used, pr)
end
-- Big lava seas by replacing air below a certain height
if mcl_vars.mg_lava then
if mcl_mapgen.lava then
lvm_used = set_layers(data, area, c_lava, c_air, mcl_mapgen.overworld.min, mcl_mapgen.overworld.lava_max, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_nether_lava, c_air, mcl_mapgen.nether.min, mcl_vars.mg_lava_nether_max, minp, maxp, lvm_used, pr)
lvm_used = set_layers(data, area, c_nether_lava, c_air, mcl_mapgen.nether.min, mcl_mapgen.nether.lava_max, minp, maxp, lvm_used, pr)
end
-- Clay, vines, cocoas
lvm_used = generate_clay(minp, maxp, blockseed, data, area, lvm_used)
-- lvm_used = generate_clay(minp, maxp, chunkseed, data, area, lvm_used)
c.biomemap = c.biomemap or minetest.get_mapgen_object("biomemap")
vm_context.biomemap = vm_context.biomemap or minetest.get_mapgen_object("biomemap")
local biomemap = vm_context.biomemap
lvm_used = generate_tree_decorations(minp, maxp, blockseed, data, data2, area, biomemap, lvm_used, pr)
@ -2061,18 +2062,18 @@ local function basic(c)
end
-- Obsidian spawn platform
if minp.y <= mcl_vars.mg_end_platform_pos.y and maxp.y >= mcl_vars.mg_end_platform_pos.y and
minp.x <= mcl_vars.mg_end_platform_pos.x and maxp.x >= mcl_vars.mg_end_platform_pos.z and
minp.z <= mcl_vars.mg_end_platform_pos.z and maxp.z >= mcl_vars.mg_end_platform_pos.z then
if minp.y <= mcl_mapgen.end_.platform_pos.y and maxp.y >= mcl_mapgen.end_.platform_pos.y and
minp.x <= mcl_mapgen.end_.platform_pos.x and maxp.x >= mcl_mapgen.end_.platform_pos.z and
minp.z <= mcl_mapgen.end_.platform_pos.z and maxp.z >= mcl_mapgen.end_.platform_pos.z then
--local pos1 = {x = math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), y = math.max(minp.y, mcl_vars.mg_end_platform_pos.y), z = math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2)}
--local pos2 = {x = math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2), y = math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2), z = math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2)}
--local pos1 = {x = math.max(minp.x, mcl_mapgen.end_.platform_pos.x-2), y = math.max(minp.y, mcl_mapgen.end_.platform_pos.y), z = math.max(minp.z, mcl_mapgen.end_.platform_pos.z-2)}
--local pos2 = {x = math.min(maxp.x, mcl_mapgen.end_.platform_pos.x+2), y = math.min(maxp.y, mcl_mapgen.end_.platform_pos.y+2), z = math.min(maxp.z, mcl_mapgen.end_.platform_pos.z+2)}
for x=math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2) do
for z=math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2), math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2) do
for y=math.max(minp.y, mcl_vars.mg_end_platform_pos.y), math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2) do
for x=math.max(minp.x, mcl_mapgen.end_.platform_pos.x-2), math.min(maxp.x, mcl_mapgen.end_.platform_pos.x+2) do
for z=math.max(minp.z, mcl_mapgen.end_.platform_pos.z-2), math.min(maxp.z, mcl_mapgen.end_.platform_pos.z+2) do
for y=math.max(minp.y, mcl_mapgen.end_.platform_pos.y), math.min(maxp.y, mcl_mapgen.end_.platform_pos.y+2) do
local p_pos = area:index(x, y, z)
if y == mcl_vars.mg_end_platform_pos.y then
if y == mcl_mapgen.end_.platform_pos.y then
data[p_pos] = c_obsidian
else
data[p_pos] = c_air
@ -2104,8 +2105,7 @@ local function basic(c)
generate_structures(minp, maxp, blockseed, biomemap)
end
return lvm_used, shadow
return vm_context --, lvm_used, shadow
end
mcl_mapgen.register_chunk_generator_lvm(basic, 1)
mcl_mapgen.register_mapgen_block_lvm(basic_safe, 1)

View File

@ -39,7 +39,7 @@ end
local y_wanted = mcl_mapgen.OFFSET_NODES -- supposed to be -32
local y_bottom = mcl_mapgen.overworld.min -- -62
mcl_mapgen.register_chunk_generator(function(minp, maxp, seed)
mcl_mapgen.register_mapgen(function(minp, maxp, seed)
local minp = minp
local y = minp.y
if y ~= y_wanted then return end
@ -94,4 +94,4 @@ mcl_mapgen.register_chunk_generator(function(minp, maxp, seed)
minetest_log("action", "[mcl_ocean_monument] Placed at " .. minetest_pos_to_string(minp) .. ", " .. rotation_str .. " deg.")
end, mcl_mapgen.priorities.OCEAN_MONUMENT)
end, mcl_mapgen.order.OCEAN_MONUMENT)

View File

@ -68,7 +68,7 @@ end
init_strongholds()
-- Stronghold generation for register_on_generated.
mcl_mapgen.register_chunk_generator(function(minp, maxp, blockseed)
mcl_mapgen.register_mapgen(function(minp, maxp, blockseed)
local pr = PseudoRandom(blockseed)
for s=1, #strongholds do
if not strongholds[s].generated then
@ -100,4 +100,4 @@ mcl_mapgen.register_chunk_generator(function(minp, maxp, blockseed)
end
end
end
end, mcl_mapgen.priorities.STRONGHOLDS)
end, mcl_mapgen.order.STRONGHOLDS)

View File

@ -75,7 +75,7 @@ end
-- Disable natural generation in singlenode.
local mg_name = minetest.get_mapgen_setting("mg_name")
if mg_name ~= "singlenode" then
mcl_mapgen.register_chunk_generator(function(minp, maxp, blockseed)
mcl_mapgen.register_mapgen(function(minp, maxp, blockseed)
-- local str1 = (maxp.y >= 0 and blockseed % 77 == 17) and "YES" or "no"
-- minetest.log("action","[mcl_villages] " .. str1 .. ": minp=" .. minetest.pos_to_string(minp) .. ", maxp=" .. minetest.pos_to_string(maxp) .. ", blockseed=" .. tostring(blockseed))
-- don't build settlement underground
@ -103,7 +103,7 @@ if mg_name ~= "singlenode" then
if height_difference > max_height_difference then return end
build_a_settlement(minp, maxp, blockseed)
end, mcl_mapgen.priorities.VILLAGES)
end, mcl_mapgen.order.VILLAGES)
end
-- manually place villages
if minetest.is_creative_enabled("") then

View File

@ -1092,7 +1092,7 @@ local function create_corridor_system(main_cave_coords)
end
-- The rail corridor algorithm starts here
mcl_mapgen.register_chunk_generator(function(minp, maxp, blockseed, _pr)
mcl_mapgen.register_mapgen(function(minp, maxp, blockseed)
-- We re-init the randomizer for every mapchunk as we start generating in the middle of each mapchunk.
-- We can't use the mapgen seed as this would make the algorithm depending on the order the mapchunk generate.
InitRandomizer(blockseed)