Full implementation of layer wrapping, noise mixing and noise

mirroring on all edges. Teleportation implemented, also on all
edges.
This commit is contained in:
evrooije 2018-07-31 21:49:32 +02:00
parent e29ad477ea
commit f24d4a3a80
4 changed files with 117 additions and 82 deletions

View File

@ -70,7 +70,6 @@ function multi_map.get_layer_name_y(y)
end
end
-- Get the absolute y center centerpoint for a given layer
-- current_layer = the layer for which to calculate the centerpoint, or if nil the current layer that multi_map is processing
function multi_map.get_absolute_centerpoint(current_layer)
@ -377,17 +376,7 @@ multi_map.node = setmetatable({}, {
-- Simple init, does a sanity check of the settings and sets the mapgen to singlenode
minetest.register_on_mapgen_init(function(mapgen_params)
minetest.set_mapgen_params({mgname="singlenode"})
end)
local firstrun = true
function multi_map.initialized()
return not firstrun
end
-- Here all the magic (or should I say mess...) happens!
minetest.register_on_generated(function(minp, maxp)
if firstrun then
minetest.after(0, function()
multi_map.layer_height = multi_map.layer_height_chunks * 80
multi_map.layers_start = multi_map.layers_start_chunk * 80
multi_map.half_layer_height = multi_map.layer_height / 2
@ -400,9 +389,11 @@ minetest.register_on_generated(function(minp, maxp)
minetest.log("action", "[multi_map] First on_generated call started, module state:")
minetest.log("action", "[multi_map]")
multi_map.log_state()
firstrun = false
end
end)
end)
-- Here all the magic (or should I say mess...) happens!
minetest.register_on_generated(function(minp, maxp)
multi_map.set_current_layer(minp.y)
local sidelen = maxp.x - minp.x + 1
@ -420,12 +411,9 @@ minetest.register_on_generated(function(minp, maxp)
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
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.override_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)
@ -441,12 +429,9 @@ minetest.register_on_generated(function(minp, maxp)
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
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.override_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})
@ -454,6 +439,14 @@ minetest.register_on_generated(function(minp, maxp)
vm:calc_lighting(false)
vm:write_to_map(false)
end
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})
local vm_data = vm:get_data()
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.node["multi_map_core:skyrock"])
vm:set_data(vm_data)
vm:calc_lighting(false)
vm:write_to_map(false)
else
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})

View File

@ -27,7 +27,7 @@ minetest.register_on_leaveplayer(function(player)
end)
function multi_map.update_hud(player)
if not multi_map.hud.enabled or not multi_map.initialized() then
if not multi_map.hud.enabled then
return
end

View File

@ -52,13 +52,13 @@ end
function multi_map.get_which_world_edge(pos)
if pos.x < -30912 + 160 then
if pos.x < -30912 + 240 then
return multi_map.world_edge.NEGATIVE_X
elseif pos.x > 30927 - 160 then
elseif pos.x > 30927 - 240 then
return multi_map.world_edge.POSITIVE_X
elseif pos.y < -30912 + 160 then
elseif pos.y < -30912 + 240 then
return multi_map.world_edge.NEGATIVE_Z
elseif pos.y > 30927 - 160 then
elseif pos.y > 30927 - 240 then
return multi_map.world_edge.POSITIVE_Z
else
return nil
@ -67,33 +67,41 @@ function multi_map.get_which_world_edge(pos)
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
if pos.x > 30927 - 240 or pos.y > 30927 - 240 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
function multi_map.in_mirrored_area_1(pos)
if pos.x > 30927 - 160 or pos.y > 30927 - 160 then
return true
else
return false
end
end
-- Current
-- 160 80
-- [ ] [ ]
-- [ L ] [ M ]
-- [ ] [ ]
-- Opposite
-- 0 80
-- [ ] [ ]
-- [ L ] [ M ]
-- [ ] [ ]
function multi_map.in_mirrored_area_2(pos)
if pos.x > 30927 - 80 or pos.y > 30927 - 80 then
return true
else
return false
end
end
function multi_map.in_skip_area(pos)
if pos.x < -30912 + 80 or pos.y < -30912 + 80 then
return true
else
return false
end
end
-- Normal area Mixed area Mirrored area Teleport area
-- layer 1a (-320) --> layer mixed 1b (-240) and 2a (0) --> layer 1 supressed (-160) layer 2b mirrored (80) --> teleport --> layer 1 supressed (-80) layer 2c mirrored (160)
-- Normal area Normal area Normal area
-- layer 2a (0) air --> layer 2b (80) --> teleport --> layer 2c (160)
function multi_map.get_mixed_2dnoise_flat(name, chulenxz, minposxz, layer)
local edge = multi_map.get_which_world_edge(minposxz)
@ -109,56 +117,57 @@ function multi_map.get_mixed_2dnoise_flat(name, chulenxz, minposxz, layer)
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
if multi_map.in_mirrored_area_2(minposxz) then
if 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
return map2
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
elseif multi_map.in_mirrored_area_1(minposxz) then
if 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)
return map2
elseif multi_map.in_mixing_area(minposxz) then
if multi_map.world_edge.POSITIVE_X == edge then
opposite_minposxz.x = -30912
elseif multi_map.world_edge.POSITIVE_Z == edge then
opposite_minposxz.y = -30912
end
if multi_map.world_edge.NEGATIVE_X == edge then
return multi_map.mix_noise_map_x(map2, map1, minposxz)
local noise2 = minetest.get_perlin_map(multi_map.global_2d_params[name][target_layer], chulenxz)
local map2 = noise2:get2dMap_flat(opposite_minposxz)
return map2
elseif multi_map.world_edge.POSITIVE_X == edge then
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)
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)
local noise2 = minetest.get_perlin_map(multi_map.global_2d_params[name][target_layer], chulenxz)
local map2 = noise2:get2dMap_flat(opposite_minposxz)
return map2
elseif multi_map.world_edge.POSITIVE_Z == edge then
return multi_map.mix_noise_map_x(map1, map2, minposxz)
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)
return multi_map.mix_noise_map_z(map2, map1, minposxz)
end
else
return nil
@ -189,16 +198,49 @@ 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) )
local weight_index = 79
for y = minposxz.y, minposxz.y + 79 do
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
end
weight_index = weight_index + 1
nixz = nixz - 80
weight_index = weight_index - 1
end
return new_map
end
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime;
if timer >= 0.5 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)
if edge then
local layer = multi_map.get_layer(player:get_pos().y)
local target_layer = multi_map.get_linked_layer(layer, edge)
if target_layer then
if posxz.x > 30927 - 79 then
local ydiff = (target_layer - layer) * multi_map.layer_height
player:set_pos({ x = 240 + posxz.x - 61840, y = player:get_pos().y + ydiff, z = player:get_pos().z })
end
if posxz.x < -30912 + 160 then
local ydiff = (target_layer - layer) * multi_map.layer_height
player:set_pos({ x = -240 + posxz.x + 61840, y = player:get_pos().y + ydiff, z = player:get_pos().z })
end
if posxz.y > 30927 - 79 then
local ydiff = (target_layer - layer) * multi_map.layer_height
player:set_pos({ x = player:get_pos().x, y = player:get_pos().y + ydiff, z = 240 + posxz.y - 61840 })
end
if posxz.y < -30912 + 160 then
local ydiff = (target_layer - layer) * multi_map.layer_height
player:set_pos({ x = player:get_pos().x, y = player:get_pos().y + ydiff, z = -240 + posxz.y + 61840 })
end
end
end
end
timer = 0
end
end)

View File

@ -23,8 +23,8 @@ multi_map.register_generator(18, mmgen_testauri.generate)
multi_map.register_generator(19, mmgen_testauri.generate)
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_linked_layer(19, multi_map.world_edge.POSITIVE_Z, 20, true)
multi_map.register_linked_layer(19, multi_map.world_edge.NEGATIVE_Z, 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 })