forked from MineClone5/MineClone5
Update Fork #1
|
@ -27,6 +27,8 @@ movement_gravity = 10.4
|
|||
|
||||
# Mapgen stuff
|
||||
|
||||
max_block_generate_distance = 13
|
||||
|
||||
# altitude_chill and altitude_dry doesn't go well together with MCL2 biomes
|
||||
# which already include "snowed" variants as you go higher.
|
||||
# humid_rivers would cause the MushroomIsland biome to appear frequently around rivers.
|
||||
|
|
|
@ -24,240 +24,9 @@ mcl_vars.inventory_header = ""
|
|||
-- Tool wield size
|
||||
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
|
||||
minetest.nodedef_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)
|
||||
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
|
||||
|
|
|
@ -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"}`.
|
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
name = mcl_mapgen
|
||||
author = kay27
|
||||
description = MineClone 2 MapGen Basic Stuff
|
||||
depends = mcl_init
|
|
@ -5,25 +5,25 @@ local get_connected_players = minetest.get_connected_players
|
|||
-- For a given position, returns a 2-tuple:
|
||||
-- 1st return value: true if pos is in 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)
|
||||
local void =
|
||||
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
||||
(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 y = pos.y
|
||||
local void = not ((y < max1 and y > min1) or (y < max2 and y > min2) or (y < max3 and y > min3))
|
||||
|
||||
local void_deadly = false
|
||||
local deadly_tolerance = 64 -- the player must be this many nodes “deep” into the void to be damaged
|
||||
if void then
|
||||
-- Overworld → Void → End → Void → Nether → Void
|
||||
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
||||
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
||||
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then
|
||||
if y < min1 and y > max2 then
|
||||
void_deadly = y < min1 - deadly_tolerance
|
||||
elseif y < min2 and y > max3 then
|
||||
-- The void between End and Nether. Like usual, but here, the void
|
||||
-- *above* the Nether also has a small tolerance area, so player
|
||||
-- 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)
|
||||
elseif pos.y < mcl_vars.mg_nether_min then
|
||||
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
||||
void_deadly = (y < min2 - deadly_tolerance) and (y > max3 + deadly_tolerance)
|
||||
elseif y < min3 then
|
||||
void_deadly = y < min3 - deadly_tolerance
|
||||
end
|
||||
end
|
||||
return void, void_deadly
|
||||
|
@ -35,15 +35,15 @@ end
|
|||
-- If the Y coordinate is not located in any dimension, it will return:
|
||||
-- nil, "void"
|
||||
function mcl_worlds.y_to_layer(y)
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
|
||||
return y - mcl_vars.mg_nether_min, "nether"
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
return y - mcl_vars.mg_end_min, "end"
|
||||
else
|
||||
return nil, "void"
|
||||
end
|
||||
if y >= min1 then
|
||||
return y - min1, "overworld"
|
||||
elseif y >= min3 and y <= max3 then
|
||||
return y - min3, "nether"
|
||||
elseif y >= min2 and y <= max2 then
|
||||
return y - min2, "end"
|
||||
else
|
||||
return nil, "void"
|
||||
end
|
||||
end
|
||||
|
||||
local y_to_layer = mcl_worlds.y_to_layer
|
||||
|
@ -61,38 +61,38 @@ local pos_to_dimension = mcl_worlds.pos_to_dimension
|
|||
-- MineClone 2.
|
||||
-- mc_dimension is one of "overworld", "nether", "end" (default: "overworld").
|
||||
function mcl_worlds.layer_to_y(layer, mc_dimension)
|
||||
if mc_dimension == "overworld" or mc_dimension == nil then
|
||||
return layer + mcl_vars.mg_overworld_min
|
||||
elseif mc_dimension == "nether" then
|
||||
return layer + mcl_vars.mg_nether_min
|
||||
elseif mc_dimension == "end" then
|
||||
return layer + mcl_vars.mg_end_min
|
||||
end
|
||||
if mc_dimension == "overworld" or mc_dimension == nil then
|
||||
return layer + min1
|
||||
elseif mc_dimension == "nether" then
|
||||
return layer + min3
|
||||
elseif mc_dimension == "end" then
|
||||
return layer + min2
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a position and returns true if this position can have weather
|
||||
function mcl_worlds.has_weather(pos)
|
||||
-- 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
|
||||
-- Weather in the Overworld and the high part of the void below
|
||||
return pos.y <= max1 and pos.y >= min1 - 64
|
||||
end
|
||||
|
||||
-- Takes a position and returns true if this position can have Nether dust
|
||||
function mcl_worlds.has_dust(pos)
|
||||
-- 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
|
||||
-- Weather in the Overworld and the high part of the void below
|
||||
return pos.y <= max3 + 138 and pos.y >= min3 - 10
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if compasses are working here
|
||||
function mcl_worlds.compass_works(pos)
|
||||
-- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below
|
||||
local _, dim = mcl_worlds.y_to_layer(pos.y)
|
||||
if dim == "nether" or dim == "end" then
|
||||
return false
|
||||
elseif dim == "void" then
|
||||
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
|
||||
else
|
||||
return true
|
||||
end
|
||||
-- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below
|
||||
local _, dim = mcl_worlds.y_to_layer(pos.y)
|
||||
if dim == "nether" or dim == "end" then
|
||||
return false
|
||||
elseif dim == "void" then
|
||||
return pos.y <= max1 and pos.y >= min1 - 64
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if clocks are working here
|
||||
|
@ -152,4 +152,3 @@ minetest.register_globalstep(function(dtime)
|
|||
dimtimer = 0
|
||||
end
|
||||
end)
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
name = mcl_worlds
|
||||
author = Wuzzy
|
||||
description = Utility functions for worlds and the “dimensions”.
|
||||
depends = mcl_init
|
||||
|
||||
depends = mcl_mapgen
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name = mcl_mobs
|
||||
author = PilzAdam
|
||||
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
|
||||
|
|
|
@ -233,15 +233,15 @@ mobs_mc.override.spawn_height = {
|
|||
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
|
||||
|
||||
-- Overworld boundaries (inclusive)
|
||||
overworld_min = mcl_vars.mg_overworld_min,
|
||||
overworld_max = mcl_vars.mg_overworld_max,
|
||||
overworld_min = mcl_mapgen.overworld.min,
|
||||
overworld_max = mcl_mapgen.overworld.max,
|
||||
|
||||
-- Nether boundaries (inclusive)
|
||||
nether_min = mcl_vars.mg_nether_min,
|
||||
nether_max = mcl_vars.mg_nether_max,
|
||||
nether_min = mcl_mapgen.nether.min,
|
||||
nether_max = mcl_mapgen.nether.max,
|
||||
|
||||
-- End boundaries (inclusive)
|
||||
end_min = mcl_vars.mg_end_min,
|
||||
end_max = mcl_vars.mg_end_max,
|
||||
end_min = mcl_mapgen.end_.min,
|
||||
end_max = mcl_mapgen.end_.max,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_portals
|
||||
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
|
||||
|
|
|
@ -6,12 +6,6 @@ local math = math
|
|||
|
||||
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 neighbors = {
|
||||
{ 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
|
||||
-- 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
|
||||
minetest.get_voxel_manip():read_from_map(platform_pos, platform_pos)
|
||||
if not minetest.get_node_or_nil(platform_pos) then
|
||||
|
|
|
@ -19,7 +19,7 @@ local W_MIN, W_MAX = 4, 23
|
|||
local H_MIN, H_MAX = 5, 23
|
||||
local N_MIN, N_MAX = 6, (W_MAX-2) * (H_MAX-2)
|
||||
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 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
|
||||
|
@ -27,8 +27,8 @@ local DELAY = 3 -- seconds before teleporting in Nether portal in Survival mo
|
|||
local DISTANCE_MAX = 128
|
||||
local PORTAL = "mcl_portals:portal"
|
||||
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 N_Y_MIN, N_Y_MAX = mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_top_min - H_MIN
|
||||
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_mapgen.nether.bedrock_bottom_min, mcl_mapgen.nether.bedrock_top_min - H_MIN
|
||||
|
||||
-- Alpha and particles
|
||||
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))
|
||||
end)
|
||||
|
||||
local get_node = mcl_vars.get_node
|
||||
local get_node = mcl_mapgen.get_far_node
|
||||
local set_node = minetest.set_node
|
||||
local registered_nodes = minetest.registered_nodes
|
||||
local is_protected = minetest.is_protected
|
||||
|
@ -431,7 +431,7 @@ local function create_portal_2(pos1, name, obj)
|
|||
end
|
||||
local exit = build_nether_portal(pos1, W_MIN-2, H_MIN-2, orientation, name)
|
||||
finalize_teleport(obj, exit)
|
||||
local cn = mcl_vars.get_chunk_number(pos1)
|
||||
local cn = mcl_mapgen.get_chunk_number(pos1)
|
||||
chunks[cn] = nil
|
||||
if queue[cn] then
|
||||
for next_obj, _ in pairs(queue[cn]) do
|
||||
|
@ -445,9 +445,9 @@ end
|
|||
|
||||
local function get_lava_level(pos, pos1, pos2)
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
local q = queue[cn] or {}
|
||||
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
|
||||
-- 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 pos2 = add(pos1, mcl_vars.chunk_size_in_nodes - 1)
|
||||
local pos1 = add(mul(mcl_mapgen.pos_to_chunk(pos), mcl_mapgen.CS_NODES), mcl_mapgen.OFFSET_NODES)
|
||||
local pos2 = add(pos1, mcl_mapgen.CS_NODES - 1)
|
||||
|
||||
if not SCAN_2_MAP_CHUNKS 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
|
||||
|
||||
-- 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_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1)
|
||||
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_mapgen.CS_NODES - 1)
|
||||
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
|
||||
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
|
@ -1,4 +1,4 @@
|
|||
name = mcl_biomes
|
||||
author = maikerumine
|
||||
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
|
||||
|
|
|
@ -2,10 +2,8 @@
|
|||
|
||||
mcl_dungeons = {}
|
||||
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
|
||||
-- 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
|
||||
end
|
||||
|
||||
|
@ -16,7 +14,6 @@ local swap_node = minetest.swap_node
|
|||
local set_node = minetest.set_node
|
||||
local dir_to_facedir = minetest.dir_to_facedir
|
||||
local get_meta = minetest.get_meta
|
||||
local emerge_area = minetest.emerge_area
|
||||
|
||||
--vector
|
||||
local vector_add = vector.add
|
||||
|
@ -32,15 +29,15 @@ local math_max = math.max
|
|||
local math_ceil = math.ceil
|
||||
|
||||
--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 max_y = mcl_vars.mg_overworld_max - 1
|
||||
local min_y = math_max(mcl_mapgen.overworld.min, mcl_mapgen.overworld.bedrock_max) + 1
|
||||
local max_y = mcl_mapgen.overworld.max - 1
|
||||
-- Calculate the number of dungeon spawn attempts
|
||||
-- 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.
|
||||
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 = {
|
||||
{ x=5, y=4, z=5},
|
||||
|
@ -63,12 +60,14 @@ local surround_vectors = {
|
|||
{ x=0, y=0, z=1 },
|
||||
}
|
||||
|
||||
local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||
if calls_remaining >= 1 then return end
|
||||
--local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param)
|
||||
-- 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 check = not (param.dontcheck or false)
|
||||
local check = not (dontcheck or false)
|
||||
|
||||
-- Check floor and ceiling: Must be *completely* solid
|
||||
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.
|
||||
if mg_name == "v6" then
|
||||
if mcl_mapgen.v6 then
|
||||
table_insert(loottable, {
|
||||
stacks_min = 1,
|
||||
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 p1 = {x=x,y=y,z=z}
|
||||
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))
|
||||
emerge_area(p1, p2, ecb_spawn_dungeon, {p1=p1, p2=p2, dim=dim, pr=pr})
|
||||
spawn_dungeon(p1, p2, dim, pr)
|
||||
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
|
||||
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}
|
||||
minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2))
|
||||
emerge_area(p1, p2, ecb_spawn_dungeon, {p1=p1, p2=p2, dim=dim, pr=pr, dontcheck=true})
|
||||
spawn_dungeon(p1, p2, dim, pr, true)
|
||||
end
|
||||
|
||||
mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999)
|
||||
mcl_mapgen.register_chunk_generator(dungeons_nodes, mcl_mapgen.priorities.DUNGEONS)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_dungeons
|
||||
author = Wuzzy
|
||||
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
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
mcl_mapgen_core = {}
|
||||
local registered_generators = {}
|
||||
|
||||
local lvm, nodes, param2 = 0, 0, 0
|
||||
local lvm_buffer = {}
|
||||
|
||||
--
|
||||
-- Aliases for map generator outputs
|
||||
|
@ -101,8 +97,8 @@ for s=1, #specialstones do
|
|||
clust_scarcity = 15*15*15,
|
||||
clust_num_ores = 33,
|
||||
clust_size = 5,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
noise_params = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
|
@ -121,8 +117,8 @@ for s=1, #specialstones do
|
|||
clust_scarcity = 10*10*10,
|
||||
clust_num_ores = 58,
|
||||
clust_size = 7,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
noise_params = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
|
@ -146,8 +142,8 @@ minetest.register_ore({
|
|||
clust_scarcity = 15*15*15,
|
||||
clust_num_ores = 33,
|
||||
clust_size = 4,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
noise_params = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
|
@ -168,7 +164,7 @@ minetest.register_ore({
|
|||
clust_scarcity = 14*14*14,
|
||||
clust_num_ores = 33,
|
||||
clust_size = 5,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_worlds.layer_to_y(111),
|
||||
noise_params = {
|
||||
offset = 0,
|
||||
|
@ -195,7 +191,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 525*3,
|
||||
clust_num_ores = 5,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_worlds.layer_to_y(50),
|
||||
})
|
||||
minetest.register_ore({
|
||||
|
@ -205,7 +201,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 510*3,
|
||||
clust_num_ores = 8,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_worlds.layer_to_y(50),
|
||||
})
|
||||
minetest.register_ore({
|
||||
|
@ -215,7 +211,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 500*3,
|
||||
clust_num_ores = 12,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
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_num_ores = 5,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_worlds.layer_to_y(39),
|
||||
})
|
||||
minetest.register_ore({
|
||||
|
@ -319,7 +315,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 4775,
|
||||
clust_num_ores = 5,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_worlds.layer_to_y(30),
|
||||
})
|
||||
minetest.register_ore({
|
||||
|
@ -329,7 +325,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 6560,
|
||||
clust_num_ores = 7,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
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_num_ores = 4,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_worlds.layer_to_y(12),
|
||||
})
|
||||
minetest.register_ore({
|
||||
|
@ -367,7 +363,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 5000,
|
||||
clust_num_ores = 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),
|
||||
})
|
||||
minetest.register_ore({
|
||||
|
@ -377,7 +373,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 10000,
|
||||
clust_num_ores = 8,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
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_num_ores = 4,
|
||||
clust_size = 3,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
y_max = mcl_worlds.layer_to_y(13),
|
||||
})
|
||||
minetest.register_ore({
|
||||
|
@ -425,7 +421,7 @@ if minetest.settings:get_bool("mcl_generate_ores", true) then
|
|||
clust_scarcity = 800,
|
||||
clust_num_ores = 7,
|
||||
clust_size = 4,
|
||||
y_min = mcl_vars.mg_overworld_min,
|
||||
y_min = mcl_mapgen.overworld.min,
|
||||
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_num_ores = 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),
|
||||
})
|
||||
-- Rare spawn
|
||||
|
@ -682,7 +678,7 @@ local function register_mgv6_decorations()
|
|||
persist = 0.6
|
||||
},
|
||||
y_min = 4,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
decoration = "mcl_core:cactus",
|
||||
height = 1,
|
||||
height_max = 3,
|
||||
|
@ -702,7 +698,7 @@ local function register_mgv6_decorations()
|
|||
persist = 0.7
|
||||
},
|
||||
y_min = 1,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
decoration = "mcl_core:reeds",
|
||||
height = 1,
|
||||
height_max = 3,
|
||||
|
@ -732,7 +728,7 @@ local function register_mgv6_decorations()
|
|||
persist = 0.0,
|
||||
},
|
||||
y_min = 1,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
})
|
||||
|
||||
-- Large ferns
|
||||
|
@ -761,7 +757,7 @@ local function register_mgv6_decorations()
|
|||
persist = 0.66,
|
||||
},
|
||||
y_min = 1,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
})
|
||||
|
||||
-- Large flowers
|
||||
|
@ -1010,7 +1006,7 @@ local function register_mgv6_decorations()
|
|||
persist = 0.666
|
||||
},
|
||||
flags = "force_placement",
|
||||
y_min = mcl_vars.mg_lava_overworld_max + 5,
|
||||
y_min = mcl_mapgen.overworld.lava_max + 5,
|
||||
y_max = -20,
|
||||
})
|
||||
|
||||
|
@ -1042,7 +1038,7 @@ local function register_mgv6_decorations()
|
|||
persist = 0.6
|
||||
},
|
||||
y_min = 1,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
decoration = mushrooms[m],
|
||||
spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", },
|
||||
num_spawn_by = 1,
|
||||
|
@ -1063,7 +1059,7 @@ local function register_mgv6_decorations()
|
|||
persist = 0.6
|
||||
},
|
||||
y_min = 4,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
decoration = "mcl_core:deadbush",
|
||||
})
|
||||
|
||||
|
@ -1072,7 +1068,7 @@ local function register_mgv6_decorations()
|
|||
offset = 0
|
||||
end
|
||||
if y_max == nil then
|
||||
y_max = mcl_vars.mg_overworld_max
|
||||
y_max = mcl_mapgen.overworld.max
|
||||
end
|
||||
minetest.register_decoration({
|
||||
deco_type = "simple",
|
||||
|
@ -1115,7 +1111,7 @@ local function register_mgv6_decorations()
|
|||
sidelen = 16,
|
||||
fill_ratio = 11.0, -- complete coverage
|
||||
y_min = 1,
|
||||
y_max = mcl_vars.mg_overworld_max,
|
||||
y_max = mcl_mapgen.overworld.max,
|
||||
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_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.
|
||||
if maxp.y < -5 or minp.y > 0 then
|
||||
return lvm_used
|
||||
return c
|
||||
end
|
||||
minetest.log("warning", "CLAY!")
|
||||
|
||||
local pr = PseudoRandom(blockseed)
|
||||
|
||||
|
@ -1244,8 +1243,9 @@ local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_
|
|||
end
|
||||
end
|
||||
end
|
||||
return lvm_used
|
||||
end
|
||||
c.write = lvm_used
|
||||
return c
|
||||
end)
|
||||
|
||||
local function generate_end_exit_portal(pos)
|
||||
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)
|
||||
-- Generate rare underground mushrooms
|
||||
-- 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
|
||||
return
|
||||
end
|
||||
|
@ -1757,7 +1757,7 @@ end
|
|||
local function generate_nether_decorations(minp, maxp, seed)
|
||||
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
|
||||
end
|
||||
|
||||
|
@ -1819,92 +1819,6 @@ local function generate_nether_decorations(minp, maxp, seed)
|
|||
|
||||
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.
|
||||
-- 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
|
||||
|
||||
-- Below the bedrock, generate air/void
|
||||
local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
||||
local biomemap --ymin, ymax
|
||||
local function basic(c)
|
||||
local vm, data, emin, emax, area, minp, maxp, blockseed = c.vm, c.data, c.emin, c.emax, c.area, c.minp, c.maxp, c.blockseed
|
||||
c.data2 = c.data2 or vm:get_data_param2(lvm_buffer_param2)
|
||||
local data2 = c.data2
|
||||
|
||||
local lvm_used = false
|
||||
local pr = PseudoRandom(blockseed)
|
||||
|
||||
-- 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
|
||||
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:
|
||||
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:
|
||||
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
|
||||
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:
|
||||
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
|
||||
|
@ -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
|
||||
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_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_lava, c_air, mcl_mapgen.overworld.min, mcl_mapgen.overworld.lava_max, minp, maxp, lvm_used, pr)
|
||||
lvm_used = set_layers(data, area, c_nether_lava, c_air, mcl_mapgen.nether.min, mcl_vars.mg_lava_nether_max, minp, maxp, lvm_used, pr)
|
||||
end
|
||||
|
||||
-- Clay, vines, cocoas
|
||||
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)
|
||||
|
||||
----- 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
|
||||
-- and fixes floating sand and cut plants.
|
||||
-- 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:
|
||||
if mg_name == "v6" then
|
||||
|
||||
|
@ -2101,7 +2019,7 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
|||
-- Nether block fixes:
|
||||
-- * Replace water with Nether lava.
|
||||
-- * 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
|
||||
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
|
||||
|
@ -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).
|
||||
-- * Remove stone, sand, dirt in v6 so our End map generator works in v6.
|
||||
-- * 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
|
||||
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"})
|
||||
|
@ -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.
|
||||
-- -26912 is at a mapchunk border.
|
||||
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})
|
||||
lvm_used = true
|
||||
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
|
||||
lvm_used = true
|
||||
end
|
||||
|
@ -2189,5 +2107,5 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed)
|
|||
return lvm_used, shadow
|
||||
end
|
||||
|
||||
mcl_mapgen_core.register_generator("main", basic, nil, 1, true)
|
||||
mcl_mapgen.register_chunk_generator_lvm(basic, 1)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name = mcl_mapgen_core
|
||||
author = Wuzzy
|
||||
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
|
||||
|
|
|
@ -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)
|
|
@ -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
|
Binary file not shown.
|
@ -18,8 +18,7 @@ local stronghold_rings = {
|
|||
local strongholds = {}
|
||||
local strongholds_inited = false
|
||||
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true"
|
||||
local superflat = mcl_mapgen.superflat
|
||||
|
||||
-- Determine the stronghold positions and store them into the strongholds table.
|
||||
-- The stronghold positions are based on the world seed.
|
||||
|
@ -30,7 +29,7 @@ local function init_strongholds()
|
|||
return
|
||||
end
|
||||
-- Don't generate strongholds in singlenode
|
||||
if mg_name == "singlenode" then
|
||||
if mcl_mapgen.singlenode then
|
||||
strongholds_inited = true
|
||||
return
|
||||
end
|
||||
|
@ -47,9 +46,9 @@ local function init_strongholds()
|
|||
local dist = pr:next(ring.min, ring.max)
|
||||
local y
|
||||
if superflat then
|
||||
y = mcl_vars.mg_bedrock_overworld_max + 3
|
||||
y = mcl_mapgen.overworld.bedrock_max + 3
|
||||
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
|
||||
local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist }
|
||||
pos = vector.round(pos)
|
||||
|
@ -66,8 +65,10 @@ local function init_strongholds()
|
|||
strongholds_inited = true
|
||||
end
|
||||
|
||||
init_strongholds()
|
||||
|
||||
-- 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)
|
||||
for s=1, #strongholds do
|
||||
if not strongholds[s].generated then
|
||||
|
@ -99,8 +100,4 @@ local function generate_strongholds(minp, maxp, blockseed)
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
init_strongholds()
|
||||
|
||||
mcl_mapgen_core.register_generator("strongholds", nil, generate_strongholds, 999999)
|
||||
end, mcl_mapgen.priorities.STRONGHOLDS)
|
||||
|
|
|
@ -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}
|
||||
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}
|
||||
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
|
||||
|
||||
|
@ -115,14 +117,14 @@ function mcl_structures.generate_igloo(pos, rotation, pr)
|
|||
if r == 1 then
|
||||
-- Select basement depth
|
||||
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
|
||||
if dim == "nether" then
|
||||
buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10)
|
||||
elseif dim == "end" then
|
||||
buffer = pos.y - (mcl_vars.mg_end_min + 1)
|
||||
elseif dim == "overworld" then
|
||||
buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10)
|
||||
buffer = pos.y - (mcl_mapgen.overworld.lava_max + 10)
|
||||
else
|
||||
return success
|
||||
end
|
||||
|
@ -284,7 +286,7 @@ local function hut_placement_callback(p1, p2, size, orientation, pr)
|
|||
if not p1 or not p2 then return end
|
||||
local legs = minetest.find_nodes_in_area(p1, p2, "mcl_core:tree")
|
||||
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
|
||||
minetest.swap_node(legs[i], {name = "mcl_core:tree", param2 = 2})
|
||||
end
|
||||
|
|
|
@ -88,7 +88,7 @@ function settlements.create_site_plan(maxp, minp, pr)
|
|||
-- find center_surface of chunk
|
||||
local center_surface , surface_material = settlements.find_surface(center, true)
|
||||
local chunks = {}
|
||||
chunks[mcl_vars.get_chunk_number(center)] = true
|
||||
chunks[mcl_mapgen.get_chunk_number(center)] = true
|
||||
|
||||
-- go build settlement around center
|
||||
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)
|
||||
ptz = settlements.round(ptz, 0)
|
||||
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
|
||||
if chunks[chunk_number] then
|
||||
pos_surface, surface_material = settlements.find_surface(pos1)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
settlements = {}
|
||||
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.."/utils.lua")
|
||||
dofile(settlements.modpath.."/foundation.lua")
|
||||
|
@ -53,6 +55,7 @@ end
|
|||
-- on map generation, try to build a settlement
|
||||
--
|
||||
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)
|
||||
|
||||
-- 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)
|
||||
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.
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
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
|
||||
if maxp.y < 0 then return end
|
||||
-- randomly try to build settlements
|
||||
if blockseed % 77 ~= 17 then return end
|
||||
-- needed for manual and automated settlement building
|
||||
|
||||
-- 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
|
||||
|
||||
local param={minp=vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed}
|
||||
minetest.emerge_area(minp, maxp, ecb_village, param)
|
||||
end)
|
||||
build_a_settlement(minp, maxp, blockseed)
|
||||
end, mcl_mapgen.priorities.VILLAGES)
|
||||
end
|
||||
-- manually place villages
|
||||
if minetest.is_creative_enabled("") then
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
local get_node = mcl_vars.get_node
|
||||
local get_node = mcl_mapgen.get_far_node
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- function to copy tables
|
||||
|
@ -207,44 +207,6 @@ function shuffle(tbl, pr)
|
|||
return table
|
||||
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
|
||||
-- https://stackoverflow.com/questions/656199/search-for-an-item-in-a-lua-list
|
||||
-------------------------------------------------------------------------------
|
||||
|
|
|
@ -19,8 +19,7 @@ end
|
|||
local probability_railcaves_in_mapchunk = P(0.33333)
|
||||
setting = tonumber(minetest.settings:get("tsm_railcorridors_probability_railcaves_in_mapchunk"))
|
||||
-- Extra check to prevent mod griefing in singlenode, mcimported worlds.
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
if mg_name == "singlenode" then
|
||||
if mcl_mapgen.singlenode then
|
||||
probability_railcaves_in_mapchunk = P(0)
|
||||
elseif setting then
|
||||
probability_railcaves_in_mapchunk = P(setting)
|
||||
|
@ -96,10 +95,10 @@ end
|
|||
|
||||
-- Max. and min. heights between rail corridors are generated
|
||||
local height_min
|
||||
if mcl_vars.mg_lava then
|
||||
height_min = mcl_vars.mg_lava_overworld_max + 2
|
||||
if mcl_mapgen.lava then
|
||||
height_min = mcl_mapgen.overworld.lava_max + 2
|
||||
else
|
||||
height_min = mcl_vars.mg_bedrock_overworld_max + 2
|
||||
height_min = mcl_mapgen.overworld.bedrock_max + 2
|
||||
end
|
||||
local height_max = mcl_worlds.layer_to_y(60)
|
||||
|
||||
|
@ -1093,7 +1092,7 @@ local function create_corridor_system(main_cave_coords)
|
|||
end
|
||||
|
||||
-- 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 can't use the mapgen seed as this would make the algorithm depending on the order the mapchunk generate.
|
||||
InitRandomizer(blockseed)
|
||||
|
|
|
@ -8,33 +8,6 @@ minetest.register_craft({
|
|||
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({
|
||||
output = "mcl_armor:helmet_chain",
|
||||
recipe = {
|
||||
|
|
|
@ -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 emerge_pos1, emerge_pos2
|
||||
|
||||
local spawn_limit = mcl_vars.mapgen_edge_max
|
||||
local spawn_limit = mcl_mapgen.EDGE_MAX
|
||||
|
||||
|
||||
--Functions
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
name = mcl_spawn
|
||||
author = Wuzzy
|
||||
description = Set and get the player's respawn position
|
||||
depends = mcl_init
|
||||
depends = mcl_mapgen
|
||||
|
|
Loading…
Reference in New Issue