Created framework for supporting multiple map generators per layer, with
a fallback (or default if need be) generator in case no layer specified generator is found. Added sample/ basis mod to demonstrate registration of map generators. Rewrote Proxima Testauri map generator to conform to multi_map, simple map generator is fallback in demo. Testauri now uses a single noise which increases generation time but reduces memory usage. To try and reduce generation time, it keeps track of the last layer used and based on that will not reinitialize unless the layer changes.
This commit is contained in:
parent
d6d827849d
commit
35d768d79f
|
@ -16,6 +16,7 @@ multi_map.generate_bedrock = true
|
|||
multi_map.generate_skyrock = true
|
||||
|
||||
multi_map.generators = {}
|
||||
multi_map.fallback_generator = nil
|
||||
|
||||
function multi_map.set_current_layer(y)
|
||||
for l = 0, multi_map.number_of_layers do
|
||||
|
@ -32,8 +33,39 @@ function multi_map.get_offset_y(y)
|
|||
return y - center_point
|
||||
end
|
||||
|
||||
function multi_map.append_generator(generator)
|
||||
table.insert(multi_map.generators, generator)
|
||||
function multi_map.register_fallback_generator(generator)
|
||||
multi_map.fallback_generator = generator
|
||||
end
|
||||
|
||||
function multi_map.register_generator(...)
|
||||
local arg = {...}
|
||||
local position
|
||||
local generator
|
||||
|
||||
if arg[2] then
|
||||
position = arg[1]
|
||||
generator = arg[2]
|
||||
else
|
||||
generator = arg[1]
|
||||
end
|
||||
|
||||
if not position then
|
||||
for i = 0, multi_map.number_of_layers - 1 do
|
||||
local t = multi_map.generators[i]
|
||||
if not t then
|
||||
t = {}
|
||||
multi_map.generators[i] = t
|
||||
end
|
||||
table.insert(t, generator)
|
||||
end
|
||||
else
|
||||
local t = multi_map.generators[position]
|
||||
if not t then
|
||||
t = {}
|
||||
multi_map.generators[position] = t
|
||||
end
|
||||
table.insert(t, generator)
|
||||
end
|
||||
end
|
||||
|
||||
function multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, content_id)
|
||||
|
@ -53,11 +85,10 @@ local firstrun = true
|
|||
multi_map.c_stone = nil
|
||||
multi_map.c_air = nil
|
||||
multi_map.c_water = nil
|
||||
multi_map.c_lava = nil
|
||||
multi_map.c_bedrock = nil
|
||||
multi_map.c_skyrock = nil
|
||||
|
||||
minetest.set_mapgen_params({mgname = "singlenode"})
|
||||
|
||||
minetest.register_on_mapgen_init(function(mapgen_params)
|
||||
if multi_map.number_of_layers * multi_map.layer_height > multi_map.map_height then
|
||||
minetest.log("error", "Number of layers for the given layer height exceeds map height!")
|
||||
|
@ -69,6 +100,7 @@ minetest.register_on_generated(function(minp, maxp)
|
|||
multi_map.c_stone = minetest.get_content_id("default:stone")
|
||||
multi_map.c_air = minetest.get_content_id("air")
|
||||
multi_map.c_water = minetest.get_content_id("default:water_source")
|
||||
multi_map.c_lava = minetest.get_content_id("default:lava_source")
|
||||
multi_map.c_bedrock = minetest.get_content_id(multi_map.bedrock)
|
||||
multi_map.c_skyrock = minetest.get_content_id(multi_map.skyrock)
|
||||
firstrun = false
|
||||
|
@ -110,10 +142,20 @@ minetest.register_on_generated(function(minp, maxp)
|
|||
vm:calc_lighting(false)
|
||||
vm:write_to_map(false)
|
||||
else
|
||||
for i,f in ipairs(multi_map.generators) do
|
||||
local t = multi_map.generators[multi_map.current_layer]
|
||||
if not t then
|
||||
if multi_map.fallback_generator then
|
||||
multi_map.fallback_generator(multi_map.current_layer, minp, maxp, offset_minp, offset_maxp)
|
||||
else
|
||||
minetest.log("error", "Generator for layer "..multi_map.current_layer.." missing and no fallback specified, exiting mapgen!")
|
||||
return
|
||||
end
|
||||
else
|
||||
for i,f in ipairs(t) do
|
||||
f(multi_map.current_layer, minp, maxp, offset_minp, offset_maxp)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_node("multi_map_core:skyrock", {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
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_lvm_example.lua")
|
||||
dofile(multi_map_generators_path.."/mmgen_simple.lua")
|
||||
dofile(multi_map_generators_path.."/mmgen_testauri.lua")
|
||||
|
||||
multi_map.register_fallback_generator(mmgen_simple.generate)
|
||||
multi_map.register_generator(11, mmgen_testauri.generate)
|
||||
multi_map.register_generator(12, mmgen_testauri.generate)
|
||||
multi_map.register_generator(13, mmgen_testauri.generate)
|
|
@ -0,0 +1,16 @@
|
|||
function generate(current_layer, minp, maxp, offset_minp, offset_maxp)
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local vm_data = vm:get_data()
|
||||
if offset_minp.y >= 0 then
|
||||
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.c_air)
|
||||
vm:set_lighting({day=15, night=0})
|
||||
else
|
||||
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.c_stone)
|
||||
end
|
||||
vm:set_data(vm_data)
|
||||
vm:calc_lighting(false)
|
||||
vm:write_to_map(false)
|
||||
end
|
||||
|
||||
multi_map.append_generator(generate)
|
|
@ -0,0 +1,16 @@
|
|||
mmgen_simple = {}
|
||||
|
||||
function mmgen_simple.generate(current_layer, minp, maxp, offset_minp, offset_maxp)
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local vm_data = vm:get_data()
|
||||
if offset_minp.y >= 0 then
|
||||
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.c_air)
|
||||
vm:set_lighting({day=15, night=0})
|
||||
else
|
||||
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.c_stone)
|
||||
end
|
||||
vm:set_data(vm_data)
|
||||
vm:calc_lighting(false)
|
||||
vm:write_to_map(false)
|
||||
end
|
|
@ -0,0 +1,183 @@
|
|||
mmgen_testauri = {}
|
||||
local layers = {}
|
||||
|
||||
mmgen_testauri.water_height = 0
|
||||
|
||||
mmgen_testauri.seed = 835726
|
||||
|
||||
math.randomseed(mmgen_testauri.seed)
|
||||
|
||||
for i = 0, multi_map.number_of_layers -1 do
|
||||
local height_map_seed = math.random(-1000000000000, 1000000000000)
|
||||
local terrain_type_seed = math.random(-1000000000000, 1000000000000)
|
||||
local mountain_peak_seed = math.random(-1000000000000, 1000000000000)
|
||||
|
||||
layers[i] = {
|
||||
height_map_params = {
|
||||
offset = 0,
|
||||
scale = 50,
|
||||
spread = {x=2048, y=2048, z=2048},
|
||||
seed = height_map_seed,
|
||||
octaves = 7,
|
||||
persist = 0.7
|
||||
},
|
||||
terrain_type_params = {
|
||||
offset = 2.5,
|
||||
scale = 2.5,
|
||||
spread = {x=1024, y=1024, z=1024},
|
||||
seed = terrain_type_seed,
|
||||
octaves = 6,
|
||||
persist = 0.6
|
||||
},
|
||||
mountain_peak_params = {
|
||||
offset = -75,
|
||||
scale = 125,
|
||||
spread = {x=256, y=256, z=256},
|
||||
seed = mountain_peak_seed,
|
||||
octaves = 7,
|
||||
persist = 0.6
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
mmgen_testauri.cave_seed = 6568239
|
||||
mmgen_testauri.lake_seed = 6568239
|
||||
|
||||
local last_layer
|
||||
|
||||
-- Base terrain is the lower frequency, lower amplitude noise
|
||||
-- Terrain type is a multiplier that can dampen terrain to make
|
||||
-- flat plains, hills or mountains
|
||||
-- Mountain peak generates peaks when greater than zero, making
|
||||
-- jagged and rugged peaks on the surface or mountain tops
|
||||
local height_map
|
||||
local terrain_type_map
|
||||
local mountain_peak_map
|
||||
local lake_map
|
||||
|
||||
local height_map_2dmap = {}
|
||||
local terrain_type_2dmap = {}
|
||||
local mountain_peak_2dmap = {}
|
||||
local lake_3dmap = {}
|
||||
|
||||
local cave_map
|
||||
local perlin_worm_start_map
|
||||
local perlin_worm_yaw_map
|
||||
local perlin_worm_pitch_map
|
||||
|
||||
local cave_3dmap = {}
|
||||
local perlin_worm_start_3dmap = {}
|
||||
local perlin_worm_yaw_3dmap = {}
|
||||
local perlin_worm_pitch_3dmap = {}
|
||||
|
||||
local perlin_worms = {}
|
||||
|
||||
local lake_params = {
|
||||
offset = 0,
|
||||
scale = 125,
|
||||
spread = {x=256, y=256, z=256},
|
||||
seed = mmgen_testauri.lake_seed,
|
||||
octaves = 6,
|
||||
persist = 0.6
|
||||
}
|
||||
|
||||
local cave_params = {
|
||||
offset = 0,
|
||||
scale = 10,
|
||||
spread = {x=128, y=128, z=128},
|
||||
seed = mmgen_testauri.cave_seed,
|
||||
octaves = 5,
|
||||
persist = 0.8
|
||||
}
|
||||
|
||||
local perlin_worm_start_params = {
|
||||
offset = 0,
|
||||
scale = 1,
|
||||
spread = {x=256, y=256, z=256},
|
||||
seed = 9876,
|
||||
octaves = 7,
|
||||
persist = 0.7
|
||||
}
|
||||
|
||||
function mmgen_testauri.generate(current_layer, minp, maxp, offset_minp, offset_maxp)
|
||||
local sidelen = maxp.x - minp.x + 1
|
||||
local blocklen = sidelen / 5
|
||||
--3d
|
||||
local chulenxyz = {x = sidelen, y = sidelen, z = sidelen}
|
||||
--2d
|
||||
local chulenxz = {x = sidelen, y = sidelen, z = 1}
|
||||
|
||||
local minposxyz = {x = minp.x, y = minp.y - 1, z = minp.z}
|
||||
local minposxz = {x = minp.x, y = minp.z}
|
||||
|
||||
-- strides for voxelmanip
|
||||
local ystridevm = sidelen + 32
|
||||
local zstridevm = ystridevm ^ 2
|
||||
|
||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||
local vm_data = vm:get_data()
|
||||
|
||||
if last_layer ~= current_layer then
|
||||
height_map = minetest.get_perlin_map(layers[current_layer].height_map_params, chulenxz)
|
||||
terrain_type_map = minetest.get_perlin_map(layers[current_layer].terrain_type_params, chulenxz)
|
||||
mountain_peak_map = minetest.get_perlin_map(layers[current_layer].mountain_peak_params, chulenxz)
|
||||
end
|
||||
|
||||
cave_map = cave_map or minetest.get_perlin_map(cave_params, chulenxyz)
|
||||
-- perlin_worm_start_map = perlin_worm_start_map or minetest.get_perlin_map(perlin_worm_start_params, chulenxyz)
|
||||
|
||||
height_map:get2dMap_flat(minposxz, height_map_2dmap)
|
||||
terrain_type_map:get2dMap_flat(minposxz, terrain_type_2dmap)
|
||||
mountain_peak_map:get2dMap_flat(minposxz, mountain_peak_2dmap)
|
||||
|
||||
cave_map:get3dMap_flat(minposxyz, cave_3dmap)
|
||||
-- perlin_worm_start_map:get3dMap_flat(minposxyz, perlin_worm_start_3dmap)
|
||||
|
||||
-- 3D perlinmap indexes
|
||||
local nixyz = 1
|
||||
-- 2D perlinmap indexes
|
||||
local nixz = 1
|
||||
|
||||
-- local worm_started = false
|
||||
|
||||
for z = minp.z, maxp.z do
|
||||
local niz
|
||||
local oy = offset_minp.y
|
||||
for y = minp.y, maxp.y do
|
||||
local vi = area:index(minp.x, y, z)
|
||||
for x = minp.x, maxp.x do
|
||||
local nix
|
||||
local terrain_type = terrain_type_2dmap[nixz]
|
||||
local height = terrain_type * height_map_2dmap[nixz]
|
||||
|
||||
if mountain_peak_2dmap[nixz] > 0 then
|
||||
height = height + mountain_peak_2dmap[nixz]
|
||||
end
|
||||
|
||||
if oy <= height then
|
||||
vm_data[vi] = multi_map.c_stone
|
||||
elseif oy <= mmgen_testauri.water_height then
|
||||
vm_data[vi] = multi_map.c_water
|
||||
end
|
||||
|
||||
-- Increment noise index.
|
||||
nixyz = nixyz + 1
|
||||
nixz = nixz + 1
|
||||
|
||||
-- Increment voxelmanip index along x row.
|
||||
-- The voxelmanip index increases by 1 when
|
||||
-- moving by 1 node in the +x direction.
|
||||
vi = vi + 1
|
||||
end
|
||||
nixz = nixz - sidelen
|
||||
oy = oy + 1
|
||||
end
|
||||
nixz = nixz + sidelen
|
||||
end
|
||||
|
||||
vm:set_data(vm_data)
|
||||
vm:update_liquids()
|
||||
vm:calc_lighting()
|
||||
vm:write_to_map()
|
||||
end
|
Loading…
Reference in New Issue