Merge MineClone2/mapgen

This commit is contained in:
kay27 2021-07-25 04:13:11 +04:00
commit 2f8e30b1bb
30 changed files with 959 additions and 750 deletions

View File

@ -27,6 +27,8 @@ movement_gravity = 10.4
# Mapgen stuff # Mapgen stuff
max_block_generate_distance = 13
# altitude_chill and altitude_dry doesn't go well together with MCL2 biomes # altitude_chill and altitude_dry doesn't go well together with MCL2 biomes
# which already include "snowed" variants as you go higher. # which already include "snowed" variants as you go higher.
# humid_rivers would cause the MushroomIsland biome to appear frequently around rivers. # humid_rivers would cause the MushroomIsland biome to appear frequently around rivers.

View File

@ -24,240 +24,9 @@ mcl_vars.inventory_header = ""
-- Tool wield size -- Tool wield size
mcl_vars.tool_wield_scale = { x = 1.8, y = 1.8, z = 1 } mcl_vars.tool_wield_scale = { x = 1.8, y = 1.8, z = 1 }
-- Mapgen variables
local mg_name = minetest.get_mapgen_setting("mg_name")
local minecraft_height_limit = 256
local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true"
local singlenode = mg_name == "singlenode"
-- Calculate mapgen_edge_min/mapgen_edge_max
mcl_vars.chunksize = math.max(1, tonumber(minetest.get_mapgen_setting("chunksize")) or 5)
mcl_vars.MAP_BLOCKSIZE = math.max(1, minetest.MAP_BLOCKSIZE or 16)
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, minetest.MAX_MAP_GENERATION_LIMIT or 31000)
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1
local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes
local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE
local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE)
local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.chunk_size_in_nodes
local function coordinate_to_block(x)
return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
end
local function coordinate_to_chunk(x)
return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize)
end
function mcl_vars.pos_to_block(pos)
return {
x = coordinate_to_block(pos.x),
y = coordinate_to_block(pos.y),
z = coordinate_to_block(pos.z)
}
end
function mcl_vars.pos_to_chunk(pos)
return {
x = coordinate_to_chunk(pos.x),
y = coordinate_to_chunk(pos.y),
z = coordinate_to_chunk(pos.z)
}
end
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes)
local k_positive_z = k_positive * 2
local k_positive_y = k_positive_z * k_positive_z
function mcl_vars.get_chunk_number(pos) -- unsigned int
local c = mcl_vars.pos_to_chunk(pos)
return
(c.y + k_positive) * k_positive_y +
(c.z + k_positive) * k_positive_z +
c.x + k_positive
end
if not superflat and not singlenode then
-- Normal mode
--[[ Realm stacking (h is for height)
- Overworld (h>=256)
- Void (h>=1000)
- Realm Barrier (h=11), to allow escaping the End
- End (h>=256)
- Void (h>=1000)
- Nether (h=128)
- Void (h>=1000)
]]
-- Overworld
mcl_vars.mg_overworld_min = -62
mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit
mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min
mcl_vars.mg_bedrock_overworld_max = mcl_vars.mg_bedrock_overworld_min + 4
mcl_vars.mg_lava_overworld_max = mcl_vars.mg_overworld_min + 10
mcl_vars.mg_lava = true
mcl_vars.mg_bedrock_is_rough = true
elseif singlenode then
mcl_vars.mg_overworld_min = -66
mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit
mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min
mcl_vars.mg_bedrock_overworld_max = mcl_vars.mg_bedrock_overworld_min
mcl_vars.mg_lava = false
mcl_vars.mg_lava_overworld_max = mcl_vars.mg_overworld_min
mcl_vars.mg_bedrock_is_rough = false
else
-- Classic superflat
local ground = minetest.get_mapgen_setting("mgflat_ground_level")
ground = tonumber(ground)
if not ground then
ground = 8
end
mcl_vars.mg_overworld_min = ground - 3
mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit
mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min
mcl_vars.mg_bedrock_overworld_max = mcl_vars.mg_bedrock_overworld_min
mcl_vars.mg_lava = false
mcl_vars.mg_lava_overworld_max = mcl_vars.mg_overworld_min
mcl_vars.mg_bedrock_is_rough = false
end
mcl_vars.mg_overworld_max = mcl_vars.mapgen_edge_max
-- The Nether (around Y = -29000)
mcl_vars.mg_nether_min = -29067 -- Carefully chosen to be at a mapchunk border
mcl_vars.mg_nether_max = mcl_vars.mg_nether_min + 128
mcl_vars.mg_bedrock_nether_bottom_min = mcl_vars.mg_nether_min
mcl_vars.mg_bedrock_nether_top_max = mcl_vars.mg_nether_max
if not superflat then
mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min + 4
mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max - 4
mcl_vars.mg_lava_nether_max = mcl_vars.mg_nether_min + 31
else
-- Thin bedrock in classic superflat mapgen
mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min
mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max
mcl_vars.mg_lava_nether_max = mcl_vars.mg_nether_min + 2
end
if mg_name == "flat" then
if superflat then
mcl_vars.mg_flat_nether_floor = mcl_vars.mg_bedrock_nether_bottom_max + 4
mcl_vars.mg_flat_nether_ceiling = mcl_vars.mg_bedrock_nether_bottom_max + 52
else
mcl_vars.mg_flat_nether_floor = mcl_vars.mg_lava_nether_max + 4
mcl_vars.mg_flat_nether_ceiling = mcl_vars.mg_lava_nether_max + 52
end
end
-- The End (surface at ca. Y = -27000)
mcl_vars.mg_end_min = -27073 -- Carefully chosen to be at a mapchunk border
mcl_vars.mg_end_max_official = mcl_vars.mg_end_min + minecraft_height_limit
mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000
mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 74, z = 0 }
-- Realm barrier used to safely separate the End from the void below the Overworld
mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max
mcl_vars.mg_realm_barrier_overworld_end_min = mcl_vars.mg_end_max - 11
-- Use MineClone 5-style dungeons
mcl_vars.mg_dungeons = true
-- Set default stack sizes -- Set default stack sizes
minetest.nodedef_default.stack_max = 64 minetest.nodedef_default.stack_max = 64
minetest.craftitemdef_default.stack_max = 64 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

View File

@ -0,0 +1,74 @@
# mcl_mapgen
============
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;
`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`: curent voxel manipulator object itself;
`blockseed`: seed of this mapchunk;
`minp` & `maxp`: minimum and maximum chunk position;
`emin` & `emax`: minimum and maximum chunk position WITH SHELL AROUND IT;
`area`: voxel area, can be helpful to access data;
`data`: LVM buffer data array, data loads into it before the callbacks;
`write`: set it to true in yout callback functionm, if you changed `data` and want to write it;
`data2`: LVM buffer data array of `param2`, !NO ANY DATA LOADS INTO IT BEFORE THE CALLBACKS! - you load it yourfels:
`vm_context.data2 = vm_context.data2 or vm_context.vm.get_param2_data(vm_context.lvm_param2_buffer)`
`write_param2`: set it to true in yout callback functionm, if you used `data2` and want to write it;
`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:
`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:
`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:
`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:
`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:
`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`
## mcl_mapgen.get_far_node(pos)
===============================
Returns node if it is generated. Otherwise returns `{name = "ignore"}`.

View File

@ -0,0 +1,413 @@
mcl_mapgen = {}
local priorities = { -- mcl_mapgen.priorities...
DEFAULT = 5000,
CHORUS = 100000,
BUILDINGS = 200000,
VILLAGES = 900000,
DUNGEONS = 950000,
STRONGHOLDS = 999999,
OCEAN_MONUMENT = 1000000,
LARGE_BUILDINGS = 2000000,
}
local math_floor = math.floor
local math_max = math.max
local minetest_get_node = minetest.get_node
local minetest_get_voxel_manip = minetest.get_voxel_manip
local minetest_log = minetest.log
local minetest_pos_to_string = minetest.pos_to_string
-- Calculate mapgen_edge_min/mapgen_edge_max
mcl_mapgen.CS = math_max(1, tonumber(minetest.get_mapgen_setting("chunksize")) or 5)
mcl_mapgen.BS = math_max(1, core.MAP_BLOCKSIZE or 16)
mcl_mapgen.LIMIT = math_max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
mcl_mapgen.MAX_LIMIT = math_max(1, core.MAX_MAP_GENERATION_LIMIT or 31000) -- might be set to 31000 or removed, see https://github.com/minetest/minetest/issues/10428
mcl_mapgen.OFFSET = - math_floor(mcl_mapgen.CS / 2)
mcl_mapgen.OFFSET_NODES = mcl_mapgen.OFFSET * mcl_mapgen.BS
mcl_mapgen.CS_NODES = mcl_mapgen.CS * mcl_mapgen.BS
local central_chunk_min_pos = mcl_mapgen.OFFSET * mcl_mapgen.BS
local central_chunk_max_pos = central_chunk_min_pos + mcl_mapgen.CS_NODES - 1
local ccfmin = central_chunk_min_pos - mcl_mapgen.BS -- Fullminp/fullmaxp of central chunk, in nodes
local ccfmax = central_chunk_max_pos + mcl_mapgen.BS
local mapgen_limit_b = math_floor(math.min(mcl_mapgen.LIMIT, mcl_mapgen.MAX_LIMIT) / mcl_mapgen.BS)
local mapgen_limit_min = - mapgen_limit_b * mcl_mapgen.BS
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_mapgen.BS - 1
local numcmin = math_max(math_floor((ccfmin - mapgen_limit_min) / mcl_mapgen.CS_NODES), 0) -- Number of complete chunks from central chunk
local numcmax = math_max(math_floor((mapgen_limit_max - ccfmax) / mcl_mapgen.CS_NODES), 0) -- fullminp/fullmaxp to effective mapgen limits.
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))
------------------------------------------
-- Mapgen variables
local overworld, end_, nether = {}, {}, {}
mcl_mapgen.seed = minetest.get_mapgen_setting("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"
mcl_mapgen.singlenode = mcl_mapgen.name == "singlenode"
mcl_mapgen.normal = not mcl_mapgen.superflat and not mcl_mapgen.singlenode
local superflat, singlenode, normal = mcl_mapgen.superflat, mcl_mapgen.singlenode, mcl_mapgen.normal
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 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)
local CS_NODES = mcl_mapgen.CS_NODES -- 80
local CS_3D = CS * CS * CS
local DEFAULT_PRIORITY = priorities.DEFAULT
function mcl_mapgen.register_chunk_generator(callback_function, priority)
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)
end
function mcl_mapgen.register_chunk_generator_lvm(callback_function, priority)
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)
end
function mcl_mapgen.register_block_generator(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)
end
function mcl_mapgen.register_block_generator_lvm(callback_function, priority)
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
end
local storage = minetest.get_mod_storage()
local blocks = minetest.deserialize(storage:get_string("mapgen_blocks") or "return {}") or {}
local chunks = minetest.deserialize(storage:get_string("mapgen_chunks") or "return {}") or {}
minetest.register_on_shutdown(function()
storage:set_string("mapgen_chunks", minetest.serialize(chunks))
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 data, data2, area
local current_blocks = {}
local current_chunks = {}
minetest.register_on_generated(function(minp, maxp, blockseed)
local minp, maxp, blockseed = minp, maxp, blockseed
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))
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
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:
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}
else
chunks[cx0][cy0][cz0].seed = blockseed
end
local x1, y1, z1, x2, y2, z2 = emin.x, emin.y, emin.z, emax.x, emax.y, emax.z
local x, y, z = x1, y1, z1 -- iterate 7x7x7 mapchunk, {x,y,z} - first node pos. of mapblock
local bx, by, bz -- block coords (in blocs)
local box, boy, boz -- block offsets in chunks (in blocks)
while x < x2 do
bx = math_floor(x/BS)
local block_pos_offset_removed = bx - offset
local cx = math_floor(block_pos_offset_removed / CS)
box = block_pos_offset_removed % CS
if not blocks[bx] then blocks[bx]={} end
-- We don't know how many calls, including this one, will overwrite this block's content!
-- Start calculating it with `total_mapgen_block_writes_through_x` variable.
-- It can be `8 or less`, if we (speaking of `x` axis) are on chunk edge now,
-- or it can be `4 or less` - if we are in the middle of the chunk by `x` axis:
local total_mapgen_block_writes_through_x = (box > 0 and box < LAST_BLOCK) and 4 or 8
while y < y2 do
by = math_floor(y/BS)
block_pos_offset_removed = by - offset
local cy = math_floor(block_pos_offset_removed / CS)
boy = block_pos_offset_removed % CS
if not blocks[bx][by] then blocks[bx][by]={} end
-- Here we just divide `total_mapgen_block_writes_through_x` by 2,
-- if we are (speaking of `y` axis now) in the middle of the chunk now.
-- Or we don't divide it, if not.
-- So, basing on `total_mapgen_block_writes_through_x`,
--- we calculate `total_mapgen_block_writes_through_y` this way:
local total_mapgen_block_writes_through_y = (boy > 0 and boy < LAST_BLOCK) and math_floor(total_mapgen_block_writes_through_x / 2) or total_mapgen_block_writes_through_x
while z < z2 do
bz = math_floor(z/BS)
block_pos_offset_removed = bz - offset
local cz = math_floor(block_pos_offset_removed / CS)
boz = block_pos_offset_removed % CS
-- Now we do absolutely the same for `z` axis, basing on our previous result
-- from `total_mapgen_block_writes_through_y` variable.
-- And our final result is in `total_mapgen_block_writes`.
-- It can be still 8, derived from `x` calculation, but it can be less!
-- It can be even 1, if we are in safe 3x3x3 area of mapchunk:
local total_mapgen_block_writes = (boz > 0 and boz < LAST_BLOCK) and math_floor(total_mapgen_block_writes_through_y / 2) or total_mapgen_block_writes_through_y
-- Get current number of writes from the table, or just set it to 1, if accessed first time:
local current_mapgen_block_writes = blocks[bx][by][bz] and (blocks[bx][by][bz] + 1) or 1
-- And compare:
if current_mapgen_block_writes == total_mapgen_block_writes then
-- this block shouldn't be overwritten anymore, no need to keep it in memory
blocks[bx][by][bz] = nil
if not chunks[cx] then chunks[cx] = {} end
if not chunks[cx][cy] then chunks[cx][cy] = {} end
if not chunks[cx][cy][cz] then
if not chunks[cx][cy][cz] then chunks[cx][cy][cz] = {counter = 1} end
else
chunks[cx][cy][cz].counter = chunks[cx][cy][cz].counter + 1
if chunks[cx][cy][cz].counter >= CS_3D then
current_chunks[#current_chunks+1] = { x = cx, y = cy, z = cz, s = chunks[cx][cy][cz].seed }
-- this chunk shouldn't be overwritten anymore, no need to keep it in memory
chunks[cx][cy][cz] = nil
if next(chunks[cx][cy]) == nil then chunks[cx][cy] = nil end
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)
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 }
end
else
blocks[bx][by][bz] = current_mapgen_block_writes
end
z = z + BS
end
if next(blocks[bx][by]) == nil then blocks[bx][by] = nil end
z = z1
y = y + BS
end
if next(blocks[bx]) == nil then blocks[bx] = nil end
y = y1
x = x + BS
end
end
if lvm > 0 then
for _, v in pairs(lvm_chunk_queue) do
vm_context = v.f(vm_context)
end
if vm_context.write then
vm:set_data(data)
end
if vm_context.write_param2 then
vm:set_param2_data(data2)
end
vm:calc_lighting(minp, maxp, vm_context.shadow or true) -- TODO: check boundaries
vm:write_to_map()
vm:update_liquids()
end
for i, b in pairs(current_chunks) do
local cx, cy, cz, seed = b.x, b.y, b.z, b.s
local bx, by, bz = cx * CS + offset, cy * CS + offset, cz * CS + offset
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
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
v.f(b.minp, b.maxp, b.seed)
end
current_blocks[i] = nil
end
end)
minetest.register_on_generated = mcl_mapgen.register_chunk_generator
function mcl_mapgen.get_far_node(p)
local p = p
local node = minetest_get_node(p)
if node.name ~= "ignore" then return node end
minetest_get_voxel_manip():read_from_map(p, p)
return minetest_get_node(p)
end
local function coordinate_to_block(x)
return math_floor(x / BS)
end
local function coordinate_to_chunk(x)
return math_floor((coordinate_to_block(x) - offset) / CS)
end
function mcl_mapgen.pos_to_block(pos)
return {
x = coordinate_to_block(pos.x),
y = coordinate_to_block(pos.y),
z = coordinate_to_block(pos.z)
}
end
function mcl_mapgen.pos_to_chunk(pos)
return {
x = coordinate_to_chunk(pos.x),
y = coordinate_to_chunk(pos.y),
z = coordinate_to_chunk(pos.z)
}
end
local k_positive = math.ceil(mcl_mapgen.MAX_LIMIT / mcl_mapgen.CS_NODES)
local k_positive_z = k_positive * 2
local k_positive_y = k_positive_z * k_positive_z
function mcl_mapgen.get_chunk_number(pos) -- unsigned int
local c = mcl_mapgen.pos_to_chunk(pos)
return
(c.y + k_positive) * k_positive_y +
(c.z + k_positive) * k_positive_z +
c.x + k_positive
end
mcl_mapgen.minecraft_height_limit = 256
mcl_mapgen.bedrock_is_rough = normal
--[[ Realm stacking (h is for height)
- Overworld (h>=256)
- Void (h>=1000)
- Realm Barrier (h=11), to allow escaping the End
- End (h>=256)
- Void (h>=1000)
- Nether (h=128)
- Void (h>=1000)
]]
-- Overworld
overworld.min = -62
if superflat then
mcl_mapgen.ground = tonumber(minetest.get_mapgen_setting("mgflat_ground_level")) or 8
overworld.min = ground - 3
end
-- if singlenode then mcl_mapgen.overworld.min = -66 end -- DONT KNOW WHY
overworld.max = mcl_mapgen.EDGE_MAX
overworld.bedrock_min = overworld.min
overworld.bedrock_max = overworld.bedrock_min + (mcl_mapgen.bedrock_is_rough and 4 or 0)
mcl_mapgen.lava = normal
overworld.lava_max = overworld.min + (normal and 10 or 0)
-- The Nether (around Y = -29000)
nether.min = -29067 -- Carefully chosen to be at a mapchunk border
nether.max = nether.min + 128
nether.bedrock_bottom_min = nether.min
nether.bedrock_top_max = nether.max
if not superflat then
nether.bedrock_bottom_max = nether.bedrock_bottom_min + 4
nether.bedrock_top_min = nether.bedrock_top_max - 4
nether.lava_max = nether.min + 31
else
-- Thin bedrock in classic superflat mapgen
nether.bedrock_bottom_max = nether.bedrock_bottom_min
nether.bedrock_top_min = nether.bedrock_top_max
nether.lava_max = nether.min + 2
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
else
nether.flat_nether_floor = nether.lava_max + 4
nether.flat_nether_ceiling = nether.lava_max + 52
end
end
-- The End (surface at ca. Y = -27000)
end_.min = -27073 -- Carefully chosen to be at a mapchunk border
end_.max = overworld.min - 2000
end_.platform_pos = { x = 100, y = end_.min + 74, z = 0 }
-- Realm barrier used to safely separate the End from the void below the Overworld
mcl_mapgen.realm_barrier_overworld_end_max = end_.max
mcl_mapgen.realm_barrier_overworld_end_min = end_.max - 11
-- Use MineClone 2-style dungeons for normal mapgen
mcl_mapgen.dungeons = normal
mcl_mapgen.overworld = overworld
mcl_mapgen.end_ = end_
mcl_mapgen.nether = nether
mcl_mapgen.priorities = priorities

View File

@ -0,0 +1,4 @@
name = mcl_mapgen
author = kay27
description = MineClone 2 MapGen Basic Stuff
depends = mcl_init

View File

@ -5,25 +5,25 @@ local get_connected_players = minetest.get_connected_players
-- For a given position, returns a 2-tuple: -- For a given position, returns a 2-tuple:
-- 1st return value: true if pos is in void -- 1st return value: true if pos is in void
-- 2nd return value: true if it is in the deadly part of the void -- 2nd return value: true if it is in the deadly part of the void
local min1, min2, min3 = mcl_mapgen.overworld.min, mcl_mapgen.end_.min, mcl_mapgen.nether.min
local max1, max2, max3 = mcl_mapgen.overworld.max, mcl_mapgen.end_.max, mcl_mapgen.nether.max+128
function mcl_worlds.is_in_void(pos) function mcl_worlds.is_in_void(pos)
local void = local y = pos.y
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or local void = not ((y < max1 and y > min1) or (y < max2 and y > min2) or (y < max3 and y > min3))
(pos.y < mcl_vars.mg_nether_max+128 and pos.y > mcl_vars.mg_nether_min) or
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
local void_deadly = false local void_deadly = false
local deadly_tolerance = 64 -- the player must be this many nodes “deep” into the void to be damaged local deadly_tolerance = 64 -- the player must be this many nodes “deep” into the void to be damaged
if void then if void then
-- Overworld → Void → End → Void → Nether → Void -- Overworld → Void → End → Void → Nether → Void
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then if y < min1 and y > max2 then
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance void_deadly = y < min1 - deadly_tolerance
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then elseif y < min2 and y > max3 then
-- The void between End and Nether. Like usual, but here, the void -- The void between End and Nether. Like usual, but here, the void
-- *above* the Nether also has a small tolerance area, so player -- *above* the Nether also has a small tolerance area, so player
-- can fly above the Nether without getting hurt instantly. -- can fly above the Nether without getting hurt instantly.
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max+128 + deadly_tolerance) void_deadly = (y < min2 - deadly_tolerance) and (y > max3 + deadly_tolerance)
elseif pos.y < mcl_vars.mg_nether_min then elseif y < min3 then
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance void_deadly = y < min3 - deadly_tolerance
end end
end end
return void, void_deadly return void, void_deadly
@ -35,12 +35,12 @@ end
-- If the Y coordinate is not located in any dimension, it will return: -- If the Y coordinate is not located in any dimension, it will return:
-- nil, "void" -- nil, "void"
function mcl_worlds.y_to_layer(y) function mcl_worlds.y_to_layer(y)
if y >= mcl_vars.mg_overworld_min then if y >= min1 then
return y - mcl_vars.mg_overworld_min, "overworld" return y - min1, "overworld"
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then elseif y >= min3 and y <= max3 then
return y - mcl_vars.mg_nether_min, "nether" return y - min3, "nether"
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then elseif y >= min2 and y <= max2 then
return y - mcl_vars.mg_end_min, "end" return y - min2, "end"
else else
return nil, "void" return nil, "void"
end end
@ -62,24 +62,24 @@ local pos_to_dimension = mcl_worlds.pos_to_dimension
-- mc_dimension is one of "overworld", "nether", "end" (default: "overworld"). -- mc_dimension is one of "overworld", "nether", "end" (default: "overworld").
function mcl_worlds.layer_to_y(layer, mc_dimension) function mcl_worlds.layer_to_y(layer, mc_dimension)
if mc_dimension == "overworld" or mc_dimension == nil then if mc_dimension == "overworld" or mc_dimension == nil then
return layer + mcl_vars.mg_overworld_min return layer + min1
elseif mc_dimension == "nether" then elseif mc_dimension == "nether" then
return layer + mcl_vars.mg_nether_min return layer + min3
elseif mc_dimension == "end" then elseif mc_dimension == "end" then
return layer + mcl_vars.mg_end_min return layer + min2
end end
end end
-- Takes a position and returns true if this position can have weather -- Takes a position and returns true if this position can have weather
function mcl_worlds.has_weather(pos) function mcl_worlds.has_weather(pos)
-- Weather in the Overworld and the high part of the void below -- Weather in the Overworld and the high part of the void below
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 return pos.y <= max1 and pos.y >= min1 - 64
end end
-- Takes a position and returns true if this position can have Nether dust -- Takes a position and returns true if this position can have Nether dust
function mcl_worlds.has_dust(pos) function mcl_worlds.has_dust(pos)
-- Weather in the Overworld and the high part of the void below -- Weather in the Overworld and the high part of the void below
return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10 return pos.y <= max3 + 138 and pos.y >= min3 - 10
end end
-- Takes a position (pos) and returns true if compasses are working here -- Takes a position (pos) and returns true if compasses are working here
@ -89,7 +89,7 @@ function mcl_worlds.compass_works(pos)
if dim == "nether" or dim == "end" then if dim == "nether" or dim == "end" then
return false return false
elseif dim == "void" then elseif dim == "void" then
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 return pos.y <= max1 and pos.y >= min1 - 64
else else
return true return true
end end
@ -152,4 +152,3 @@ minetest.register_globalstep(function(dtime)
dimtimer = 0 dimtimer = 0
end end
end) end)

View File

@ -1,5 +1,4 @@
name = mcl_worlds name = mcl_worlds
author = Wuzzy author = Wuzzy
description = Utility functions for worlds and the “dimensions”. description = Utility functions for worlds and the “dimensions”.
depends = mcl_init depends = mcl_mapgen

View File

@ -1,5 +1,5 @@
name = mcl_mobs name = mcl_mobs
author = PilzAdam author = PilzAdam
description = Adds a mob API for mods to add animals or monsters, etc. description = Adds a mob API for mods to add animals or monsters, etc.
depends = mcl_particles depends = mcl_mapgen, mcl_particles
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience

View File

@ -233,15 +233,15 @@ mobs_mc.override.spawn_height = {
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
-- Overworld boundaries (inclusive) -- Overworld boundaries (inclusive)
overworld_min = mcl_vars.mg_overworld_min, overworld_min = mcl_mapgen.overworld.min,
overworld_max = mcl_vars.mg_overworld_max, overworld_max = mcl_mapgen.overworld.max,
-- Nether boundaries (inclusive) -- Nether boundaries (inclusive)
nether_min = mcl_vars.mg_nether_min, nether_min = mcl_mapgen.nether.min,
nether_max = mcl_vars.mg_nether_max, nether_max = mcl_mapgen.nether.max,
-- End boundaries (inclusive) -- End boundaries (inclusive)
end_min = mcl_vars.mg_end_min, end_min = mcl_mapgen.end_.min,
end_max = mcl_vars.mg_end_max, end_max = mcl_mapgen.end_.max,
} }

View File

@ -1,4 +1,4 @@
name = mcl_portals name = mcl_portals
description = Adds buildable portals to the Nether and End dimensions. description = Adds buildable portals to the Nether and End dimensions.
depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits depends = mcl_mapgen, mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits
optional_depends = awards, doc optional_depends = awards, doc

View File

@ -6,12 +6,6 @@ local math = math
local has_doc = minetest.get_modpath("doc") local has_doc = minetest.get_modpath("doc")
-- Parameters
--local SPAWN_MIN = mcl_vars.mg_end_min+70
--local SPAWN_MAX = mcl_vars.mg_end_min+98
--local mg_name = minetest.get_mapgen_setting("mg_name")
local function destroy_portal(pos) local function destroy_portal(pos)
local neighbors = { local neighbors = {
{ x=1, y=0, z=0 }, { x=1, y=0, z=0 },
@ -184,7 +178,7 @@ function mcl_portals.end_teleport(obj, pos)
-- Teleport to the End at a fixed position and generate a -- Teleport to the End at a fixed position and generate a
-- 5×5 obsidian platform below. -- 5×5 obsidian platform below.
local platform_pos = mcl_vars.mg_end_platform_pos local platform_pos = mcl_mapgen.end_.platform_pos
-- force emerge of target1 area -- force emerge of target1 area
minetest.get_voxel_manip():read_from_map(platform_pos, platform_pos) minetest.get_voxel_manip():read_from_map(platform_pos, platform_pos)
if not minetest.get_node_or_nil(platform_pos) then if not minetest.get_node_or_nil(platform_pos) then

View File

@ -19,7 +19,7 @@ local W_MIN, W_MAX = 4, 23
local H_MIN, H_MAX = 5, 23 local H_MIN, H_MAX = 5, 23
local N_MIN, N_MAX = 6, (W_MAX-2) * (H_MAX-2) local N_MIN, N_MAX = 6, (W_MAX-2) * (H_MAX-2)
local TRAVEL_X, TRAVEL_Y, TRAVEL_Z = 8, 1, 8 local TRAVEL_X, TRAVEL_Y, TRAVEL_Z = 8, 1, 8
local LIM_MIN, LIM_MAX = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max local LIM_MIN, LIM_MAX = mcl_mapgen.EDGE_MIN, mcl_mapgen.EDGE_MAX
local PLAYER_COOLOFF, MOB_COOLOFF = 3, 14 -- for this many seconds they won't teleported again local PLAYER_COOLOFF, MOB_COOLOFF = 3, 14 -- for this many seconds they won't teleported again
local TOUCH_CHATTER_TIME = 1 -- prevent multiple teleportation attempts caused by multiple portal touches, for this number of seconds local TOUCH_CHATTER_TIME = 1 -- prevent multiple teleportation attempts caused by multiple portal touches, for this number of seconds
local CHATTER_US = TOUCH_CHATTER_TIME * 1000000 local CHATTER_US = TOUCH_CHATTER_TIME * 1000000
@ -27,8 +27,8 @@ local DELAY = 3 -- seconds before teleporting in Nether portal in Survival mo
local DISTANCE_MAX = 128 local DISTANCE_MAX = 128
local PORTAL = "mcl_portals:portal" local PORTAL = "mcl_portals:portal"
local OBSIDIAN = "mcl_core:obsidian" local OBSIDIAN = "mcl_core:obsidian"
local O_Y_MIN, O_Y_MAX = max(mcl_vars.mg_overworld_min, -31), min(mcl_vars.mg_overworld_max, 2048) local O_Y_MIN, O_Y_MAX = max(mcl_mapgen.overworld.min, -31), min(mcl_mapgen.overworld.max, 2048)
local N_Y_MIN, N_Y_MAX = mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_top_min - H_MIN local N_Y_MIN, N_Y_MAX = mcl_mapgen.nether.bedrock_bottom_min, mcl_mapgen.nether.bedrock_top_min - H_MIN
-- Alpha and particles -- Alpha and particles
local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none" local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none"
@ -66,7 +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)
local get_node = mcl_vars.get_node local get_node = mcl_mapgen.get_far_node
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
@ -431,7 +431,7 @@ local function create_portal_2(pos1, name, obj)
end end
local exit = build_nether_portal(pos1, W_MIN-2, H_MIN-2, orientation, name) local exit = build_nether_portal(pos1, W_MIN-2, H_MIN-2, orientation, name)
finalize_teleport(obj, exit) finalize_teleport(obj, exit)
local cn = mcl_vars.get_chunk_number(pos1) local cn = mcl_mapgen.get_chunk_number(pos1)
chunks[cn] = nil chunks[cn] = nil
if queue[cn] then if queue[cn] then
for next_obj, _ in pairs(queue[cn]) do for next_obj, _ in pairs(queue[cn]) do
@ -445,9 +445,9 @@ end
local function get_lava_level(pos, pos1, pos2) local function get_lava_level(pos, pos1, pos2)
if pos.y > -1000 then if pos.y > -1000 then
return max(min(mcl_vars.mg_lava_overworld_max, pos2.y-1), pos1.y+1) return max(min(mcl_mapgen.overworld.lava_max, pos2.y-1), pos1.y+1)
end end
return max(min(mcl_vars.mg_lava_nether_max, pos2.y-1), pos1.y+1) return max(min(mcl_mapgen.nether.lava_max, pos2.y-1), pos1.y+1)
end end
local function ecb_scan_area_2(blockpos, action, calls_remaining, param) local function ecb_scan_area_2(blockpos, action, calls_remaining, param)
@ -526,7 +526,7 @@ local function ecb_scan_area_2(blockpos, action, calls_remaining, param)
end end
local function create_portal(pos, limit1, limit2, name, obj) local function create_portal(pos, limit1, limit2, name, obj)
local cn = mcl_vars.get_chunk_number(pos) local cn = mcl_mapgen.get_chunk_number(pos)
if chunks[cn] then if chunks[cn] then
local q = queue[cn] or {} local q = queue[cn] or {}
q[obj] = true q[obj] = true
@ -539,8 +539,8 @@ local function create_portal(pos, limit1, limit2, name, obj)
-- so we'll emerge single chunk only: 5x5x5 blocks, 80x80x80 nodes maximum -- so we'll emerge single chunk only: 5x5x5 blocks, 80x80x80 nodes maximum
-- and maybe one more chunk from below if (SCAN_2_MAP_CHUNKS = true) -- and maybe one more chunk from below if (SCAN_2_MAP_CHUNKS = true)
local pos1 = add(mul(mcl_vars.pos_to_chunk(pos), mcl_vars.chunk_size_in_nodes), mcl_vars.central_chunk_offset_in_nodes) local pos1 = add(mul(mcl_mapgen.pos_to_chunk(pos), mcl_mapgen.CS_NODES), mcl_mapgen.OFFSET_NODES)
local pos2 = add(pos1, mcl_vars.chunk_size_in_nodes - 1) local pos2 = add(pos1, mcl_mapgen.CS_NODES - 1)
if not SCAN_2_MAP_CHUNKS then if not SCAN_2_MAP_CHUNKS then
if limit1 and limit1.x and limit1.y and limit1.z then if limit1 and limit1.x and limit1.y and limit1.z then
@ -554,8 +554,8 @@ local function create_portal(pos, limit1, limit2, name, obj)
end end
-- Basically the copy of code above, with minor additions to continue the search in single additional chunk below: -- Basically the copy of code above, with minor additions to continue the search in single additional chunk below:
local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_vars.chunk_size_in_nodes, z = pos1.z} local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_mapgen.CS_NODES, z = pos1.z}
local next_chunk_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1) local next_chunk_2 = add(next_chunk_1, mcl_mapgen.CS_NODES - 1)
local next_pos = {x = pos.x, y=max(next_chunk_2.y, limit1.y), z = pos.z} local next_pos = {x = pos.x, y=max(next_chunk_2.y, limit1.y), z = pos.z}
if limit1 and limit1.x and limit1.y and limit1.z then if limit1 and limit1.x and limit1.y and limit1.z then
pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
name = mcl_biomes name = mcl_biomes
author = maikerumine author = maikerumine
description = Adds the various biomes and biome-related things for non-v6 map generators. description = Adds the various biomes and biome-related things for non-v6 map generators.
depends = mcl_init, mcl_mapgen_core, mcl_core, mcl_worlds, mcl_farming, mcl_flowers, mcl_end, mcl_ocean depends = mcl_mapgen, mcl_mapgen_core, mcl_core, mcl_worlds, mcl_farming, mcl_flowers, mcl_end, mcl_ocean

View File

@ -2,10 +2,8 @@
mcl_dungeons = {} mcl_dungeons = {}
local mg_name = minetest.get_mapgen_setting("mg_name")
-- Are dungeons disabled? -- Are dungeons disabled?
if mcl_vars.mg_dungeons == false or mg_name == "singlenode" then if mcl_mapgen.dungeons == false or mcl_mapgen.singlenode == true then
return return
end end
@ -16,7 +14,6 @@ local swap_node = minetest.swap_node
local set_node = minetest.set_node local set_node = minetest.set_node
local dir_to_facedir = minetest.dir_to_facedir local dir_to_facedir = minetest.dir_to_facedir
local get_meta = minetest.get_meta local get_meta = minetest.get_meta
local emerge_area = minetest.emerge_area
--vector --vector
local vector_add = vector.add local vector_add = vector.add
@ -32,15 +29,15 @@ local math_max = math.max
local math_ceil = math.ceil local math_ceil = math.ceil
--custom mcl_vars --custom mcl_vars
local get_node = mcl_vars.get_node local get_node = mcl_mapgen.get_far_node
local min_y = math_max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1 local min_y = math_max(mcl_mapgen.overworld.min, mcl_mapgen.overworld.bedrock_max) + 1
local max_y = mcl_vars.mg_overworld_max - 1 local max_y = mcl_mapgen.overworld.max - 1
-- 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.
local attempts = math_ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192 local attempts = math_ceil((mcl_mapgen.CS_NODES ^ 3) / 8192) -- 63 = 80*80*80/8192
local dungeonsizes = { local dungeonsizes = {
{ x=5, y=4, z=5}, { x=5, y=4, z=5},
@ -63,12 +60,14 @@ local surround_vectors = {
{ x=0, y=0, z=1 }, { x=0, y=0, z=1 },
} }
local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) --local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
if calls_remaining >= 1 then return end -- 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 function spawn_dungeon(p1, p2, dim, pr, dontcheck)
local p1, _, dim, pr = param.p1, param.p2, param.dim, param.pr
local x, y, z = p1.x, p1.y, p1.z local x, y, z = p1.x, p1.y, p1.z
local check = not (param.dontcheck or false) local check = not (dontcheck or false)
-- Check floor and ceiling: Must be *completely* solid -- Check floor and ceiling: Must be *completely* solid
local y_floor = y local y_floor = y
@ -358,7 +357,7 @@ local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
} }
-- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. -- Bonus loot for v6 mapgen: Otherwise unobtainable saplings.
if mg_name == "v6" then if mcl_mapgen.v6 then
table_insert(loottable, { table_insert(loottable, {
stacks_min = 1, stacks_min = 1,
stacks_max = 3, stacks_max = 3,
@ -403,8 +402,7 @@ local function dungeons_nodes(minp, maxp, blockseed)
local z = pr:next(minp.z, maxp.z-dim.z-1) local z = pr:next(minp.z, maxp.z-dim.z-1)
local p1 = {x=x,y=y,z=z} local p1 = {x=x,y=y,z=z}
local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1} local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1}
minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) spawn_dungeon(p1, p2, dim, pr)
emerge_area(p1, p2, ecb_spawn_dungeon, {p1=p1, p2=p2, dim=dim, pr=pr})
end end
end end
@ -412,8 +410,7 @@ function mcl_dungeons.spawn_dungeon(p1, _, pr)
if not p1 or not pr or not p1.x or not p1.y or not p1.z then return end if not p1 or not pr or not p1.x or not p1.y or not p1.z then return end
local dim = dungeonsizes[pr:next(1, #dungeonsizes)] local dim = dungeonsizes[pr:next(1, #dungeonsizes)]
local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.z+dim.z+1} local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.z+dim.z+1}
minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) spawn_dungeon(p1, p2, dim, pr, true)
emerge_area(p1, p2, ecb_spawn_dungeon, {p1=p1, p2=p2, dim=dim, pr=pr, dontcheck=true})
end end
mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999) mcl_mapgen.register_chunk_generator(dungeons_nodes, mcl_mapgen.priorities.DUNGEONS)

View File

@ -1,4 +1,4 @@
name = mcl_dungeons name = mcl_dungeons
author = Wuzzy author = Wuzzy
description = Generates random dungeons in the world description = Generates random dungeons in the world
depends = mcl_init, mcl_core, mcl_chests, mcl_mobs, mcl_mobspawners, mcl_mapgen_core, mobs_mc depends = mcl_mapgen, mcl_core, mcl_chests, mcl_mobs, mcl_mobspawners, mcl_mapgen_core, mobs_mc

View File

@ -1,8 +1,4 @@
mcl_mapgen_core = {} mcl_mapgen_core = {}
local registered_generators = {}
local lvm, nodes, param2 = 0, 0, 0
local lvm_buffer = {}
-- --
-- Aliases for map generator outputs -- Aliases for map generator outputs
@ -101,8 +97,8 @@ for s=1, #specialstones do
clust_scarcity = 15*15*15, clust_scarcity = 15*15*15,
clust_num_ores = 33, clust_num_ores = 33,
clust_size = 5, clust_size = 5,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 1, scale = 1,
@ -121,8 +117,8 @@ for s=1, #specialstones do
clust_scarcity = 10*10*10, clust_scarcity = 10*10*10,
clust_num_ores = 58, clust_num_ores = 58,
clust_size = 7, clust_size = 7,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 1, scale = 1,
@ -146,8 +142,8 @@ minetest.register_ore({
clust_scarcity = 15*15*15, clust_scarcity = 15*15*15,
clust_num_ores = 33, clust_num_ores = 33,
clust_size = 4, clust_size = 4,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
noise_params = { noise_params = {
offset = 0, offset = 0,
scale = 1, scale = 1,
@ -168,7 +164,7 @@ minetest.register_ore({
clust_scarcity = 14*14*14, clust_scarcity = 14*14*14,
clust_num_ores = 33, clust_num_ores = 33,
clust_size = 5, clust_size = 5,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(111), y_max = mcl_worlds.layer_to_y(111),
noise_params = { noise_params = {
offset = 0, offset = 0,
@ -195,7 +191,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 525*3, clust_scarcity = 525*3,
clust_num_ores = 5, clust_num_ores = 5,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(50), y_max = mcl_worlds.layer_to_y(50),
}) })
minetest.register_ore({ minetest.register_ore({
@ -205,7 +201,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 510*3, clust_scarcity = 510*3,
clust_num_ores = 8, clust_num_ores = 8,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(50), y_max = mcl_worlds.layer_to_y(50),
}) })
minetest.register_ore({ minetest.register_ore({
@ -215,7 +211,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 500*3, clust_scarcity = 500*3,
clust_num_ores = 12, clust_num_ores = 12,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(50), y_max = mcl_worlds.layer_to_y(50),
}) })
@ -293,7 +289,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 830, clust_scarcity = 830,
clust_num_ores = 5, clust_num_ores = 5,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(39), y_max = mcl_worlds.layer_to_y(39),
}) })
minetest.register_ore({ minetest.register_ore({
@ -319,7 +315,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 4775, clust_scarcity = 4775,
clust_num_ores = 5, clust_num_ores = 5,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(30), y_max = mcl_worlds.layer_to_y(30),
}) })
minetest.register_ore({ minetest.register_ore({
@ -329,7 +325,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 6560, clust_scarcity = 6560,
clust_num_ores = 7, clust_num_ores = 7,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(30), y_max = mcl_worlds.layer_to_y(30),
}) })
@ -357,7 +353,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 10000, clust_scarcity = 10000,
clust_num_ores = 4, clust_num_ores = 4,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(12), y_max = mcl_worlds.layer_to_y(12),
}) })
minetest.register_ore({ minetest.register_ore({
@ -367,7 +363,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 5000, clust_scarcity = 5000,
clust_num_ores = 2, clust_num_ores = 2,
clust_size = 2, clust_size = 2,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(12), y_max = mcl_worlds.layer_to_y(12),
}) })
minetest.register_ore({ minetest.register_ore({
@ -377,7 +373,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 10000, clust_scarcity = 10000,
clust_num_ores = 8, clust_num_ores = 8,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(12), y_max = mcl_worlds.layer_to_y(12),
}) })
@ -415,7 +411,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 500, clust_scarcity = 500,
clust_num_ores = 4, clust_num_ores = 4,
clust_size = 3, clust_size = 3,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(13), y_max = mcl_worlds.layer_to_y(13),
}) })
minetest.register_ore({ minetest.register_ore({
@ -425,7 +421,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 800, clust_scarcity = 800,
clust_num_ores = 7, clust_num_ores = 7,
clust_size = 4, clust_size = 4,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(13), y_max = mcl_worlds.layer_to_y(13),
}) })
@ -466,7 +462,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
clust_scarcity = 14340, clust_scarcity = 14340,
clust_num_ores = 1, clust_num_ores = 1,
clust_size = 1, clust_size = 1,
y_min = mcl_vars.mg_overworld_min, y_min = mcl_mapgen.overworld.min,
y_max = mcl_worlds.layer_to_y(29), y_max = mcl_worlds.layer_to_y(29),
}) })
-- Rare spawn -- Rare spawn
@ -682,7 +678,7 @@ local function register_mgv6_decorations()
persist = 0.6 persist = 0.6
}, },
y_min = 4, y_min = 4,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
decoration = "mcl_core:cactus", decoration = "mcl_core:cactus",
height = 1, height = 1,
height_max = 3, height_max = 3,
@ -702,7 +698,7 @@ local function register_mgv6_decorations()
persist = 0.7 persist = 0.7
}, },
y_min = 1, y_min = 1,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
decoration = "mcl_core:reeds", decoration = "mcl_core:reeds",
height = 1, height = 1,
height_max = 3, height_max = 3,
@ -732,7 +728,7 @@ local function register_mgv6_decorations()
persist = 0.0, persist = 0.0,
}, },
y_min = 1, y_min = 1,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
}) })
-- Large ferns -- Large ferns
@ -761,7 +757,7 @@ local function register_mgv6_decorations()
persist = 0.66, persist = 0.66,
}, },
y_min = 1, y_min = 1,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
}) })
-- Large flowers -- Large flowers
@ -1010,7 +1006,7 @@ local function register_mgv6_decorations()
persist = 0.666 persist = 0.666
}, },
flags = "force_placement", flags = "force_placement",
y_min = mcl_vars.mg_lava_overworld_max + 5, y_min = mcl_mapgen.overworld.lava_max + 5,
y_max = -20, y_max = -20,
}) })
@ -1042,7 +1038,7 @@ local function register_mgv6_decorations()
persist = 0.6 persist = 0.6
}, },
y_min = 1, y_min = 1,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
decoration = mushrooms[m], decoration = mushrooms[m],
spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", }, spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", },
num_spawn_by = 1, num_spawn_by = 1,
@ -1063,7 +1059,7 @@ local function register_mgv6_decorations()
persist = 0.6 persist = 0.6
}, },
y_min = 4, y_min = 4,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
decoration = "mcl_core:deadbush", decoration = "mcl_core:deadbush",
}) })
@ -1072,7 +1068,7 @@ local function register_mgv6_decorations()
offset = 0 offset = 0
end end
if y_max == nil then if y_max == nil then
y_max = mcl_vars.mg_overworld_max y_max = mcl_mapgen.overworld.max
end end
minetest.register_decoration({ minetest.register_decoration({
deco_type = "simple", deco_type = "simple",
@ -1115,7 +1111,7 @@ local function register_mgv6_decorations()
sidelen = 16, sidelen = 16,
fill_ratio = 11.0, -- complete coverage fill_ratio = 11.0, -- complete coverage
y_min = 1, y_min = 1,
y_max = mcl_vars.mg_overworld_max, y_max = mcl_mapgen.overworld.max,
decoration = "mcl_core:snow", decoration = "mcl_core:snow",
}) })
@ -1194,11 +1190,14 @@ local perlin_structures
local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density
local perlin_clay local perlin_clay
local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_area, lvm_used) -- 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
-- TODO: Make clay generation reproducible for same seed. -- TODO: Make clay generation reproducible for same seed.
if maxp.y < -5 or minp.y > 0 then if maxp.y < -5 or minp.y > 0 then
return lvm_used return c
end end
minetest.log("warning", "CLAY!")
local pr = PseudoRandom(blockseed) local pr = PseudoRandom(blockseed)
@ -1244,8 +1243,9 @@ local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_
end end
end end
end end
return lvm_used c.write = lvm_used
end return c
end)
local function generate_end_exit_portal(pos) local function generate_end_exit_portal(pos)
local obj = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon") local obj = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon")
@ -1724,7 +1724,7 @@ local function generate_underground_mushrooms(minp, maxp, seed)
local pr_shroom = PseudoRandom(seed-24359) local pr_shroom = PseudoRandom(seed-24359)
-- Generate rare underground mushrooms -- Generate rare underground mushrooms
-- TODO: Make them appear in groups, use Perlin noise -- TODO: Make them appear in groups, use Perlin noise
local min, max = mcl_vars.mg_lava_overworld_max + 4, 0 local min, max = mcl_mapgen.overworld.lava_max + 4, 0
if minp.y > max or maxp.y < min then if minp.y > max or maxp.y < min then
return return
end end
@ -1757,7 +1757,7 @@ end
local function generate_nether_decorations(minp, maxp, seed) local function generate_nether_decorations(minp, maxp, seed)
local pr_nether = PseudoRandom(seed+667) local pr_nether = PseudoRandom(seed+667)
if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then if minp.y > mcl_mapgen.nether.max or maxp.y < mcl_mapgen.nether.min then
return return
end end
@ -1819,92 +1819,6 @@ local function generate_nether_decorations(minp, maxp, seed)
end end
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))
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
local lvm_used, shadow = false, false
local lb2 = {} -- param2
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 data2
local data = vm:get_data(lvm_buffer)
if param2 > 0 then
data2 = vm:get_param2_data(lb2)
end
local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
for _, rec in pairs(registered_generators) do
if rec.vf then
local lvm_used0, shadow0 = rec.vf(vm, data, data2, e1, e2, area, p1, p2, blockseed)
if lvm_used0 then
lvm_used = true
end
if shadow0 then
shadow = true
end
end
end
if lvm_used then
-- Write stuff
vm:set_data(data)
if param2 > 0 then
vm:set_param2_data(data2)
end
vm:calc_lighting(p1, p2, shadow)
vm:write_to_map()
vm:update_liquids()
end
end
if nodes > 0 then
for _, rec in pairs(registered_generators) do
if rec.nf then
rec.nf(p1, p2, blockseed)
end
end
end
mcl_vars.add_chunk(minp)
end)
function minetest.register_on_generated(node_function)
mcl_mapgen_core.register_generator("mod_"..tostring(#registered_generators+1), nil, node_function)
end
function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2)
if not id then return end
local priority = priority or 5000
if lvm_function then lvm = lvm + 1 end
if lvm_function then nodes = nodes + 1 end
if needs_param2 then param2 = param2 + 1 end
local new_record = {
i = priority,
vf = lvm_function,
nf = node_function,
needs_param2 = needs_param2,
}
registered_generators[id] = new_record
table.sort(registered_generators, function(a, b)
return (a.i < b.i) or ((a.i == b.i) and a.vf and (b.vf == nil))
end)
end
function mcl_mapgen_core.unregister_generator(id)
if not registered_generators[id] then return end
local rec = registered_generators[id]
registered_generators[id] = nil
if rec.vf then lvm = lvm - 1 end
if rec.nf then nodes = nodes - 1 end
if rec.needs_param2 then param2 = param2 - 1 end
--if rec.needs_level0 then level0 = level0 - 1 end
end
-- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc. -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc.
-- Also perform some basic node replacements. -- Also perform some basic node replacements.
@ -1981,29 +1895,32 @@ local function set_layers(data, area, content_id, check, min, max, minp, maxp, l
end end
-- Below the bedrock, generate air/void -- Below the bedrock, generate air/void
local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) local function basic(c)
local biomemap --ymin, ymax 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 lvm_used = false local lvm_used = false
local pr = PseudoRandom(blockseed) local pr = PseudoRandom(blockseed)
-- The Void below the Nether: -- The Void below the Nether:
lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mapgen_edge_min , mcl_vars.mg_nether_min -1, minp, maxp, lvm_used, pr) lvm_used = set_layers(data, area, c_void , nil, mcl_mapgen.EDGE_MIN , mcl_mapgen.nether.min -1, minp, maxp, lvm_used, pr)
-- [[ THE NETHER: mcl_vars.mg_nether_min mcl_vars.mg_nether_max ]] -- [[ THE NETHER: mcl_mapgen.nether.min mcl_mapgen.nether.max ]]
-- The Air on the Nether roof, https://git.minetest.land/MineClone2/MineClone2/issues/1186 -- The Air on the Nether roof, https://git.minetest.land/MineClone2/MineClone2/issues/1186
lvm_used = set_layers(data, area, c_air , nil, mcl_vars.mg_nether_max +1, mcl_vars.mg_nether_max + 128 , minp, maxp, lvm_used, pr) lvm_used = set_layers(data, area, c_air , nil, mcl_mapgen.nether.max +1, mcl_mapgen.nether.max + 128 , minp, maxp, lvm_used, pr)
-- The Void above the Nether below the End: -- The Void above the Nether below the End:
lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_nether_max + 128 +1, mcl_vars.mg_end_min -1, minp, maxp, lvm_used, pr) lvm_used = set_layers(data, area, c_void , nil, mcl_mapgen.nether.max + 128 +1, mcl_mapgen.end_.min -1, minp, maxp, lvm_used, pr)
-- [[ THE END: mcl_vars.mg_end_min mcl_vars.mg_end_max ]] -- [[ THE END: mcl_mapgen.end_.min mcl_mapgen.end_.max ]]
-- The Void above the End below the Realm barrier: -- The Void above the End below the Realm barrier:
lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_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_vars.mg_realm_barrier_overworld_end_min-1, minp, maxp, lvm_used, pr)
-- Realm barrier between the Overworld void and the End -- 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_vars.mg_realm_barrier_overworld_end_min , mcl_vars.mg_realm_barrier_overworld_end_max , minp, maxp, lvm_used, pr)
-- The Void above Realm barrier below the Overworld: -- 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_vars.mg_overworld_min -1, minp, maxp, lvm_used, pr) 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)
if mg_name ~= "singlenode" then if mg_name ~= "singlenode" then
@ -2019,14 +1936,15 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
-- Big lava seas by replacing air below a certain height -- Big lava seas by replacing air below a certain height
if mcl_vars.mg_lava then if mcl_vars.mg_lava then
lvm_used = set_layers(data, area, c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, emin, emax, lvm_used, pr) 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_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, emin, emax, 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)
end end
-- Clay, vines, cocoas -- Clay, vines, cocoas
lvm_used = generate_clay(minp, maxp, blockseed, data, area, lvm_used) lvm_used = generate_clay(minp, maxp, blockseed, data, area, lvm_used)
biomemap = minetest.get_mapgen_object("biomemap") c.biomemap = c.biomemap or minetest.get_mapgen_object("biomemap")
lvm_used = generate_tree_decorations(minp, maxp, blockseed, data, data2, area, biomemap, lvm_used, pr) lvm_used = generate_tree_decorations(minp, maxp, blockseed, data, data2, area, biomemap, lvm_used, pr)
----- Interactive block fixing section ----- ----- Interactive block fixing section -----
@ -2035,7 +1953,7 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
-- Snow and sand fixes. This code implements snow consistency -- Snow and sand fixes. This code implements snow consistency
-- and fixes floating sand and cut plants. -- and fixes floating sand and cut plants.
-- A snowy grass block must be below a top snow or snow block at all times. -- A snowy grass block must be below a top snow or snow block at all times.
if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then if minp.y <= mcl_mapgen.overworld.max and maxp.y >= mcl_mapgen.overworld.min then
-- v6 mapgen: -- v6 mapgen:
if mg_name == "v6" then if mg_name == "v6" then
@ -2101,7 +2019,7 @@ 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 emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then elseif emin.y <= mcl_mapgen.nether.max and emax.y >= mcl_mapgen.nether.min then
if mg_name == "v6" then if mg_name == "v6" then
local nodes = minetest.find_nodes_in_area(emin, emax, {"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
@ -2128,7 +2046,7 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
-- * Replace water with end stone or air (depending on height). -- * Replace water with end stone or air (depending on height).
-- * Remove stone, sand, dirt in v6 so our End map generator works in v6. -- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
-- * Generate spawn platform (End portal destination) -- * Generate spawn platform (End portal destination)
elseif minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min then elseif minp.y <= mcl_mapgen.end_.max and maxp.y >= mcl_mapgen.end_.min then
local nodes local nodes
if mg_name == "v6" then if mg_name == "v6" then
nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"})
@ -2170,11 +2088,11 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
-- Final hackery: Set sun light level in the End. -- Final hackery: Set sun light level in the End.
-- -26912 is at a mapchunk border. -- -26912 is at a mapchunk border.
local shadow = true local shadow = true
if minp.y >= -26912 and maxp.y <= mcl_vars.mg_end_max then if minp.y >= -26912 and maxp.y <= mcl_mapgen.end_.max then
vm:set_lighting({day=15, night=15}) vm:set_lighting({day=15, night=15})
lvm_used = true lvm_used = true
end end
if minp.y >= mcl_vars.mg_end_min and maxp.y <= -26911 then if minp.y >= mcl_mapgen.end_.min and maxp.y <= -26911 then
shadow = false shadow = false
lvm_used = true lvm_used = true
end end
@ -2189,5 +2107,5 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
return lvm_used, shadow return lvm_used, shadow
end end
mcl_mapgen_core.register_generator("main", basic, nil, 1, true) mcl_mapgen.register_chunk_generator_lvm(basic, 1)

View File

@ -1,5 +1,5 @@
name = mcl_mapgen_core name = mcl_mapgen_core
author = Wuzzy author = Wuzzy
description = The core of the MCL2 mapgen description = The core of the MCL2 mapgen
depends = mcl_init, mcl_core, biomeinfo, mcl_worlds, mcl_cocoas, mcl_sponges, mcl_ocean, mcl_stairs, mcl_monster_eggs, mcl_structures depends = mcl_mapgen, mcl_core, biomeinfo, mcl_worlds, mcl_cocoas, mcl_sponges, mcl_ocean, mcl_stairs, mcl_monster_eggs, mcl_structures
optional_depends = mclx_core optional_depends = mclx_core

View File

@ -0,0 +1,97 @@
-- Check it:
-- seed 1, v7 mapgen
-- /teleport 14958,8,11370
local mcl_mapgen_get_far_node = mcl_mapgen.get_far_node
local minetest_log = minetest.log
local minetest_place_schematic = minetest.place_schematic
local minetest_pos_to_string = minetest.pos_to_string
local minetest_swap_node = minetest.swap_node
local path = minetest.get_modpath("mcl_ocean_monument") .. "/schematics/ocean_monument.mts"
local water = "mcl_core:water_source"
local air = "air"
local ice = "mcl_core:ice"
local leg_materials = {
"mcl_ocean:prismarine_brick",
"mcl_ocean:prismarine",
}
local what_we_can_replace_by_legs = {
water,
air,
"mcl_core:water_flowing",
"mcl_core:stone",
}
local leg_search_quick_index = {}
for _, v in pairs(leg_materials) do
leg_search_quick_index[v] = true
end
local leg_replace_quick_index = {}
for _, v in pairs(what_we_can_replace_by_legs) do
leg_replace_quick_index[v] = true
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)
local minp = minp
local y = minp.y
if y ~= y_wanted then return end
local x, z = minp.x, minp.z
local pr = PseudoRandom(seed)
-- scan the ocean - it should be the ocean:
for i = 1, pr:next(10, 100) do
local pos = {x = pr:next(15, 64) + x, y = pr:next(0, 25) - 25, z = pr:next(15, 64) + z}
local node_name = mcl_mapgen_get_far_node(pos).name
if node_name ~= water then return end
end
-- scan nodes above water level - there should be the air:
for i = 1, pr:next(10, 100) do
local pos = {x = pr:next(0, 79) + x, y = 2, z = pr:next(0,79) + z}
local node_name = mcl_mapgen_get_far_node(pos).name
if node_name ~= air then return end
end
-- scan ocean surface - allow only water and ice:
for i = 1, pr:next(10,100) do
local pos = {x=pr:next(0, 79)+x, y=1, z=pr:next(0,79)+z}
local node_name = mcl_mapgen_get_far_node(pos).name
if node_name ~= water and node_name ~= ice then return end
end
-- random rotation:
local rotation = pr:next(0, 3)
local rotation_str = tostring(rotation * 90)
minetest_place_schematic(minp, path, rotation_str, nil, true)
-- search prismarine legs at base level and continue them up to the bottom:
for x = x, maxp.x do
for z = z, maxp.z do
local pos = {x = x, y = y, z = z}
local node_name = mcl_mapgen_get_far_node(pos).name
if leg_search_quick_index[node_name] then
local node_leg = {name = node_name}
for y = y - 1, y_bottom, -1 do
pos.y = y
local next_name = mcl_mapgen_get_far_node(pos).name
if not leg_replace_quick_index[next_name] then
break
end
minetest_swap_node(pos, node_leg)
end
end
end
end
minetest_log("action", "[mcl_ocean_monument] Placed at " .. minetest_pos_to_string(minp) .. ", " .. rotation_str .. " deg.")
end, mcl_mapgen.priorities.OCEAN_MONUMENT)

View File

@ -0,0 +1,4 @@
name = mcl_ocean_monument
author = TrashPanda
description = Adds Ocean Monument, https://git.minetest.land/MineClone2/MineClone2/issues/958#issuecomment-14102
depends = mcl_mapgen, mcl_structures

View File

@ -18,8 +18,7 @@ local stronghold_rings = {
local strongholds = {} local strongholds = {}
local strongholds_inited = false local strongholds_inited = false
local mg_name = minetest.get_mapgen_setting("mg_name") local superflat = mcl_mapgen.superflat
local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true"
-- Determine the stronghold positions and store them into the strongholds table. -- Determine the stronghold positions and store them into the strongholds table.
-- The stronghold positions are based on the world seed. -- The stronghold positions are based on the world seed.
@ -30,7 +29,7 @@ local function init_strongholds()
return return
end end
-- Don't generate strongholds in singlenode -- Don't generate strongholds in singlenode
if mg_name == "singlenode" then if mcl_mapgen.singlenode then
strongholds_inited = true strongholds_inited = true
return return
end end
@ -47,9 +46,9 @@ local function init_strongholds()
local dist = pr:next(ring.min, ring.max) local dist = pr:next(ring.min, ring.max)
local y local y
if superflat then if superflat then
y = mcl_vars.mg_bedrock_overworld_max + 3 y = mcl_mapgen.overworld.bedrock_max + 3
else else
y = pr:next(mcl_vars.mg_bedrock_overworld_max+1, mcl_vars.mg_overworld_min+48) y = pr:next(mcl_mapgen.overworld.bedrock_max+1, mcl_mapgen.overworld.bedrock_min+48)
end end
local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist } local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist }
pos = vector.round(pos) pos = vector.round(pos)
@ -66,8 +65,10 @@ local function init_strongholds()
strongholds_inited = true strongholds_inited = true
end end
init_strongholds()
-- Stronghold generation for register_on_generated. -- Stronghold generation for register_on_generated.
local function generate_strongholds(minp, maxp, blockseed) mcl_mapgen.register_chunk_generator(function(minp, maxp, blockseed)
local pr = PseudoRandom(blockseed) local pr = PseudoRandom(blockseed)
for s=1, #strongholds do for s=1, #strongholds do
if not strongholds[s].generated then if not strongholds[s].generated then
@ -99,8 +100,4 @@ local function generate_strongholds(minp, maxp, blockseed)
end end
end end
end end
end end, mcl_mapgen.priorities.STRONGHOLDS)
init_strongholds()
mcl_mapgen_core.register_generator("strongholds", nil, generate_strongholds, 999999)

View File

@ -38,7 +38,9 @@ function mcl_structures.place_schematic(pos, schematic, rotation, replacements,
local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1}
minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2))
local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param}
minetest.emerge_area(p1, p2, ecb_place, param) -- minetest.emerge_area(p1, p2, ecb_place, param)
-- TODO: Make it better
ecb_place(0, 0, 0, param)
end end
end end
@ -115,14 +117,14 @@ function mcl_structures.generate_igloo(pos, rotation, pr)
if r == 1 then if r == 1 then
-- Select basement depth -- Select basement depth
local dim = mcl_worlds.pos_to_dimension(pos) local dim = mcl_worlds.pos_to_dimension(pos)
--local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) --local buffer = pos.y - (mcl_mapgen.overworld.lava_max + 10)
local buffer local buffer
if dim == "nether" then if dim == "nether" then
buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10) buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10)
elseif dim == "end" then elseif dim == "end" then
buffer = pos.y - (mcl_vars.mg_end_min + 1) buffer = pos.y - (mcl_vars.mg_end_min + 1)
elseif dim == "overworld" then elseif dim == "overworld" then
buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) buffer = pos.y - (mcl_mapgen.overworld.lava_max + 10)
else else
return success return success
end end
@ -284,7 +286,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_vars.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_mapgen.get_far_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

View File

@ -88,7 +88,7 @@ function settlements.create_site_plan(maxp, minp, pr)
-- find center_surface of chunk -- find center_surface of chunk
local center_surface , surface_material = settlements.find_surface(center, true) local center_surface , surface_material = settlements.find_surface(center, true)
local chunks = {} local chunks = {}
chunks[mcl_vars.get_chunk_number(center)] = true chunks[mcl_mapgen.get_chunk_number(center)] = true
-- go build settlement around center -- go build settlement around center
if not center_surface then return false end if not center_surface then return false end
@ -124,7 +124,7 @@ function settlements.create_site_plan(maxp, minp, pr)
ptx = settlements.round(ptx, 0) ptx = settlements.round(ptx, 0)
ptz = settlements.round(ptz, 0) ptz = settlements.round(ptz, 0)
local pos1 = { x=ptx, y=center_surface.y+50, z=ptz} local pos1 = { x=ptx, y=center_surface.y+50, z=ptz}
local chunk_number = mcl_vars.get_chunk_number(pos1) local chunk_number = mcl_mapgen.get_chunk_number(pos1)
local pos_surface, surface_material local pos_surface, surface_material
if chunks[chunk_number] then if chunks[chunk_number] then
pos_surface, surface_material = settlements.find_surface(pos1) pos_surface, surface_material = settlements.find_surface(pos1)

View File

@ -1,6 +1,8 @@
settlements = {} settlements = {}
settlements.modpath = minetest.get_modpath(minetest.get_current_modname()) settlements.modpath = minetest.get_modpath(minetest.get_current_modname())
local minetest_get_spawn_level = minetest.get_spawn_level
dofile(settlements.modpath.."/const.lua") dofile(settlements.modpath.."/const.lua")
dofile(settlements.modpath.."/utils.lua") dofile(settlements.modpath.."/utils.lua")
dofile(settlements.modpath.."/foundation.lua") dofile(settlements.modpath.."/foundation.lua")
@ -53,6 +55,7 @@ end
-- on map generation, try to build a settlement -- on map generation, try to build a settlement
-- --
local function build_a_settlement(minp, maxp, blockseed) local function build_a_settlement(minp, maxp, blockseed)
minetest.log("action","[mcl_villages] Building village at mapchunk " .. minetest.pos_to_string(minp) .. "..." .. minetest.pos_to_string(maxp) .. ", blockseed = " .. tostring(blockseed))
local pr = PseudoRandom(blockseed) local pr = PseudoRandom(blockseed)
-- fill settlement_info with buildings and their data -- fill settlement_info with buildings and their data
@ -69,29 +72,38 @@ local function build_a_settlement(minp, maxp, blockseed)
settlements.place_schematics(settlement_info, pr) settlements.place_schematics(settlement_info, pr)
end end
local function ecb_village(blockpos, action, calls_remaining, param)
if calls_remaining >= 1 then return end
local minp, maxp, blockseed = param.minp, param.maxp, param.blockseed
build_a_settlement(minp, maxp, blockseed)
end
-- Disable natural generation in singlenode. -- Disable natural generation in singlenode.
local mg_name = minetest.get_mapgen_setting("mg_name") local mg_name = minetest.get_mapgen_setting("mg_name")
if mg_name ~= "singlenode" then if mg_name ~= "singlenode" then
mcl_mapgen_core.register_generator("villages", nil, function(minp, maxp, blockseed) mcl_mapgen.register_chunk_generator(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 -- don't build settlement underground
if maxp.y < 0 then return end if maxp.y < 0 then return end
-- randomly try to build settlements -- randomly try to build settlements
if blockseed % 77 ~= 17 then return end if blockseed % 77 ~= 17 then return end
-- needed for manual and automated settlement building
-- don't build settlements on (too) uneven terrain -- don't build settlements on (too) uneven terrain
--local heightmap = minetest.get_mapgen_object("heightmap")
local height_difference = settlements.evaluate_heightmap() -- lame and quick replacement of `heightmap` by kay27 - we maybe need to restore `heightmap` analysis if there will be a way for the engine to avoid cavegen conflicts:
--------------------------------------------------------------------------
local height_difference, min, max
local pr1=PseudoRandom(blockseed)
for i=1,pr1:next(5,10) do
local x = pr1:next(0, 40) + minp.x + 19
local z = pr1:next(0, 40) + minp.z + 19
local y = minetest_get_spawn_level(x, z)
if not y then return end
if y < (min or y+1) then min = y end
if y > (max or y-1) then max = y end
end
height_difference = max - min + 1
--------------------------------------------------------------------------
if height_difference > max_height_difference then return end if height_difference > max_height_difference then return end
local param={minp=vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed} build_a_settlement(minp, maxp, blockseed)
minetest.emerge_area(minp, maxp, ecb_village, param) end, mcl_mapgen.priorities.VILLAGES)
end)
end end
-- manually place villages -- manually place villages
if minetest.is_creative_enabled("") then if minetest.is_creative_enabled("") then

View File

@ -1,4 +1,4 @@
local get_node = mcl_vars.get_node local get_node = mcl_mapgen.get_far_node
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- function to copy tables -- function to copy tables
@ -207,44 +207,6 @@ function shuffle(tbl, pr)
return table return table
end end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- evaluate heightmap
-------------------------------------------------------------------------------
function settlements.evaluate_heightmap()
local heightmap = minetest.get_mapgen_object("heightmap")
-- max height and min height, initialize with impossible values for easier first time setting
local max_y = -50000
local min_y = 50000
-- only evaluate the center square of heightmap 40 x 40
local square_start = 1621
local square_end = 1661
for j = 1 , 40, 1 do
for i = square_start, square_end, 1 do
-- skip buggy heightmaps, return high value
if heightmap[i] == -31000 or heightmap[i] == 31000 then
return max_height_difference + 1
end
if heightmap[i] < min_y then
min_y = heightmap[i]
end
if heightmap[i] > max_y then
max_y = heightmap[i]
end
end
-- set next line
square_start = square_start + 80
square_end = square_end + 80
end
-- return the difference between highest and lowest pos in chunk
local height_diff = max_y - min_y
-- filter buggy heightmaps
if height_diff <= 1 then
return max_height_difference + 1
end
-- debug info
settlements.debug("heightdiff ".. height_diff)
return height_diff
end
-------------------------------------------------------------------------------
-- Set array to list -- Set array to list
-- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list -- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@ -19,8 +19,7 @@ end
local probability_railcaves_in_mapchunk = P(0.33333) local probability_railcaves_in_mapchunk = P(0.33333)
setting = tonumber(minetest.settings:get("tsm_railcorridors_probability_railcaves_in_mapchunk")) setting = tonumber(minetest.settings:get("tsm_railcorridors_probability_railcaves_in_mapchunk"))
-- Extra check to prevent mod griefing in singlenode, mcimported worlds. -- Extra check to prevent mod griefing in singlenode, mcimported worlds.
local mg_name = minetest.get_mapgen_setting("mg_name") if mcl_mapgen.singlenode then
if mg_name == "singlenode" then
probability_railcaves_in_mapchunk = P(0) probability_railcaves_in_mapchunk = P(0)
elseif setting then elseif setting then
probability_railcaves_in_mapchunk = P(setting) probability_railcaves_in_mapchunk = P(setting)
@ -96,10 +95,10 @@ end
-- Max. and min. heights between rail corridors are generated -- Max. and min. heights between rail corridors are generated
local height_min local height_min
if mcl_vars.mg_lava then if mcl_mapgen.lava then
height_min = mcl_vars.mg_lava_overworld_max + 2 height_min = mcl_mapgen.overworld.lava_max + 2
else else
height_min = mcl_vars.mg_bedrock_overworld_max + 2 height_min = mcl_mapgen.overworld.bedrock_max + 2
end end
local height_max = mcl_worlds.layer_to_y(60) local height_max = mcl_worlds.layer_to_y(60)
@ -1093,7 +1092,7 @@ local function create_corridor_system(main_cave_coords)
end end
-- The rail corridor algorithm starts here -- The rail corridor algorithm starts here
mcl_mapgen_core.register_generator("railcorridors", nil, function(minp, maxp, blockseed, _pr) mcl_mapgen.register_chunk_generator(function(minp, maxp, blockseed, _pr)
-- We re-init the randomizer for every mapchunk as we start generating in the middle of each mapchunk. -- 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. -- We can't use the mapgen seed as this would make the algorithm depending on the order the mapchunk generate.
InitRandomizer(blockseed) InitRandomizer(blockseed)

View File

@ -8,33 +8,6 @@ minetest.register_craft({
recipe = {"mcl_core:iron_ingot", "mcl_core:stick", "group:wood", "mcl_chests:chest"}, recipe = {"mcl_core:iron_ingot", "mcl_core:stick", "group:wood", "mcl_chests:chest"},
}) })
minetest.register_craft({
output = "mcl_sponges:sponge",
recipe = {
{ "mcl_farming:hay_block", "mcl_farming:hay_block", "mcl_farming:hay_block" },
{ "mcl_farming:hay_block", "mcl_core:goldblock", "mcl_farming:hay_block" },
{ "mcl_farming:hay_block", "mcl_farming:hay_block", "mcl_farming:hay_block" },
}
})
minetest.register_craft({
output = "mcl_ocean:prismarine_shard",
recipe = {
{ "mcl_core:glass_cyan", },
}
})
minetest.register_craft({
type = "shapeless",
output = "mcl_ocean:prismarine_crystals",
recipe = {
"mcl_ocean:prismarine_shard",
"mcl_ocean:prismarine_shard",
"mcl_ocean:prismarine_shard",
"mcl_core:gold_ingot",
},
})
minetest.register_craft({ minetest.register_craft({
output = "mcl_armor:helmet_chain", output = "mcl_armor:helmet_chain",
recipe = { recipe = {

View File

@ -81,7 +81,7 @@ local dir_step = storage:get_int("mcl_spawn_dir_step") or 0
local dir_ind = storage:get_int("mcl_spawn_dir_ind") or 1 local dir_ind = storage:get_int("mcl_spawn_dir_ind") or 1
local emerge_pos1, emerge_pos2 local emerge_pos1, emerge_pos2
local spawn_limit = mcl_vars.mapgen_edge_max local spawn_limit = mcl_mapgen.EDGE_MAX
--Functions --Functions

View File

@ -1,4 +1,4 @@
name = mcl_spawn name = mcl_spawn
author = Wuzzy author = Wuzzy
description = Set and get the player's respawn position description = Set and get the player's respawn position
depends = mcl_init depends = mcl_mapgen