diff --git a/multi_map_core/core.lua b/multi_map_core/core.lua index c9eb4c4..d48f4ad 100644 --- a/multi_map_core/core.lua +++ b/multi_map_core/core.lua @@ -24,14 +24,12 @@ multi_map.generate_bedrock = true multi_map.generate_skyrock = true multi_map.generate_shadow_caster = true -multi_map.override_bedrock_generator = nil -multi_map.override_skyrock_generator = nil - +-- Table with layer specific configuration +multi_map.layers = {} -- Table with generator chains multi_map.generators = {} -- When no suitable generator is found, this generator is used as a fallback multi_map.fallback_generator = nil -multi_map.layer_names = {} -- Set the current layer which the mapgen is generating -- y = absolute y value to be translated to layer @@ -63,8 +61,8 @@ end -- y = absolute y value to be translated to layer function multi_map.get_layer_name_y(y) local l = multi_map.get_layer(y) - if l then - return multi_map.layer_names[l] + if l and multi_map.layers[l] and multi_map.layers[l].name then + return multi_map.layers[l].name else return tostring(l) end @@ -263,6 +261,10 @@ function multi_map.register_fallback_generator(...) multi_map.fallback_generator = { name = name, generator = generator, arguments = arguments } end +function multi_map.set_layer_params(layer, layer_params) + multi_map.layers[layer] = layer_params +end + -- Register a generator for all if position is left out or one layer if position is specified -- position = the optional layer for which call this generator -- generator = the function to call @@ -308,18 +310,11 @@ function multi_map.register_generator(...) end end --- Set a nice name for this layer, e.g. to use for display on the HUD --- layer = the layer number --- name = the name to give to this layer -function multi_map.set_layer_name(layer, name) - multi_map.layer_names[layer] = name -end - -- Get the layer name, e.g. to use for display on the HUD -- layer = the layer number function multi_map.get_layer_name(layer) - if multi_map.layer_names[layer] then - return multi_map.layer_names[layer] + if multi_map.layers[layer] and multi_map.layers[layer].name then + return multi_map.layers[layer].name elseif multi_map.fallback_generator then return multi_map.fallback_generator.name end @@ -404,23 +399,56 @@ minetest.register_on_generated(function(minp, maxp) local offset_minp = { x = minp.x, y = multi_map.get_offset_y(minp.y), z = minp.z } local offset_maxp = { x = maxp.x, y = multi_map.get_offset_y(maxp.y), z = maxp.z } - if multi_map.generate_bedrock and + local generate_bedrock = multi_map.generate_bedrock + local generate_skyrock = multi_map.generate_skyrock + + if multi_map.generate_bedrock then + if multi_map.layers[multi_map.current_layer] and + not multi_map.layers[multi_map.current_layer].generate_bedrock + then + generate_bedrock = false + end + else + if multi_map.layers[multi_map.current_layer] and + multi_map.layers[multi_map.current_layer].generate_bedrock + then + generate_bedrock = true + end + end + + if multi_map.generate_skyrock then + if multi_map.layers[multi_map.current_layer] and + not multi_map.layers[multi_map.current_layer].generate_skyrock + then + generate_skyrock = false + end + else + if multi_map.layers[multi_map.current_layer] and + multi_map.layers[multi_map.current_layer].generate_skyrock + then + generate_skyrock = true + end + end + + if generate_bedrock and multi_map.map_min + multi_map.layers_start + (multi_map.layer_height * multi_map.current_layer) == minp.y then local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local vm_data = vm:get_data() - if multi_map.override_bedrock_generator then - multi_map.override_bedrock_generator(multi_map.current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp) + if multi_map.layers[multi_map.current_layer] and + multi_map.layers[multi_map.current_layer].bedrock_generator + then + multi_map.layers[multi_map.current_layer].bedrock_generator(multi_map.current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp) else multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node[multi_map.bedrock]) - - vm:set_data(vm_data) - vm:calc_lighting(false) - vm:write_to_map(false) end - elseif multi_map.generate_skyrock + vm:set_data(vm_data) + vm:calc_lighting(false) + vm:write_to_map(false) + + elseif generate_skyrock and (multi_map.map_min + multi_map.layers_start + (multi_map.layer_height * (multi_map.current_layer + 1)) - 80 == minp.y or multi_map.map_min + multi_map.layers_start + (multi_map.layer_height * (multi_map.current_layer + 1)) - 160 == minp.y ) @@ -429,16 +457,18 @@ minetest.register_on_generated(function(minp, maxp) local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local vm_data = vm:get_data() - if multi_map.override_skyrock_generator then - multi_map.override_skyrock_generator(multi_map.current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp) + if multi_map.layers[multi_map.current_layer] and + multi_map.layers[multi_map.current_layer].skyrock_generator + then + multi_map.layers[multi_map.current_layer].skyrock_generator(multi_map.current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp) else multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node[multi_map.skyrock]) - - vm:set_lighting({day=15, night=0}) - vm:set_data(vm_data) - vm:calc_lighting(false) - vm:write_to_map(false) end + vm:set_lighting({day=15, night=0}) + vm:set_data(vm_data) + vm:calc_lighting(false) + vm:write_to_map(false) + elseif multi_map.wrap_layers and multi_map.in_skip_area({ x = minp.x, y = minp.z }) then local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) @@ -453,8 +483,10 @@ minetest.register_on_generated(function(minp, maxp) local vm_data = vm:get_data() local remove_shadow_caster = false - -- Add a temporary stone layer above the chunk to ensure caves are dark - if multi_map.generate_shadow_caster and multi_map.get_absolute_centerpoint() >= maxp.y then + -- Add a temporary shadow caster layer above the chunk to ensure caves are dark + if (multi_map.generate_shadow_caster and multi_map.get_absolute_centerpoint() >= maxp.y) or + (multi_map.layers[multi_map.current_layer] and multi_map.layers[multi_map.current_layer].generate_shadow_caster) + then if vm_data[area:index(minp.x, maxp.y + 1, minp.z)] == multi_map.node["ignore"] then remove_shadow_caster = true multi_map.generate_singlenode_plane(minp, maxp, area, vm_data, maxp.y + 1, multi_map.node["multi_map_core:shadow_caster"]) diff --git a/multi_map_core/debug.lua b/multi_map_core/debug.lua index ffb1009..82b3c26 100644 --- a/multi_map_core/debug.lua +++ b/multi_map_core/debug.lua @@ -20,7 +20,11 @@ function multi_map.log_state() minetest.log("action", "[multi_map] - "..name.." "..debug.getinfo(multi_map.fallback_generator.generator).short_src:match("^.+/(.+)$").." (fallback)") end for k,v in pairs(multi_map.generators) do - local name = multi_map.layer_names[k] + local name + if multi_map.layers[k] and multi_map.layers[k].name then + name = multi_map.layers[k].name + end + if name then name = "\""..name.."\"," else diff --git a/multi_map_core/hud.lua b/multi_map_core/hud.lua index 2941ebb..d96b346 100644 --- a/multi_map_core/hud.lua +++ b/multi_map_core/hud.lua @@ -33,8 +33,8 @@ function multi_map.update_hud(player) local player_name = player:get_player_name() - local layer = multi_map.get_layer(player:get_pos().y) - local offset_y = multi_map.get_offset_y(player:get_pos().y, layer) + local layer = multi_map.get_layer(player:get_pos().y + 0.5) + local offset_y = multi_map.get_offset_y(player:get_pos().y, layer) + 0.5 local hud_text = "" diff --git a/multi_map_core/noise_mixer.lua b/multi_map_core/noise_mixer.lua index a4fc958..63efc54 100644 --- a/multi_map_core/noise_mixer.lua +++ b/multi_map_core/noise_mixer.lua @@ -214,7 +214,7 @@ end local timer = 0 minetest.register_globalstep(function(dtime) timer = timer + dtime; - if timer >= 0.5 then + if timer >= 1 then for _,player in ipairs(minetest.get_connected_players()) do local posxz = { x = player:get_pos().x, y = player:get_pos().z } local edge = multi_map.get_which_world_edge(posxz) diff --git a/multi_map_generators/init.lua b/multi_map_generators/init.lua index ba73b35..538218f 100644 --- a/multi_map_generators/init.lua +++ b/multi_map_generators/init.lua @@ -19,6 +19,18 @@ multi_map.layer_height_chunks = 20 multi_map.wrap_layers = true multi_map.register_fallback_generator(mmgen_simple.generate) + +multi_map.register_generator(0, mmgen_testauri.generate) +multi_map.register_generator(1, mmgen_testauri.generate) + +multi_map.set_layer_params(0, + { name = "Bottom World 1", generate_bedrock = false, generate_skyrock = false, generate_shadow_caster = true }) + +multi_map.set_layer_params(1, + { name = "Bottom World 2", generate_bedrock = false, generate_skyrock = true }) + +multi_map.register_generator(2, mmgen_levels.generate) + multi_map.register_generator(18, mmgen_testauri.generate) multi_map.register_generator(19, mmgen_testauri.generate) multi_map.register_generator(20, mmgen_testauri.generate) diff --git a/multi_map_generators/mmgen_levels.lua b/multi_map_generators/mmgen_levels.lua index fdbdf2f..8b9c0f7 100644 --- a/multi_map_generators/mmgen_levels.lua +++ b/multi_map_generators/mmgen_levels.lua @@ -31,29 +31,32 @@ local LUXCHA = 1 / 9 ^ 3 -- 3D noise -local np_terrain = { - offset = 0, - scale = 1, - spread = {x=384, y=192, z=384}, - seed = 5900033, - octaves = 5, - persist = 0.63, - lacunarity = 2.0, - --flags = "" -} +multi_map.register_global_3dmap( + "terrain", { + offset = 0, + scale = 1, + spread = {x=384, y=192, z=384}, + seed = 5900033, + octaves = 5, + persist = 0.63, + lacunarity = 2.0, + } +) -- 2D noise -local np_spike = { - offset = 0, - scale = 1, - spread = {x=128, y=128, z=128}, - seed = -188900, - octaves = 3, - persist = 0.5, - lacunarity = 2.0, - flags = "noeased" -} +multi_map.register_global_2dmap( + "spike", { + offset = 0, + scale = 1, + spread = {x=128, y=128, z=128}, + seed = -188900, + octaves = 3, + persist = 0.5, + lacunarity = 2.0, + flags = "noeased" + } +) -- Nodes @@ -86,20 +89,12 @@ minetest.register_node("multi_map_generators:luxore", { local floatper = math.pi / FLOATPER --- Set mapgen parameters +-- Generate function -minetest.register_on_mapgen_init(function(mgparams) - minetest.set_mapgen_params({mgname="singlenode", flags="nolight"}) -end) +function mmgen_levels.generate(current_layer, vm, area, data, minp, maxp, offset_minp, offset_maxp, params) --- Initialize noise objects to nil + if not params then params = {} end -local nobj_terrain = nil -local nobj_spike = nil - --- On generated function - -function mmgen_levels.generate(current_layer, vm, area, data, minp, maxp, offset_minp, offset_maxp) local x1 = maxp.x local y1 = maxp.y local z1 = maxp.z @@ -126,11 +121,8 @@ function mmgen_levels.generate(current_layer, vm, area, data, minp, maxp, offset local minpos3d = {x=x0, y=y0-16, z=z0} local minpos2d = {x=x0, y=z0} - nobj_terrain = nobj_terrain or minetest.get_perlin_map(np_terrain, chulens3d) - nobj_spike = nobj_spike or minetest.get_perlin_map(np_spike, chulens2d) - - local nvals_terrain = nobj_terrain:get3dMap_flat(minpos3d) - local nvals_spike = nobj_spike:get2dMap_flat(minpos2d) + local nvals_terrain = multi_map.get_global_3dmap_flat("terrain", chulens3d, minpos3d) + local nvals_spike = multi_map.get_global_2dmap_flat("spike", chulens2d, minpos2d) local ni3d = 1 local ni2d = 1 @@ -153,25 +145,25 @@ function mmgen_levels.generate(current_layer, vm, area, data, minp, maxp, offset local n_terrain = nvals_terrain[ni3d] local n_spike = nvals_spike[ni2d] local spikeoff = 0 - if n_spike > TSPIKE then - spikeoff = (n_spike - TSPIKE) ^ 4 * SPIKEAMP + if n_spike > (params.tspike or TSPIKE) then + spikeoff = (n_spike - (params.tspike or TSPIKE)) ^ 4 * (params.spikeamp or SPIKEAMP) end - local grad = (YSURFCEN - relative_y) / TERSCA + spikeoff - if relative_y > YSURFMAX then + local grad = ((params.ysurfcen or YSURFCEN) - relative_y) / (params.tersca or TERSCA) + spikeoff + if relative_y > (params.ysurfmax or YSURFMAX) then grad = math.max( - -FLOATFAC * math.abs(math.cos((relative_y - YSURFMAX) * floatper)), + (-1 * (params.floatfac or FLOATFAC)) * math.abs(math.cos((relative_y - (params.ysurfmax or YSURFMAX)) * floatper)), grad ) - elseif relative_y < YSURFMIN then + elseif relative_y < (params.ysurfmin or YSURFMIN) then grad = math.min( - UNDERFAC * (relative_y - YUNDERCEN) ^ 2 + UNDEROFF, + (params.underfac or UNDERFAC) * (relative_y - (params.yundercen or YUNDERCEN)) ^ 2 + (params.underoff or UNDEROFF), grad ) end local density = n_terrain + grad if y < y0 then - if density >= TSTONE then + if density >= (params.tstone or TSTONE) then stable[si] = stable[si] + 1 elseif density <= 0 then stable[si] = 0 @@ -187,8 +179,8 @@ function mmgen_levels.generate(current_layer, vm, area, data, minp, maxp, offset end end elseif y >= y0 and y <= y1 then - if density >= TSTONE then - if math.random() < LUXCHA and relative_y < YSURFMIN + if density >= (params.tstone or TSTONE) then + if math.random() < (params.luxcha or LUXCHA) and relative_y < (params.ysurfmin or YSURFMIN) and density < 0.01 and data[viu] == c_stone then data[vi] = c_luxore else @@ -196,20 +188,20 @@ function mmgen_levels.generate(current_layer, vm, area, data, minp, maxp, offset end stable[si] = stable[si] + 1 under[si] = 0 - elseif density > 0 and density < TSTONE - and stable[si] >= STABLE and relative_y > YSURFMIN then - if relative_y <= YSAND then + elseif density > 0 and density < (params.tstone or TSTONE) + and stable[si] >= (params.stable or STABLE) and relative_y > (params.ysurfmin or YSURFMIN) then + if relative_y <= (params.ysand or YSAND) then data[vi] = c_sand under[si] = 0 else data[vi] = c_dirt under[si] = 1 end - elseif relative_y > YSURFMIN and relative_y <= YWATER then + elseif relative_y > (params.ysurfmin or YSURFMIN) and relative_y <= (params.ywater or YWATER) then data[vi] = c_water stable[si] = 0 under[si] = 0 - elseif relative_y <= YLAVA then + elseif relative_y <= (params.ylava or YLAVA) then data[vi] = c_lava stable[si] = 0 under[si] = 0 @@ -221,7 +213,7 @@ function mmgen_levels.generate(current_layer, vm, area, data, minp, maxp, offset under[si] = 0 end elseif y == y1 + 1 then - if density <= 0 and relative_y > YWATER then -- air, possibly just above surface + if density <= 0 and relative_y > (params.ywater or YWATER) then -- air, possibly just above surface if under[si] == 1 then data[viu] = c_grass end diff --git a/multi_map_generators/mmgen_simple.lua b/multi_map_generators/mmgen_simple.lua index bd15bc2..0f46ee6 100644 --- a/multi_map_generators/mmgen_simple.lua +++ b/multi_map_generators/mmgen_simple.lua @@ -2,16 +2,16 @@ mmgen_simple = {} function mmgen_simple.generate(current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp, params) - local nodetype = params.nodetype - local height = params.height + local nodetype = "default:stone" + local height = 0 - local c_ground - if nodetype then - c_ground = multi_map.node[nodetype] - else - c_ground = multi_map.node["default:stone"] + if params and type(params) == "table" then + if params.nodetype then nodetype = params.nodetype end + if params.height then height = params.height end end + local c_ground = multi_map.node[nodetype] + if offset_minp.y >= height then multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node["air"]) else