Turned into a modpack, supplying simple mapgen. Changed to work on chunk

boundaries. Current version does not call the registered mapgen yet, and
simple mapgen is part of core (to be moved)
This commit is contained in:
evrooije 2018-07-17 21:16:37 +02:00
parent f643ce0700
commit d5d4520b2e
10 changed files with 428 additions and 308 deletions

View File

@ -1,50 +0,0 @@
multi_map = {}
multi_map.number_of_layers = 32
multi_map.day_light = 15
multi_map.night_light = 0
multi_map.bedrock = "multi_map:bedrock"
multi_map.skyrock = "multi_map:skyrock"
multi_map.water_height = 0
multi_map.seed = 835726
multi_map.layer_height = 65535 / multi_map.number_of_layers
multi_map.half_layer_height = multi_map.layer_height / 2
function multi_map.get_current_layer(y)
for l = (multi_map.number_of_layers / -2), (multi_map.number_of_layers / 2) do
if y >= (l * layer_height) - half_layer_height and y < (l * layer_height) + half_layer_height then
return l
end
end
end
function multi_map.get_offset_y(y)
return y - (multi_map.get_current_layer(y) * multi_map.layer_height)
end
minetest.register_node("multi_map:skyrock", {
description = "Multi Map Impenetrable Skyblock",
drawtype = "airlike",
is_ground_content = false,
sunlight_propagates = true,
walkable = true,
pointable = false,
diggable = false,
climbable = false,
paramtype = "light",
})
minetest.register_node("multi_map:bedrock", {
description = "Multi Map Impenetrable Bedrock",
drawtype = "normal",
tiles ={"multi_map_bedrock.png"},
is_ground_content = false,
walkable = true,
pointable = false,
diggable = false,
climbable = false,
})
local mod_path = minetest.get_modpath("multi_map")
dofile(mod_path.."/mapgen.lua")

View File

@ -1,258 +0,0 @@
local settings = {}
local layers = {}
settings.number_of_layers = 32
settings.day_light = 15
settings.night_light = 0
settings.bedrock = "multi_map:bedrock"
settings.skyrock = "multi_map:skyrock"
settings.water_height = 0
settings.seed = 835726
math.randomseed(settings.seed)
for i = settings.number_of_layers / -2, settings.number_of_layers / 2 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
},
height_map = nil,
height_map_2dmap = {},
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
},
terrain_type_map = nil,
terrain_type_2dmap = {},
mountain_peak_params = {
offset = -75,
scale = 125,
spread = {x=256, y=256, z=256},
seed = mountain_peak_seed,
octaves = 7,
persist = 0.6
},
mountain_peak_map = nil,
mountain_peak_2dmap = {},
}
end
settings.cave_seed = 6568239
local layer_height = 65535 / settings.number_of_layers
local half_layer_height = layer_height / 2
-- 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 height_map_params = {
-- offset = 0,
-- scale = 50,
-- spread = {x=2048, y=2048, z=2048},
-- seed = settings.height_map_seed,
-- octaves = 7,
-- persist = 0.7
--}
--local terrain_type_params = {
-- offset = 2.5,
-- scale = 2.5,
-- spread = {x=1024, y=1024, z=1024},
-- seed = settings.terrain_type_seed,
-- octaves = 6,
-- persist = 0.6
--}
--local mountain_peak_params = {
-- offset = -75,
-- scale = 125,
-- spread = {x=256, y=256, z=256},
-- seed = settings.mountain_peak_seed,
-- octaves = 7,
-- persist = 0.6
--}
local lake_params = {
offset = 0,
scale = 125,
spread = {x=256, y=256, z=256},
seed = settings.lake_seed,
octaves = 6,
persist = 0.6
}
local cave_params = {
offset = 0,
scale = 10,
spread = {x=128, y=128, z=128},
seed = settings.cave_seed,
octaves = 5,
persist = 0.8
}
local perlin_worm_start_params = {
offset = 0,
scale = 1,
spread = {x=256, y=256, z=256},
seed = settings.perlin_worm_start_seed,
octaves = 7,
persist = 0.7
}
minetest.register_on_generated(function(minp, maxp)
local c_stone = minetest.get_content_id("default:stone")
local c_air = minetest.get_content_id("air")
local c_water = minetest.get_content_id("default:water_source")
local c_bedrock = minetest.get_content_id(settings.bedrock)
local c_skyrock = minetest.get_content_id(settings.skyrock)
local current_layer = nil
for l = (settings.number_of_layers / -2), (settings.number_of_layers / 2) do
if minp.y >= (l * layer_height) - half_layer_height and minp.y < (l * layer_height) + half_layer_height then
current_layer = l
break
end
end
if not current_layer then
minetest.log("error", "Could not determine current multi_map layer, exiting mapgen!")
return
end
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()
layers[current_layer].height_map = layers[current_layer].height_map or
minetest.get_perlin_map(layers[current_layer].height_map_params, chulenxz)
layers[current_layer].terrain_type_map = layers[current_layer].terrain_type_map or
minetest.get_perlin_map(layers[current_layer].terrain_type_params, chulenxz)
layers[current_layer].mountain_peak_map = layers[current_layer].mountain_peak_map or
minetest.get_perlin_map(layers[current_layer].mountain_peak_params, chulenxz)
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)
layers[current_layer].height_map:get2dMap_flat(minposxz, layers[current_layer].height_map_2dmap)
layers[current_layer].terrain_type_map:get2dMap_flat(minposxz, layers[current_layer].terrain_type_2dmap)
layers[current_layer].mountain_peak_map:get2dMap_flat(minposxz, layers[current_layer].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
local supress_shadow = false
for z = minp.z, maxp.z do
local niz
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 = layers[current_layer].terrain_type_2dmap[nixz]
local height = terrain_type * layers[current_layer].height_map_2dmap[nixz]
if layers[current_layer].mountain_peak_2dmap[nixz] > 0 then
height = height + layers[current_layer].mountain_peak_2dmap[nixz]
end
if (layer_height * current_layer) + half_layer_height < y and y <= (layer_height * current_layer) + half_layer_height + sidelen then
vm_data[vi] = c_bedrock
elseif (layer_height * current_layer) + half_layer_height - (sidelen * 2) <= y and y <= (layer_height * current_layer) + half_layer_height then
vm_data[vi] = c_skyrock
supress_shadow = true
elseif y <= height + (layer_height * current_layer) then
-- if math.abs(cave_3dmap[nixyz]) < 10 then -- + (y / 400) then
vm_data[vi] = c_stone
-- else
-- vm_data[vi] = c_air
-- end
elseif y <= (layer_height * current_layer) + settings.water_height then
vm_data[vi] = 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
end
nixz = nixz + sidelen
end
vm:set_data(vm_data)
vm:update_liquids()
if supress_shadow then
vm:calc_lighting(false)
vm:write_to_map(false)
else
vm:calc_lighting()
vm:write_to_map()
end
end)

0
modpack.txt Normal file
View File

View File

152
multi_map_core/init.lua Normal file
View File

@ -0,0 +1,152 @@
multi_map = {}
multi_map.number_of_layers = 24
multi_map.layer_height_chunks = 32
multi_map.layer_height = multi_map.layer_height_chunks * 80
multi_map.map_height = 61840
multi_map.map_min = -30912
multi_map.map_max = 30927
multi_map.half_layer_height = multi_map.layer_height / 2
multi_map.current_layer = nil
multi_map.bedrock = "multi_map:bedrock"
multi_map.skyrock = "multi_map:skyrock"
multi_map.generate_bedrock = true
multi_map.generate_skyrock = true
multi_map.generators = {}
function multi_map.set_current_layer(y)
for l = 0, multi_map.number_of_layers do
if y >= multi_map.map_min + (l * multi_map.layer_height)
and y < multi_map.map_min + ((l + 1) * multi_map.layer_height)
then
multi_map.current_layer = l
end
end
end
function multi_map.get_offset_y(y)
local center_point = multi_map.map_min + (multi_map.current_layer * multi_map.layer_height) + multi_map.half_layer_height
return y - center_point
end
function multi_map.append_generator(generator)
table.insert(multi_map.generators, generator)
end
function multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, content_id, light_data, light_level)
for z = minp.z, maxp.z do
for y = minp.y, maxp.y do
local vi = area:index(minp.x, y, z)
for x = minp.x, maxp.x do
vm_data[vi] = content_id
if light_data then
light_data[vi] = light_level
end
vi = vi + 1
end
end
end
end
local firstrun = true
-- Global helpers for mapgens
multi_map.c_stone = nil
multi_map.c_air = nil
multi_map.c_water = nil
multi_map.c_bedrock = nil
multi_map.c_skyrock = nil
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!")
end
end)
minetest.register_on_generated(function(minp, maxp)
-- if firstrun then
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_bedrock = minetest.get_content_id(multi_map.bedrock)
multi_map.c_skyrock = minetest.get_content_id(multi_map.skyrock)
firstrun = false
-- end
multi_map.set_current_layer(minp.y)
local sidelen = maxp.x - minp.x + 1
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
multi_map.map_min + (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()
multi_map.generate_singlenode_chunk(minp, maxp, area, vm_data, multi_map.c_bedrock)
vm:set_data(vm_data)
vm:calc_lighting(false)
vm:write_to_map(false)
elseif multi_map.generate_skyrock
and (multi_map.map_min + (multi_map.layer_height * (multi_map.current_layer + 1)) - 80 == minp.y or
multi_map.map_min + (multi_map.layer_height * (multi_map.current_layer + 1)) - 160 == minp.y
)
then
print("Generating skyrock at y = "..minp.y)
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.c_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})
local vm_data = vm:get_data()
local light_data = vm:get_light_data()
print(offset_minp.y)
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, light_data, 0)
end
vm:set_data(vm_data)
vm:calc_lighting()
vm:write_to_map()
-- for i,f in ipairs(multi_map.generators) do
-- f(multi_map.current_layer, minp, maxp, offset_minp, offset_maxp)
-- end
end
end)
minetest.register_node("multi_map:skyrock", {
description = "Multi Map Impenetrable Skyblock",
drawtype = "airlike",
is_ground_content = false,
sunlight_propagates = true,
walkable = true,
pointable = false,
diggable = false,
climbable = false,
paramtype = "light",
})
minetest.register_node("multi_map:bedrock", {
description = "Multi Map Impenetrable Bedrock",
drawtype = "normal",
tiles ={"multi_map_bedrock.png"},
is_ground_content = false,
walkable = true,
pointable = false,
diggable = false,
climbable = false,
})

View File

Before

Width:  |  Height:  |  Size: 804 B

After

Width:  |  Height:  |  Size: 804 B

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Emiel van Rooijen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,2 @@
# mm_testauri_mountain
Multi map generator for Proxima Testauri subgame

View File

@ -0,0 +1 @@
multi_map

View File

@ -0,0 +1,252 @@
-- levels 0.2.6
-- bugfixes: rename luxoff to luxore, remove 'local' from nobj_s
-- Parameters
local TERSCA = 96
local TSPIKE = 1.2
local SPIKEAMP = 2000
local TSTONE = 0.04
local STABLE = 2
local FLOATPER = 512
local FLOATFAC = 2
local FLOATOFF = -0.2
local YSURFMAX = 256
local YSAND = 4
local YWATER = 1
local YSURFCEN = 0
local YSURFMIN = -256
local YUNDERCEN = -512
local YLAVA = -528
local UNDERFAC = 0.0001
local UNDEROFF = -0.2
local LUXCHA = 1 / 9 ^ 3
-- Noise parameters
-- 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 = ""
}
-- 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"
}
-- Nodes
minetest.register_node("mm_testauri_mountains:grass", {
description = "Grass",
tiles = {"default_grass.png", "default_dirt.png", "default_grass.png"},
groups = {crumbly=3},
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_grass_footstep", gain=0.25},
}),
})
minetest.register_node("mm_testauri_mountains:dirt", {
description = "Dirt",
tiles = {"default_dirt.png"},
groups = {crumbly=3},
sounds = default.node_sound_dirt_defaults(),
})
minetest.register_node("mm_testauri_mountains:luxore", {
description = "Lux Ore",
tiles = {"levels_luxore.png"},
paramtype = "light",
light_source = 14,
groups = {cracky=3},
sounds = default.node_sound_glass_defaults(),
})
-- Stuff
local floatper = math.pi / FLOATPER
-- Set mapgen parameters
minetest.register_on_mapgen_init(function(mgparams)
minetest.set_mapgen_params({mgname="singlenode", flags="nolight"})
end)
-- Initialize noise objects to nil
local nobj_terrain = nil
local nobj_spike = nil
-- On generated function
function generate(current_layer, minp, maxp, offset_minp, offset_maxp)
-- local t0 = os.clock()
local x1 = maxp.x
local y1 = maxp.y
local z1 = maxp.z
local x0 = minp.x
local y0 = minp.y
local z0 = minp.z
local ox1 = offset_maxp.x
local oy1 = offset_maxp.y
local oz1 = offset_maxp.z
local ox0 = offset_minp.x
local oy0 = offset_minp.y
local oz0 = offset_minp.z
-- print ("[levels] chunk minp ("..x0.." "..y0.." "..z0..")")
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
local data = vm:get_data()
local c_stone = minetest.get_content_id("default:stone")
local c_sand = minetest.get_content_id("default:sand")
local c_water = minetest.get_content_id("default:water_source")
local c_lava = minetest.get_content_id("default:lava_source")
local c_grass = minetest.get_content_id("mm_testauri_mountains:grass")
local c_dirt = minetest.get_content_id("mm_testauri_mountains:dirt")
local c_luxore = minetest.get_content_id("mm_testauri_mountains:luxore")
local sidelen = x1 - x0 + 1
local ystride = sidelen + 32
--local zstride = ystride ^ 2
local chulens3d = {x=sidelen, y=sidelen+17, z=sidelen}
local chulens2d = {x=sidelen, y=sidelen, z=1}
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 ni3d = 1
local ni2d = 1
local stable = {}
local under = {}
for z = oz0, oz1 do
for x = ox0, ox1 do
local si = x - ox0 + 1
stable[si] = 0
end
for y = oy0 - 16, oy1 + 1 do
local vi = area:index(x0, y, z)
for x = ox0, ox1 do
local si = x - ox0 + 1
local viu = vi - ystride
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
end
local grad = (YSURFCEN - y) / TERSCA + spikeoff
if y > YSURFMAX then
grad = math.max(
-FLOATFAC * math.abs(math.cos((y - YSURFMAX) * floatper)),
grad
)
elseif y < YSURFMIN then
grad = math.min(
UNDERFAC * (y - YUNDERCEN) ^ 2 + UNDEROFF,
grad
)
end
local density = n_terrain + grad
if y < oy0 then
if density >= TSTONE then
stable[si] = stable[si] + 1
elseif density <= 0 then
stable[si] = 0
end
if y == oy0 - 1 then
local nodid = data[vi]
if nodid == c_stone
or nodid == c_sand
or nodid == c_grass
or nodid == c_dirt
or nodid == c_luxore then
stable[si] = STABLE
end
end
elseif y >= oy0 and y <= oy1 then
if density >= TSTONE then
if math.random() < LUXCHA and y < YSURFMIN
and density < 0.01 and data[viu] == c_stone then
data[vi] = c_luxore
else
data[vi] = c_stone
end
stable[si] = stable[si] + 1
under[si] = 0
elseif density > 0 and density < TSTONE
and stable[si] >= STABLE and y > YSURFMIN then
if y <= YSAND then
data[vi] = c_sand
under[si] = 0
else
data[vi] = c_dirt
under[si] = 1
end
elseif y > YSURFMIN and y <= YWATER then
data[vi] = c_water
stable[si] = 0
under[si] = 0
elseif y <= YLAVA then
data[vi] = c_lava
stable[si] = 0
under[si] = 0
else -- air, possibly just above surface
if under[si] == 1 then
data[viu] = c_grass
end
stable[si] = 0
under[si] = 0
end
elseif y == oy1 + 1 then
if density <= 0 and y > YWATER then -- air, possibly just above surface
if under[si] == 1 then
data[viu] = c_grass
end
end
end
ni3d = ni3d + 1
ni2d = ni2d + 1
vi = vi + 1
end
ni2d = ni2d - sidelen
end
ni2d = ni2d + sidelen
end
vm:set_data(data)
vm:calc_lighting()
vm:write_to_map(data)
vm:update_liquids()
-- local chugent = math.ceil((os.clock() - t0) * 1000)
-- print ("[levels] "..chugent.." ms")
end