First (non-functional) cut at the layer wrapping code. Added some

additional hooks to control the core, overriding bedrock and
skyrock generation. Shadow caster can now be enabled/ disabled.
This commit is contained in:
evrooije 2018-07-28 20:45:53 +02:00
parent e369d9ceab
commit e29ad477ea
7 changed files with 276 additions and 25 deletions

View File

@ -2,6 +2,7 @@
multi_map.number_of_layers = 24 -- How may layers to generate multi_map.number_of_layers = 24 -- How may layers to generate
multi_map.layers_start_chunk = 0 -- Y level where to start generating layers, in chunks multi_map.layers_start_chunk = 0 -- Y level where to start generating layers, in chunks
multi_map.layer_height_chunks = 32 -- Height of each layer, in chunks multi_map.layer_height_chunks = 32 -- Height of each layer, in chunks
multi_map.wrap_layers = false
-- Either MT engine defaults or derived from above values, to be used for more readable calculations -- Either MT engine defaults or derived from above values, to be used for more readable calculations
multi_map.layer_height = nil multi_map.layer_height = nil
@ -17,9 +18,14 @@ multi_map.map_max = 30927
multi_map.bedrock = "multi_map_core:bedrock" -- Node to use to fill the bottom of a layer multi_map.bedrock = "multi_map_core:bedrock" -- Node to use to fill the bottom of a layer
multi_map.skyrock = "multi_map_core:skyrock" -- Node to use to fill the top of a layer multi_map.skyrock = "multi_map_core:skyrock" -- Node to use to fill the top of a layer
-- Whether to generate a bedrock layer under a layer/ skyrock above a layer -- Whether to generate a bedrock layer under a layer/ skyrock above a layer/ shadow caster
-- above undeground mapchunks
multi_map.generate_bedrock = true multi_map.generate_bedrock = true
multi_map.generate_skyrock = 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 generator chains -- Table with generator chains
multi_map.generators = {} multi_map.generators = {}
@ -148,7 +154,9 @@ function multi_map.register_global_2dmap(name, params)
spread = {x=params.spread.x, y=params.spread.y, z=params.spread.z}, spread = {x=params.spread.x, y=params.spread.y, z=params.spread.z},
seed = math.random(-1000000000000, 1000000000000), seed = math.random(-1000000000000, 1000000000000),
octaves = params.octaves, octaves = params.octaves,
persist = params.persist persist = params.persist,
lacunarity = params.lacunarity,
flags = params.flags,
} }
multi_map.global_2d_params[name][i] = new_params multi_map.global_2d_params[name][i] = new_params
end end
@ -159,23 +167,30 @@ end
-- chulenxz = chunk length in 2 dimensions (xz) -- chulenxz = chunk length in 2 dimensions (xz)
-- minposxz = minimum 2D position (xz) -- minposxz = minimum 2D position (xz)
-- current layer = the layer for which to retrieve the map or nil to use multi_map's current layer -- current layer = the layer for which to retrieve the map or nil to use multi_map's current layer
function multi_map.get_global_2dmap_flat(name, chulenxz, minposxz, current_layer) function multi_map.get_global_2dmap_flat(name, chulenxz, minposxz, layer)
if not multi_map.global_2d_map_arrays[name] then if not multi_map.global_2d_map_arrays[name] then
minetest.log("error", "[multi_map] Trying to get an unregistered global 2D map") minetest.log("error", "[multi_map] Trying to get an unregistered global 2D map")
end end
if multi_map.wrap_layers then
if layer then
map_cache[name] = multi_map.get_mixed_2dnoise_flat(name, chulenxz, minposxz, layer)
else
map_cache[name] = multi_map.get_mixed_2dnoise_flat(name, chulenxz, minposxz, multi_map.current_layer)
end
end
if not map_cache[name] then if not map_cache[name] then
if not current_layer then if not layer then
if multi_map.current_layer ~= last_used_layer then if multi_map.current_layer ~= last_used_layer then
multi_map.global_2d_maps[name] = minetest.get_perlin_map(multi_map.global_2d_params[name][multi_map.current_layer], chulenxz) multi_map.global_2d_maps[name] = minetest.get_perlin_map(multi_map.global_2d_params[name][multi_map.current_layer], chulenxz)
end end
map_cache[name] = multi_map.global_2d_maps[name]:get2dMap_flat(minposxz, multi_map.global_2d_map_arrays[name][multi_map.current_layer]) map_cache[name] = multi_map.global_2d_maps[name]:get2dMap_flat(minposxz, multi_map.global_2d_map_arrays[name][multi_map.current_layer])
return map_cache[name]
else else
if current_layer ~= last_used_layer then if layer ~= last_used_layer then
multi_map.global_2d_maps[name] = minetest.get_perlin_map(multi_map.global_2d_params[name][current_layer], chulenxz) multi_map.global_2d_maps[name] = minetest.get_perlin_map(multi_map.global_2d_params[name][layer], chulenxz)
end end
map_cache[name] = multi_map.global_2d_maps[name]:get2dMap_flat(minposxz, multi_map.global_2d_map_arrays[name][current_layer]) map_cache[name] = multi_map.global_2d_maps[name]:get2dMap_flat(minposxz, multi_map.global_2d_map_arrays[name][layer])
end end
end end
@ -405,11 +420,18 @@ minetest.register_on_generated(function(minp, maxp)
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local vm_data = vm:get_data() local vm_data = vm:get_data()
local skip = false
if multi_map.override_bedrock_generator then
skip = multi_map.override_bedrock_generator(multi_map.current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp)
end
if not skip then
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node[multi_map.bedrock]) multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node[multi_map.bedrock])
vm:set_data(vm_data) vm:set_data(vm_data)
vm:calc_lighting(false) vm:calc_lighting(false)
vm:write_to_map(false) vm:write_to_map(false)
end
elseif multi_map.generate_skyrock elseif multi_map.generate_skyrock
and (multi_map.map_min + multi_map.layers_start + (multi_map.layer_height * (multi_map.current_layer + 1)) - 80 == minp.y or 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 multi_map.map_min + multi_map.layers_start + (multi_map.layer_height * (multi_map.current_layer + 1)) - 160 == minp.y
@ -419,12 +441,19 @@ minetest.register_on_generated(function(minp, maxp)
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local vm_data = vm:get_data() local vm_data = vm:get_data()
local skip = false
if multi_map.override_skyrock_generator then
skip = multi_map.override_skyrock_generator(multi_map.current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp)
end
if not skip then
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node[multi_map.skyrock]) 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_lighting({day=15, night=0})
vm:set_data(vm_data) vm:set_data(vm_data)
vm:calc_lighting(false) vm:calc_lighting(false)
vm:write_to_map(false) vm:write_to_map(false)
end
else else
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
@ -432,7 +461,7 @@ minetest.register_on_generated(function(minp, maxp)
local remove_shadow_caster = false local remove_shadow_caster = false
-- Add a temporary stone layer above the chunk to ensure caves are dark -- Add a temporary stone layer above the chunk to ensure caves are dark
if multi_map.get_absolute_centerpoint() >= maxp.y then if multi_map.generate_shadow_caster and multi_map.get_absolute_centerpoint() >= maxp.y then
if vm_data[area:index(minp.x, maxp.y + 1, minp.z)] == multi_map.node["ignore"] then if vm_data[area:index(minp.x, maxp.y + 1, minp.z)] == multi_map.node["ignore"] then
remove_shadow_caster = true 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"]) multi_map.generate_singlenode_plane(minp, maxp, area, vm_data, maxp.y + 1, multi_map.node["multi_map_core:shadow_caster"])

View File

@ -5,6 +5,7 @@ function multi_map.log_state()
minetest.log("action", "[multi_map] - Number of layers: "..multi_map.number_of_layers) minetest.log("action", "[multi_map] - Number of layers: "..multi_map.number_of_layers)
minetest.log("action", "[multi_map] - Layers start at: "..(multi_map.map_min + multi_map.layers_start)) minetest.log("action", "[multi_map] - Layers start at: "..(multi_map.map_min + multi_map.layers_start))
minetest.log("action", "[multi_map] - Layer height: "..multi_map.layer_height) minetest.log("action", "[multi_map] - Layer height: "..multi_map.layer_height)
minetest.log("action", "[multi_map] - Wrap layers: "..tostring(multi_map.wrap_layers))
minetest.log("action", "[multi_map] - HUD enabled: "..tostring(multi_map.hud.enabled)) minetest.log("action", "[multi_map] - HUD enabled: "..tostring(multi_map.hud.enabled))
minetest.log("action", "[multi_map]") minetest.log("action", "[multi_map]")

View File

@ -10,6 +10,7 @@ local multi_map_core_path = minetest.get_modpath("multi_map_core")
-- The various sourced files contain the remainder of the API, the -- The various sourced files contain the remainder of the API, the
-- settings, node definitions and other core/ helper functionality -- settings, node definitions and other core/ helper functionality
dofile(multi_map_core_path.."/core.lua") dofile(multi_map_core_path.."/core.lua")
dofile(multi_map_core_path.."/noise_mixer.lua")
dofile(multi_map_core_path.."/debug.lua") dofile(multi_map_core_path.."/debug.lua")
dofile(multi_map_core_path.."/nodes.lua") dofile(multi_map_core_path.."/nodes.lua")
dofile(multi_map_core_path.."/hud.lua") dofile(multi_map_core_path.."/hud.lua")

View File

@ -0,0 +1,204 @@
multi_map.world_edge = {
NEGATIVE_X = 1,
POSITIVE_X = 2,
NEGATIVE_Z = 3,
POSITIVE_Z = 4,
}
multi_map.linked_layers = {}
function multi_map.register_linked_layer(source_layer, edge, target_layer, link_back)
if not multi_map.linked_layers[source_layer] then
multi_map.linked_layers[source_layer] = {}
end
if not multi_map.linked_layers[target_layer] then
multi_map.linked_layers[target_layer] = {}
end
if link_back == nil then
link_back = true
end
if multi_map.world_edge.NEGATIVE_X == edge then
multi_map.linked_layers[source_layer][multi_map.world_edge.NEGATIVE_X] = target_layer
if link_back then
multi_map.linked_layers[target_layer][multi_map.world_edge.POSITIVE_X] = source_layer
end
elseif multi_map.world_edge.POSITIVE_X == edge then
multi_map.linked_layers[source_layer][multi_map.world_edge.POSITIVE_X] = target_layer
if link_back then
multi_map.linked_layers[target_layer][multi_map.world_edge.NEGATIVE_X] = source_layer
end
elseif multi_map.world_edge.NEGATIVE_Z == edge then
multi_map.linked_layers[source_layer][multi_map.world_edge.NEGATIVE_Z] = target_layer
if link_back then
multi_map.linked_layers[target_layer][multi_map.world_edge.POSITIVE_Z] = source_layer
end
elseif multi_map.world_edge.POSITIVE_Z == edge then
multi_map.linked_layers[source_layer][multi_map.world_edge.POSITIVE_Z] = target_layer
if link_back then
multi_map.linked_layers[target_layer][multi_map.world_edge.NEGATIVE_Z] = source_layer
end
end
end
function multi_map.get_linked_layer(layer, edge)
if multi_map.linked_layers[layer] then
return multi_map.linked_layers[layer][edge]
end
end
function multi_map.get_which_world_edge(pos)
if pos.x < -30912 + 160 then
return multi_map.world_edge.NEGATIVE_X
elseif pos.x > 30927 - 160 then
return multi_map.world_edge.POSITIVE_X
elseif pos.y < -30912 + 160 then
return multi_map.world_edge.NEGATIVE_Z
elseif pos.y > 30927 - 160 then
return multi_map.world_edge.POSITIVE_Z
else
return nil
end
end
function multi_map.in_mixing_area(pos)
if pos.x < -30912 + 160 or pos.x > 30927 - 160 or
pos.y < -30912 + 160 or pos.y > 30927 - 160 then
return true
else
return false
end
end
function multi_map.in_mirrored_area(pos)
if pos.x < -30912 + 80 or pos.x > 30927 - 80 or
pos.y < -30912 + 80 or pos.y > 30927 - 80 then
return true
else
return false
end
end
-- Current
-- 160 80
-- [ ] [ ]
-- [ L ] [ M ]
-- [ ] [ ]
-- Opposite
-- 0 80
-- [ ] [ ]
-- [ L ] [ M ]
-- [ ] [ ]
function multi_map.get_mixed_2dnoise_flat(name, chulenxz, minposxz, layer)
local edge = multi_map.get_which_world_edge(minposxz)
if edge == nil then
return
end
local target_layer = multi_map.get_linked_layer(layer, edge)
if not target_layer then
return nil
end
local opposite_minposxz = { x = minposxz.x, y = minposxz.y }
if multi_map.in_mirrored_area(minposxz) then
if multi_map.world_edge.NEGATIVE_X == edge then
opposite_minposxz.x = 30927 - 160
elseif multi_map.world_edge.POSITIVE_X == edge then
opposite_minposxz.x = -30912 + 160
elseif multi_map.world_edge.NEGATIVE_Z == edge then
opposite_minposxz.y = 30927 - 160
elseif multi_map.world_edge.POSITIVE_Z == edge then
opposite_minposxz.y = -30912 + 160
end
local noise1 = minetest.get_perlin_map(multi_map.global_2d_params[name][layer], chulenxz)
local noise2 = minetest.get_perlin_map(multi_map.global_2d_params[name][target_layer], chulenxz)
local map1 = noise1:get2dMap_flat(minposxz)
local map2 = noise2:get2dMap_flat(opposite_minposxz)
if multi_map.world_edge.NEGATIVE_X == edge then
return multi_map.mix_noise_map_x(map1, map2, opposite_minposxz)
elseif multi_map.world_edge.POSITIVE_X == edge then
return multi_map.mix_noise_map_x(map2, map1, opposite_minposxz)
elseif multi_map.world_edge.NEGATIVE_Z == edge then
return multi_map.mix_noise_map_z(map1, map2, opposite_minposxz)
elseif multi_map.world_edge.POSITIVE_Z == edge then
return multi_map.mix_noise_map_x(map2, map1, opposite_minposxz)
end
elseif multi_map.in_mixing_area(minposxz) then
if multi_map.world_edge.NEGATIVE_X == edge then
opposite_minposxz.x = 30927 - 80
elseif multi_map.world_edge.POSITIVE_X == edge then
opposite_minposxz.x = -30912 + 80
elseif multi_map.world_edge.NEGATIVE_Z == edge then
opposite_minposxz.y = 30927 - 80
elseif multi_map.world_edge.POSITIVE_Z == edge then
opposite_minposxz.y = -30912 + 80
end
local noise1 = minetest.get_perlin_map(multi_map.global_2d_params[name][layer], chulenxz)
local noise2 = minetest.get_perlin_map(multi_map.global_2d_params[name][target_layer], chulenxz)
local map1 = noise1:get2dMap_flat(minposxz)
local map2 = noise2:get2dMap_flat(opposite_minposxz)
if multi_map.world_edge.NEGATIVE_X == edge then
return multi_map.mix_noise_map_x(map2, map1, minposxz)
elseif multi_map.world_edge.POSITIVE_X == edge then
return multi_map.mix_noise_map_x(map1, map2, minposxz)
elseif multi_map.world_edge.NEGATIVE_Z == edge then
return multi_map.mix_noise_map_z(map2, map1, minposxz)
elseif multi_map.world_edge.POSITIVE_Z == edge then
return multi_map.mix_noise_map_x(map1, map2, minposxz)
end
else
return nil
end
end
function multi_map.mix_noise_map_x(map1, map2, minposxz)
local new_map = {}
local nixz = 1
for y = minposxz.y, minposxz.y + 79 do
local weight_index = 1
for x = minposxz.x, minposxz.x + 79 do
new_map[nixz] = ( map1[nixz] * (1 - (weight_index / 80)) ) + ( map2[nixz] * (weight_index / 80) )
nixz = nixz + 1
weight_index = weight_index + 1
end
end
return new_map
end
function multi_map.mix_noise_map_z(map1, map2, minposxz)
local new_map = {}
local nixz = 1
for y = minposxz.y, minposxz.y + 80 do
local weight_index = 1
for x = minposxz.x, minposxz.x + 80 do
new_map[nixz] = ( map1[nixz] * (1 - (weight_index / 160)) ) + ( map2[nixz] * (weight_index / 160) )
nixz = nixz + 1
end
weight_index = weight_index + 1
nixz = nixz - 80
end
return new_map
end

View File

@ -3,7 +3,7 @@ local multi_map_generators_path = minetest.get_modpath("multi_map_generators")
dofile(multi_map_generators_path.."/mmgen_levels.lua") dofile(multi_map_generators_path.."/mmgen_levels.lua")
--dofile(multi_map_generators_path.."/mmgen_lvm_example.lua") --dofile(multi_map_generators_path.."/mmgen_lvm_example.lua")
dofile(multi_map_generators_path.."/mmgen_simple.lua") dofile(multi_map_generators_path.."/mmgen_simple.lua")
--dofile(multi_map_generators_path.."/mmgen_testauri.lua") dofile(multi_map_generators_path.."/mmgen_testauri.lua")
--multi_map.register_fallback_generator("Default Simple", mmgen_simple.generate) --multi_map.register_fallback_generator("Default Simple", mmgen_simple.generate)
--multi_map.register_generator(9, mmgen_simple.generate, "default:sandstone") --multi_map.register_generator(9, mmgen_simple.generate, "default:sandstone")
@ -16,8 +16,19 @@ dofile(multi_map_generators_path.."/mmgen_simple.lua")
multi_map.number_of_layers = 38 multi_map.number_of_layers = 38
multi_map.layers_start_chunk = 0 multi_map.layers_start_chunk = 0
multi_map.layer_height_chunks = 20 multi_map.layer_height_chunks = 20
multi_map.wrap_layers = true
multi_map.register_fallback_generator("Default Levels", mmgen_levels.generate) multi_map.register_fallback_generator(mmgen_simple.generate)
multi_map.register_generator(19, mmgen_levels.generate) multi_map.register_generator(18, mmgen_testauri.generate)
multi_map.set_layer_name(19, "Central Layer") multi_map.register_generator(19, mmgen_testauri.generate)
multi_map.set_layer_name(20, "Remote Levels Land") multi_map.register_generator(20, mmgen_testauri.generate)
--multi_map.register_linked_layer(19, multi_map.world_edge.POSITIVE_X, 20, true)
--multi_map.register_linked_layer(19, multi_map.world_edge.NEGATIVE_X, 18, true)
--multi_map.register_generator(9, mmgen_simple.generate, { nodetype = "default:sandstone", height = 0 })
--multi_map.register_generator(9, mmgen_simple.generate, { nodetype = "default:sandstone", height = 1 })
--multi_map.register_fallback_generator("Default Levels", mmgen_levels.generate)
--multi_map.register_generator(19, mmgen_levels.generate)
--multi_map.set_layer_name(19, "Central Layer")
--multi_map.set_layer_name(20, "Remote Levels Land")

View File

@ -1,6 +1,10 @@
mmgen_simple = {} mmgen_simple = {}
function mmgen_simple.generate(current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp, nodetype) 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 c_ground local c_ground
if nodetype then if nodetype then
c_ground = multi_map.node[nodetype] c_ground = multi_map.node[nodetype]
@ -8,7 +12,7 @@ function mmgen_simple.generate(current_layer, vm, area, vm_data, minp, maxp, off
c_ground = multi_map.node["default:stone"] c_ground = multi_map.node["default:stone"]
end end
if offset_minp.y >= 0 then if offset_minp.y >= height then
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node["air"]) multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node["air"])
else else
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, c_ground) multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, c_ground)

View File

@ -93,6 +93,7 @@ local perlin_worm_start_params = {
function mmgen_testauri.generate(current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp) function mmgen_testauri.generate(current_layer, vm, area, vm_data, minp, maxp, offset_minp, offset_maxp)
local sidelen = maxp.x - minp.x + 1 local sidelen = maxp.x - minp.x + 1
local blocklen = sidelen / 5 local blocklen = sidelen / 5
--3d --3d
local chulenxyz = {x = sidelen, y = sidelen, z = sidelen} local chulenxyz = {x = sidelen, y = sidelen, z = sidelen}
--2d --2d