forked from MineClone5/MineClone5
[mcl_mapgen_core] Redesign, mostly to remove water from End and restore static lvm_buffer to speed it up
This commit is contained in:
parent
d07cf64d11
commit
cb2aae5a55
|
@ -175,3 +175,86 @@ minetest.craftitemdef_default.stack_max = 64
|
||||||
-- Set random seed for all other mods (Remember to make sure no other mod calls this function)
|
-- Set random seed for all other mods (Remember to make sure no other mod calls this function)
|
||||||
math.randomseed(os.time())
|
math.randomseed(os.time())
|
||||||
|
|
||||||
|
local chunks = {} -- intervals of chunks generated
|
||||||
|
function mcl_vars.add_chunk(pos)
|
||||||
|
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
||||||
|
local prev
|
||||||
|
for i, d in pairs(chunks) do
|
||||||
|
if n <= d[2] then -- we've found it
|
||||||
|
if (n == d[2]) or (n >= d[1]) then return end -- already here
|
||||||
|
if n == d[1]-1 then -- right before:
|
||||||
|
if prev and (prev[2] == n-1) then
|
||||||
|
prev[2] = d[2]
|
||||||
|
table.remove(chunks, i)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
d[1] = n
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if prev and (prev[2] == n-1) then --join to previous
|
||||||
|
prev[2] = n
|
||||||
|
return
|
||||||
|
end
|
||||||
|
table.insert(chunks, i, {n, n}) -- insert new interval before i
|
||||||
|
return
|
||||||
|
end
|
||||||
|
prev = d
|
||||||
|
end
|
||||||
|
chunks[#chunks+1] = {n, n}
|
||||||
|
end
|
||||||
|
function mcl_vars.is_generated(pos)
|
||||||
|
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
||||||
|
for i, d in pairs(chunks) do
|
||||||
|
if n <= d[2] then
|
||||||
|
return (n >= d[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does.
|
||||||
|
-- p: Position, if it's wrong, {name="error"} node will return.
|
||||||
|
-- force: optional (default: false) - Do the maximum to still read the node within us_timeout.
|
||||||
|
-- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job.
|
||||||
|
--
|
||||||
|
-- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}.
|
||||||
|
function mcl_vars.get_node(p, force, us_timeout)
|
||||||
|
-- check initial circumstances
|
||||||
|
if not p or not p.x or not p.y or not p.z then return {name="error"} end
|
||||||
|
|
||||||
|
-- try common way
|
||||||
|
local node = minetest.get_node(p)
|
||||||
|
if node.name ~= "ignore" then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
|
||||||
|
-- copy table to get sure it won't changed by other threads
|
||||||
|
local pos = {x=p.x,y=p.y,z=p.z}
|
||||||
|
|
||||||
|
-- try LVM
|
||||||
|
minetest.get_voxel_manip():read_from_map(pos, pos)
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
if node.name ~= "ignore" or not force then
|
||||||
|
return node
|
||||||
|
end
|
||||||
|
|
||||||
|
-- all ways failed - need to emerge (or forceload if generated)
|
||||||
|
local us_timeout = us_timeout or 244
|
||||||
|
if mcl_vars.is_generated(pos) then
|
||||||
|
minetest.chat_send_all("IMPOSSIBLE! Please report this to MCL2 issue tracker!")
|
||||||
|
minetest.forceload_block(pos)
|
||||||
|
else
|
||||||
|
minetest.emerge_area(pos, pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
local t = minetest.get_us_time()
|
||||||
|
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
|
||||||
|
while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do
|
||||||
|
node = minetest.get_node(pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
return node
|
||||||
|
-- it still can return "ignore", LOL, even if force = true, but only after time out
|
||||||
|
end
|
||||||
|
|
|
@ -66,12 +66,7 @@ minetest.register_on_shutdown(function()
|
||||||
storage:set_string("nether_exits_keys", minetest.serialize(keys))
|
storage:set_string("nether_exits_keys", minetest.serialize(keys))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
mcl_portals.get_node = function(pos)
|
local get_node = mcl_vars.get_node
|
||||||
if mcl_mapgen_core and mcl_mapgen_core.get_node then
|
|
||||||
mcl_portals.get_node = mcl_mapgen_core.get_node
|
|
||||||
end
|
|
||||||
return minetest.get_node(pos)
|
|
||||||
end
|
|
||||||
local set_node = minetest.set_node
|
local set_node = minetest.set_node
|
||||||
local registered_nodes = minetest.registered_nodes
|
local registered_nodes = minetest.registered_nodes
|
||||||
local is_protected = minetest.is_protected
|
local is_protected = minetest.is_protected
|
||||||
|
@ -97,7 +92,6 @@ local limits = {
|
||||||
-- Incoming verification performed: two nodes must be portal nodes, and an obsidian below them.
|
-- Incoming verification performed: two nodes must be portal nodes, and an obsidian below them.
|
||||||
-- If the verification passes - position adds to the table and saves to mod storage on exit.
|
-- If the verification passes - position adds to the table and saves to mod storage on exit.
|
||||||
local function add_exit(p)
|
local function add_exit(p)
|
||||||
local get_node = mcl_portals.get_node
|
|
||||||
if not p or not p.y or not p.z or not p.x then return end
|
if not p or not p.y or not p.z or not p.x then return end
|
||||||
local x, y, z = floor(p.x), floor(p.y), floor(p.z)
|
local x, y, z = floor(p.x), floor(p.y), floor(p.z)
|
||||||
local p = {x = x, y = y, z = z}
|
local p = {x = x, y = y, z = z}
|
||||||
|
@ -202,7 +196,6 @@ local function destroy_nether_portal(pos, node)
|
||||||
local nn, orientation = node.name, node.param2
|
local nn, orientation = node.name, node.param2
|
||||||
local obsidian = nn == OBSIDIAN
|
local obsidian = nn == OBSIDIAN
|
||||||
|
|
||||||
local get_node = mcl_portals.get_node
|
|
||||||
local check_remove = function(pos, orientation)
|
local check_remove = function(pos, orientation)
|
||||||
local node = get_node(pos)
|
local node = get_node(pos)
|
||||||
if node and (node.name == PORTAL and (orientation == nil or (node.param2 == orientation))) then
|
if node and (node.name == PORTAL and (orientation == nil or (node.param2 == orientation))) then
|
||||||
|
@ -315,8 +308,6 @@ function build_nether_portal(pos, width, height, orientation, name)
|
||||||
|
|
||||||
light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1))
|
light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1))
|
||||||
|
|
||||||
local get_node = mcl_portals.get_node
|
|
||||||
|
|
||||||
-- Build obsidian platform:
|
-- Build obsidian platform:
|
||||||
for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do
|
for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do
|
||||||
for z = pos.z - 1 + orientation, pos.z + 1 - orientation + (width - 1) * orientation, 2 - orientation do
|
for z = pos.z - 1 + orientation, pos.z + 1 - orientation + (width - 1) * orientation, 2 - orientation do
|
||||||
|
@ -379,7 +370,7 @@ local function finalize_teleport(obj, exit)
|
||||||
|
|
||||||
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
||||||
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
||||||
if mcl_portals.get_node(objpos).name ~= PORTAL then return end
|
if get_node(objpos).name ~= PORTAL then return end
|
||||||
|
|
||||||
-- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 1 of 2 -- TODO: Remove --
|
-- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 1 of 2 -- TODO: Remove --
|
||||||
-- Old worlds have no exits indexed - adding the exit to return here:
|
-- Old worlds have no exits indexed - adding the exit to return here:
|
||||||
|
@ -529,7 +520,7 @@ local function create_portal(pos, limit1, limit2, name, obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function available_for_nether_portal(p)
|
local function available_for_nether_portal(p)
|
||||||
local nn = mcl_portals.get_node(p).name
|
local nn = get_node(p).name
|
||||||
local obsidian = nn == OBSIDIAN
|
local obsidian = nn == OBSIDIAN
|
||||||
if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then
|
if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then
|
||||||
return false, obsidian
|
return false, obsidian
|
||||||
|
@ -636,7 +627,7 @@ local function teleport_no_delay(obj, pos)
|
||||||
|
|
||||||
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
-- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y
|
||||||
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}
|
||||||
if mcl_portals.get_node(objpos).name ~= PORTAL then return end
|
if get_node(objpos).name ~= PORTAL then return end
|
||||||
|
|
||||||
local target, dim = get_target(objpos)
|
local target, dim = get_target(objpos)
|
||||||
if not target then return end
|
if not target then return end
|
||||||
|
|
|
@ -12,6 +12,8 @@ end
|
||||||
local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
|
local min_y = math.max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1
|
||||||
local max_y = mcl_vars.mg_overworld_max - 1
|
local max_y = mcl_vars.mg_overworld_max - 1
|
||||||
|
|
||||||
|
local get_node = mcl_vars.get_node
|
||||||
|
|
||||||
-- Calculate the number of dungeon spawn attempts
|
-- Calculate the number of dungeon spawn attempts
|
||||||
-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks).
|
-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks).
|
||||||
-- Minetest chunks don't have this size, so scale the number accordingly.
|
-- Minetest chunks don't have this size, so scale the number accordingly.
|
||||||
|
@ -49,8 +51,8 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
local y_floor = y
|
local y_floor = y
|
||||||
local y_ceiling = y + dim.y + 1
|
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 for tx = x+1, x+dim.x do for tz = z+1, z+dim.z do
|
||||||
if not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_floor , z = tz}).name].walkable
|
if not minetest.registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name].walkable
|
||||||
or not minetest.registered_nodes[mcl_mapgen_core.get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
|
or not minetest.registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name].walkable then return false end
|
||||||
end end end
|
end end end
|
||||||
|
|
||||||
-- Check for air openings (2 stacked air at ground level) in wall positions
|
-- Check for air openings (2 stacked air at ground level) in wall positions
|
||||||
|
@ -63,25 +65,25 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
|
|
||||||
local x2,z2 = x+dim.x+1, z+dim.z+1
|
local x2,z2 = x+dim.x+1, z+dim.z+1
|
||||||
|
|
||||||
if mcl_mapgen_core.get_node({x=x, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=z}).name == "air" then
|
if get_node({x=x, y=y+1, z=z}).name == "air" and get_node({x=x, y=y+2, z=z}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x] then openings[x]={} end
|
if not openings[x] then openings[x]={} end
|
||||||
openings[x][z] = true
|
openings[x][z] = true
|
||||||
table.insert(corners, {x=x, z=z})
|
table.insert(corners, {x=x, z=z})
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x2, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=z}).name == "air" then
|
if get_node({x=x2, y=y+1, z=z}).name == "air" and get_node({x=x2, y=y+2, z=z}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x2] then openings[x2]={} end
|
if not openings[x2] then openings[x2]={} end
|
||||||
openings[x2][z] = true
|
openings[x2][z] = true
|
||||||
table.insert(corners, {x=x2, z=z})
|
table.insert(corners, {x=x2, z=z})
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=z2}).name == "air" then
|
if get_node({x=x, y=y+1, z=z2}).name == "air" and get_node({x=x, y=y+2, z=z2}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x] then openings[x]={} end
|
if not openings[x] then openings[x]={} end
|
||||||
openings[x][z2] = true
|
openings[x][z2] = true
|
||||||
table.insert(corners, {x=x, z=z2})
|
table.insert(corners, {x=x, z=z2})
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x2, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=z2}).name == "air" then
|
if get_node({x=x2, y=y+1, z=z2}).name == "air" and get_node({x=x2, y=y+2, z=z2}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if not openings[x2] then openings[x2]={} end
|
if not openings[x2] then openings[x2]={} end
|
||||||
openings[x2][z2] = true
|
openings[x2][z2] = true
|
||||||
|
@ -89,13 +91,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
end
|
end
|
||||||
|
|
||||||
for wx = x+1, x+dim.x do
|
for wx = x+1, x+dim.x do
|
||||||
if mcl_mapgen_core.get_node({x=wx, y=y+1, z=z}).name == "air" and mcl_mapgen_core.get_node({x=wx, y=y+2, z=z}).name == "air" then
|
if get_node({x=wx, y=y+1, z=z}).name == "air" and get_node({x=wx, y=y+2, z=z}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[wx] then openings[wx]={} end
|
if not openings[wx] then openings[wx]={} end
|
||||||
openings[wx][z] = true
|
openings[wx][z] = true
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=wx, y=y+1, z=z2}).name == "air" and mcl_mapgen_core.get_node({x=wx, y=y+2, z=z2}).name == "air" then
|
if get_node({x=wx, y=y+1, z=z2}).name == "air" and get_node({x=wx, y=y+2, z=z2}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[wx] then openings[wx]={} end
|
if not openings[wx] then openings[wx]={} end
|
||||||
|
@ -103,13 +105,13 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for wz = z+1, z+dim.z do
|
for wz = z+1, z+dim.z do
|
||||||
if mcl_mapgen_core.get_node({x=x, y=y+1, z=wz}).name == "air" and mcl_mapgen_core.get_node({x=x, y=y+2, z=wz}).name == "air" then
|
if get_node({x=x, y=y+1, z=wz}).name == "air" and get_node({x=x, y=y+2, z=wz}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[x] then openings[x]={} end
|
if not openings[x] then openings[x]={} end
|
||||||
openings[x][wz] = true
|
openings[x][wz] = true
|
||||||
end
|
end
|
||||||
if mcl_mapgen_core.get_node({x=x2, y=y+1, z=wz}).name == "air" and mcl_mapgen_core.get_node({x=x2, y=y+2, z=wz}).name == "air" then
|
if get_node({x=x2, y=y+1, z=wz}).name == "air" and get_node({x=x2, y=y+2, z=wz}).name == "air" then
|
||||||
openings_counter = openings_counter + 1
|
openings_counter = openings_counter + 1
|
||||||
if check and openings_counter > 5 then return end
|
if check and openings_counter > 5 then return end
|
||||||
if not openings[x2] then openings[x2]={} end
|
if not openings[x2] then openings[x2]={} end
|
||||||
|
@ -185,7 +187,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
|
|
||||||
-- Calculate the mob spawner position, to be re-used for later
|
-- Calculate the mob spawner position, to be re-used for later
|
||||||
local sp = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)}
|
local sp = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)}
|
||||||
local rn = minetest.registered_nodes[mcl_mapgen_core.get_node(sp).name]
|
local rn = minetest.registered_nodes[get_node(sp).name]
|
||||||
if rn and rn.is_ground_content then
|
if rn and rn.is_ground_content then
|
||||||
table.insert(spawner_posses, sp)
|
table.insert(spawner_posses, sp)
|
||||||
end
|
end
|
||||||
|
@ -200,7 +202,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||||
|
|
||||||
-- Do not overwrite nodes with is_ground_content == false (e.g. bedrock)
|
-- Do not overwrite nodes with is_ground_content == false (e.g. bedrock)
|
||||||
-- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other
|
-- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other
|
||||||
local name = mcl_mapgen_core.get_node(p).name
|
local name = get_node(p).name
|
||||||
if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then
|
if minetest.registered_nodes[name].is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then
|
||||||
-- Floor
|
-- Floor
|
||||||
if ty == y then
|
if ty == y then
|
||||||
|
|
|
@ -1,45 +1,8 @@
|
||||||
mcl_mapgen_core = {}
|
mcl_mapgen_core = {}
|
||||||
mcl_mapgen_core.registered_generators = {}
|
local registered_generators = {}
|
||||||
|
|
||||||
local lvm, nodes, param2 = 0, 0, 0
|
local lvm, nodes, param2 = 0, 0, 0
|
||||||
|
local lvm_buffer = {}
|
||||||
local generating = {} -- generating chunks
|
|
||||||
local chunks = {} -- intervals of chunks generated
|
|
||||||
local function add_chunk(pos)
|
|
||||||
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
|
||||||
local prev
|
|
||||||
for i, d in pairs(chunks) do
|
|
||||||
if n <= d[2] then -- we've found it
|
|
||||||
if (n == d[2]) or (n >= d[1]) then return end -- already here
|
|
||||||
if n == d[1]-1 then -- right before:
|
|
||||||
if prev and (prev[2] == n-1) then
|
|
||||||
prev[2] = d[2]
|
|
||||||
table.remove(chunks, i)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
d[1] = n
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if prev and (prev[2] == n-1) then --join to previous
|
|
||||||
prev[2] = n
|
|
||||||
return
|
|
||||||
end
|
|
||||||
table.insert(chunks, i, {n, n}) -- insert new interval before i
|
|
||||||
return
|
|
||||||
end
|
|
||||||
prev = d
|
|
||||||
end
|
|
||||||
chunks[#chunks+1] = {n, n}
|
|
||||||
end
|
|
||||||
function mcl_mapgen_core.is_generated(pos)
|
|
||||||
local n = mcl_vars.get_chunk_number(pos) -- unsigned int
|
|
||||||
for i, d in pairs(chunks) do
|
|
||||||
if n <= d[2] then
|
|
||||||
return (n >= d[1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Aliases for map generator outputs
|
-- Aliases for map generator outputs
|
||||||
|
@ -1850,24 +1813,22 @@ end
|
||||||
|
|
||||||
minetest.register_on_generated(function(minp, maxp, blockseed)
|
minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||||
minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
|
minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp))
|
||||||
add_chunk(minp)
|
|
||||||
local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z}
|
local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z}
|
||||||
if lvm > 0 then
|
if lvm > 0 then
|
||||||
local lvm_used, shadow = false, false
|
local lvm_used, shadow = false, false
|
||||||
local lb = {} -- buffer
|
|
||||||
local lb2 = {} -- param2
|
local lb2 = {} -- param2
|
||||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||||
local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z}
|
local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z}
|
||||||
local data2
|
local data2
|
||||||
local data = vm:get_data(lb)
|
local data = vm:get_data(lvm_buffer)
|
||||||
if param2 > 0 then
|
if param2 > 0 then
|
||||||
data2 = vm:get_param2_data(lb2)
|
data2 = vm:get_param2_data(lb2)
|
||||||
end
|
end
|
||||||
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
|
||||||
|
|
||||||
for _, rec in pairs(mcl_mapgen_core.registered_generators) do
|
for _, rec in pairs(registered_generators) do
|
||||||
if rec.vf then
|
if rec.vf then
|
||||||
local lvm_used0, shadow0 = rec.vf(vm, data, data2, p1, p2, area, p1, p2, blockseed)
|
local lvm_used0, shadow0 = rec.vf(vm, data, data2, e1, e2, area, p1, p2, blockseed)
|
||||||
if lvm_used0 then
|
if lvm_used0 then
|
||||||
lvm_used = true
|
lvm_used = true
|
||||||
end
|
end
|
||||||
|
@ -1890,18 +1851,18 @@ minetest.register_on_generated(function(minp, maxp, blockseed)
|
||||||
end
|
end
|
||||||
|
|
||||||
if nodes > 0 then
|
if nodes > 0 then
|
||||||
for _, rec in pairs(mcl_mapgen_core.registered_generators) do
|
for _, rec in pairs(registered_generators) do
|
||||||
if rec.nf then
|
if rec.nf then
|
||||||
rec.nf(p1, p2, blockseed)
|
rec.nf(p1, p2, blockseed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add_chunk(minp)
|
mcl_vars.add_chunk(minp)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_generated=function(node_function)
|
minetest.register_on_generated=function(node_function)
|
||||||
mcl_mapgen_core.register_generator("mod_"..tostring(#mcl_mapgen_core.registered_generators+1), nil, node_function)
|
mcl_mapgen_core.register_generator("mod_"..tostring(#registered_generators+1), nil, node_function)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2)
|
function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2)
|
||||||
|
@ -1920,18 +1881,18 @@ function mcl_mapgen_core.register_generator(id, lvm_function, node_function, pri
|
||||||
needs_param2 = needs_param2,
|
needs_param2 = needs_param2,
|
||||||
}
|
}
|
||||||
|
|
||||||
mcl_mapgen_core.registered_generators[id] = new_record
|
registered_generators[id] = new_record
|
||||||
table.sort(
|
table.sort(
|
||||||
mcl_mapgen_core.registered_generators,
|
registered_generators,
|
||||||
function(a, b)
|
function(a, b)
|
||||||
return (a.i < b.i) or ((a.i == b.i) and (a.vf ~= nil) and (b.vf == nil))
|
return (a.i < b.i) or ((a.i == b.i) and (a.vf ~= nil) and (b.vf == nil))
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_mapgen_core.unregister_generator(id)
|
function mcl_mapgen_core.unregister_generator(id)
|
||||||
if not mcl_mapgen_core.registered_generators[id] then return end
|
if not registered_generators[id] then return end
|
||||||
local rec = mcl_mapgen_core.registered_generators[id]
|
local rec = registered_generators[id]
|
||||||
mcl_mapgen_core.registered_generators[id] = nil
|
registered_generators[id] = nil
|
||||||
if rec.vf then lvm = lvm - 1 end
|
if rec.vf then lvm = lvm - 1 end
|
||||||
if rev.nf then nodes = nodes - 1 end
|
if rev.nf then nodes = nodes - 1 end
|
||||||
if rec.needs_param2 then param2 = param2 - 1 end
|
if rec.needs_param2 then param2 = param2 - 1 end
|
||||||
|
@ -2134,9 +2095,9 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
||||||
-- Nether block fixes:
|
-- Nether block fixes:
|
||||||
-- * Replace water with Nether lava.
|
-- * Replace water with Nether lava.
|
||||||
-- * Replace stone, sand dirt in v6 so the Nether works in v6.
|
-- * Replace stone, sand dirt in v6 so the Nether works in v6.
|
||||||
elseif minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min then
|
elseif emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then
|
||||||
if mg_name == "v6" then
|
if mg_name == "v6" then
|
||||||
local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
local nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
|
||||||
for n=1, #nodes do
|
for n=1, #nodes do
|
||||||
local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
|
local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z)
|
||||||
if data[p_pos] == c_water then
|
if data[p_pos] == c_water then
|
||||||
|
@ -2151,7 +2112,7 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining, param)
|
minetest.emerge_area(emin, emax, function(blockpos, action, calls_remaining, param)
|
||||||
if calls_remaining > 0 then return end
|
if calls_remaining > 0 then return end
|
||||||
-- local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"mcl_core:water_source"})
|
-- local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"mcl_core:water_source"})
|
||||||
local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"group:water"})
|
local nodes = minetest.find_nodes_in_area(param.minp, param.maxp, {"group:water"})
|
||||||
|
@ -2160,7 +2121,7 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
||||||
for _, n in pairs(nodes) do
|
for _, n in pairs(nodes) do
|
||||||
sn(n, l)
|
sn(n, l)
|
||||||
end
|
end
|
||||||
end, {minp=vector.new(minp), maxp=vector.new(maxp)})
|
end, {minp=vector.new(emin), maxp=vector.new(emax)})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- End block fixes:
|
-- End block fixes:
|
||||||
|
@ -2231,48 +2192,3 @@ end
|
||||||
|
|
||||||
mcl_mapgen_core.register_generator("main", basic, nil, 1, true)
|
mcl_mapgen_core.register_generator("main", basic, nil, 1, true)
|
||||||
|
|
||||||
-- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like 5.3.0 does.
|
|
||||||
-- p: Position, if it's wrong, {name="error"} node will return.
|
|
||||||
-- force: optional (default: false) - Do the maximum to still read the node within us_timeout.
|
|
||||||
-- us_timeout: optional (default: 244 = 0.000244 s = 1/80/80/80), set it at least to 3000000 to let mapgen to finish its job.
|
|
||||||
--
|
|
||||||
-- returns node definition, eg. {name="air"}. Unfortunately still can return {name="ignore"}.
|
|
||||||
function mcl_mapgen_core.get_node(p, force, us_timeout)
|
|
||||||
-- check initial circumstances
|
|
||||||
if not p or not p.x or not p.y or not p.z then return {name="error"} end
|
|
||||||
|
|
||||||
-- try common way
|
|
||||||
local node = minetest.get_node(p)
|
|
||||||
if node.name ~= "ignore" then
|
|
||||||
return node
|
|
||||||
end
|
|
||||||
|
|
||||||
-- copy table to get sure it won't changed by other threads
|
|
||||||
local pos = {x=p.x,y=p.y,z=p.z}
|
|
||||||
|
|
||||||
-- try LVM
|
|
||||||
minetest.get_voxel_manip():read_from_map(pos, pos)
|
|
||||||
node = minetest.get_node(pos)
|
|
||||||
if node.name ~= "ignore" or not force then
|
|
||||||
return node
|
|
||||||
end
|
|
||||||
|
|
||||||
-- all ways failed - need to emerge (or forceload if generated)
|
|
||||||
local us_timeout = us_timeout or 244
|
|
||||||
if mcl_mapgen_core.is_generated(pos) then
|
|
||||||
minetest.forceload_block(pos)
|
|
||||||
else
|
|
||||||
minetest.emerge_area(pos, pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
local t = minetest.get_us_time()
|
|
||||||
|
|
||||||
node = minetest.get_node(pos)
|
|
||||||
|
|
||||||
while (not node or node.name == "ignore") and (minetest.get_us_time() - t < us_timeout) do
|
|
||||||
node = minetest.get_node(pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
return node
|
|
||||||
-- it still can return "ignore", LOL, even if force = true, but only after time out
|
|
||||||
end
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ local function hut_placement_callback(p1, p2, size, orientation, pr)
|
||||||
if not p1 or not p2 then return end
|
if not p1 or not p2 then return end
|
||||||
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
|
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
|
||||||
for i = 1, #legs do
|
for i = 1, #legs do
|
||||||
while minetest.get_item_group(mcl_mapgen_core.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do
|
while minetest.get_item_group(mcl_vars.get_node({x=legs[i].x, y=legs[i].y-1, z=legs[i].z}, true, 333333).name, "water") ~= 0 do
|
||||||
legs[i].y = legs[i].y - 1
|
legs[i].y = legs[i].y - 1
|
||||||
minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2})
|
minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2})
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name)
|
function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name)
|
||||||
-- get building node material for better integration to surrounding
|
-- get building node material for better integration to surrounding
|
||||||
local platform_material = mcl_mapgen_core.get_node(pos)
|
local platform_material = mcl_vars.get_node(pos)
|
||||||
if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then
|
if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -52,7 +52,7 @@ function settlements.terraform(settlement_info, pr)
|
||||||
else
|
else
|
||||||
-- write ground
|
-- write ground
|
||||||
-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi}
|
-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi}
|
||||||
-- local node = mcl_mapgen_core.get_node(p)
|
-- local node = mcl_vars.get_node(p)
|
||||||
-- if node and node.name ~= "air" then
|
-- if node and node.name ~= "air" then
|
||||||
-- minetest.swap_node(p,{name="air"})
|
-- minetest.swap_node(p,{name="air"})
|
||||||
-- end
|
-- end
|
||||||
|
|
|
@ -1,28 +1,5 @@
|
||||||
local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass")
|
local get_node = mcl_vars.get_node
|
||||||
local c_dirt_with_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow")
|
|
||||||
--local c_dirt_with_dry_grass = minetest.get_content_id("mcl_core:dirt_with_dry_grass")
|
|
||||||
local c_podzol = minetest.get_content_id("mcl_core:podzol")
|
|
||||||
local c_sand = minetest.get_content_id("mcl_core:sand")
|
|
||||||
local c_desert_sand = minetest.get_content_id("mcl_core:redsand")
|
|
||||||
--local c_silver_sand = minetest.get_content_id("mcl_core:silver_sand")
|
|
||||||
--
|
|
||||||
local c_air = minetest.get_content_id("air")
|
|
||||||
local c_snow = minetest.get_content_id("mcl_core:snow")
|
|
||||||
local c_fern_1 = minetest.get_content_id("mcl_flowers:fern")
|
|
||||||
local c_fern_2 = minetest.get_content_id("mcl_flowers:fern")
|
|
||||||
local c_fern_3 = minetest.get_content_id("mcl_flowers:fern")
|
|
||||||
local c_rose = minetest.get_content_id("mcl_flowers:poppy")
|
|
||||||
local c_viola = minetest.get_content_id("mcl_flowers:blue_orchid")
|
|
||||||
local c_geranium = minetest.get_content_id("mcl_flowers:allium")
|
|
||||||
local c_tulip = minetest.get_content_id("mcl_flowers:tulip_orange")
|
|
||||||
local c_dandelion_y = minetest.get_content_id("mcl_flowers:dandelion")
|
|
||||||
local c_dandelion_w = minetest.get_content_id("mcl_flowers:oxeye_daisy")
|
|
||||||
local c_bush_leaves = minetest.get_content_id("mcl_core:leaves")
|
|
||||||
local c_bush_stem = minetest.get_content_id("mcl_core:tree")
|
|
||||||
local c_a_bush_leaves = minetest.get_content_id("mcl_core:acacialeaves")
|
|
||||||
local c_a_bush_stem = minetest.get_content_id("mcl_core:acaciatree")
|
|
||||||
local c_water_source = minetest.get_content_id("mcl_core:water_source")
|
|
||||||
local c_water_flowing = minetest.get_content_id("mcl_core:water_flowing")
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
-- function to copy tables
|
-- function to copy tables
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
@ -53,9 +30,9 @@ function settlements.find_surface(pos, wait)
|
||||||
-- check, in which direction to look for surface
|
-- check, in which direction to look for surface
|
||||||
local surface_node
|
local surface_node
|
||||||
if wait then
|
if wait then
|
||||||
surface_node = mcl_mapgen_core.get_node(p6, true, 10000000)
|
surface_node = get_node(p6, true, 10000000)
|
||||||
else
|
else
|
||||||
surface_node = mcl_mapgen_core.get_node(p6)
|
surface_node = get_node(p6)
|
||||||
end
|
end
|
||||||
if surface_node.name=="air" or surface_node.name=="ignore" then
|
if surface_node.name=="air" or surface_node.name=="ignore" then
|
||||||
itter = -1
|
itter = -1
|
||||||
|
@ -65,7 +42,7 @@ function settlements.find_surface(pos, wait)
|
||||||
-- Check Surface_node and Node above
|
-- Check Surface_node and Node above
|
||||||
--
|
--
|
||||||
if settlements.surface_mat[surface_node.name] then
|
if settlements.surface_mat[surface_node.name] then
|
||||||
local surface_node_plus_1 = mcl_mapgen_core.get_node({ x=p6.x, y=p6.y+1, z=p6.z})
|
local surface_node_plus_1 = get_node({ x=p6.x, y=p6.y+1, z=p6.z})
|
||||||
if surface_node_plus_1 and surface_node and
|
if surface_node_plus_1 and surface_node and
|
||||||
(string.find(surface_node_plus_1.name,"air") or
|
(string.find(surface_node_plus_1.name,"air") or
|
||||||
string.find(surface_node_plus_1.name,"snow") or
|
string.find(surface_node_plus_1.name,"snow") or
|
||||||
|
@ -90,7 +67,7 @@ function settlements.find_surface(pos, wait)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
cnt = cnt+1
|
cnt = cnt+1
|
||||||
surface_node = mcl_mapgen_core.get_node(p6)
|
surface_node = get_node(p6)
|
||||||
end
|
end
|
||||||
settlements.debug("find_surface5: cnt_max overflow")
|
settlements.debug("find_surface5: cnt_max overflow")
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue