mirror of
https://gitlab.com/gaelysam/mapgen_rivers.git
synced 2025-01-04 07:10:34 +01:00
Started refactoring code structure to support a separate mapgen thread
Probably not working for now (untested), still some things to do Also making the code cleaner
This commit is contained in:
parent
1ad8c96b8c
commit
11e6e72324
286
init.lua
286
init.lua
@ -11,269 +11,31 @@ end
|
|||||||
|
|
||||||
dofile(modpath .. 'settings.lua')
|
dofile(modpath .. 'settings.lua')
|
||||||
|
|
||||||
local sea_level = mapgen_rivers.settings.sea_level
|
local sfile = io.open(mapgen_rivers.world_data_path .. 'size')
|
||||||
local elevation_chill = mapgen_rivers.settings.elevation_chill
|
if sfile then
|
||||||
local use_distort = mapgen_rivers.settings.distort
|
sfile:close()
|
||||||
local use_biomes = mapgen_rivers.settings.biomes
|
else
|
||||||
local use_biomegen_mod = use_biomes and minetest.global_exists('biomegen')
|
dofile(modpath .. 'pregenerate.lua')
|
||||||
use_biomes = use_biomes and minetest.global_exists('default') and not use_biomegen_mod
|
collectgarbage()
|
||||||
|
|
||||||
if use_biomegen_mod then
|
|
||||||
biomegen.set_elevation_chill(elevation_chill)
|
|
||||||
end
|
|
||||||
dofile(modpath .. 'noises.lua')
|
|
||||||
|
|
||||||
local heightmaps = dofile(modpath .. 'heightmap.lua')
|
|
||||||
|
|
||||||
-- Linear interpolation
|
|
||||||
local function interp(v00, v01, v11, v10, xf, zf)
|
|
||||||
local v0 = v01*xf + v00*(1-xf)
|
|
||||||
local v1 = v11*xf + v10*(1-xf)
|
|
||||||
return v1*zf + v0*(1-zf)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Localize for performance
|
mapgen_rivers.use_mapgen_thread = minetest.settings:get_bool("mapgen_rivers_use_mapgen_thread")
|
||||||
local floor, min = math.floor, math.min
|
mapgen_rivers.thread = 'main'
|
||||||
|
if mapgen_rivers.use_mapgen_thread and minetest.register_mapgen_dofile then
|
||||||
local data = {}
|
minetest.register_mapgen_dofile(modpath .. 'mapgen.lua')
|
||||||
|
else
|
||||||
local noise_x_obj, noise_z_obj, noise_distort_obj, noise_heat_obj, noise_heat_blend_obj
|
minetest.log("warning", "[mapgen_rivers] Mapgen thread not available on this Minetest version.")
|
||||||
local noise_x_map = {}
|
mapgen_rivers.use_mapgen_thread = false
|
||||||
local noise_z_map = {}
|
dofile(modpath .. 'mapgen.lua')
|
||||||
local noise_distort_map = {}
|
|
||||||
local noise_heat_map = {}
|
|
||||||
local noise_heat_blend_map = {}
|
|
||||||
local mapsize
|
|
||||||
local init = false
|
|
||||||
|
|
||||||
local sumtime = 0
|
|
||||||
local sumtime2 = 0
|
|
||||||
local ngen = 0
|
|
||||||
|
|
||||||
local function generate(minp, maxp, seed)
|
|
||||||
minetest.log("info", ("[mapgen_rivers] Generating from %s to %s"):format(minetest.pos_to_string(minp), minetest.pos_to_string(maxp)))
|
|
||||||
|
|
||||||
local chulens = {
|
|
||||||
x = maxp.x-minp.x+1,
|
|
||||||
y = maxp.y-minp.y+1,
|
|
||||||
z = maxp.z-minp.z+1,
|
|
||||||
}
|
|
||||||
|
|
||||||
if not init then
|
|
||||||
mapsize = {
|
|
||||||
x = chulens.x,
|
|
||||||
y = chulens.y+1,
|
|
||||||
z = chulens.z,
|
|
||||||
}
|
|
||||||
if use_distort then
|
|
||||||
noise_x_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_x, mapsize)
|
|
||||||
noise_z_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_z, mapsize)
|
|
||||||
noise_distort_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.distort_amplitude, chulens)
|
|
||||||
end
|
|
||||||
if use_biomes then
|
|
||||||
noise_heat_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.heat, chulens)
|
|
||||||
noise_heat_blend_obj = minetest.get_perlin_map(mapgen_rivers.noise_params.heat_blend, chulens)
|
|
||||||
end
|
|
||||||
init = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local t0 = os.clock()
|
|
||||||
local minp2d = {x=minp.x, y=minp.z}
|
|
||||||
if use_distort then
|
|
||||||
noise_x_obj:get_3d_map_flat(minp, noise_x_map)
|
|
||||||
noise_z_obj:get_3d_map_flat(minp, noise_z_map)
|
|
||||||
noise_distort_obj:get_2d_map_flat(minp2d, noise_distort_map)
|
|
||||||
end
|
|
||||||
if use_biomes then
|
|
||||||
noise_heat_obj:get_2d_map_flat(minp2d, noise_heat_map)
|
|
||||||
noise_heat_blend_obj:get_2d_map_flat(minp2d, noise_heat_blend_map)
|
|
||||||
end
|
|
||||||
|
|
||||||
local terrain_map, lake_map, incr, i_origin
|
|
||||||
|
|
||||||
if use_distort then
|
|
||||||
local xmin, xmax, zmin, zmax = minp.x, maxp.x, minp.z, maxp.z
|
|
||||||
local i = 0
|
|
||||||
local i2d = 0
|
|
||||||
for z=minp.z, maxp.z do
|
|
||||||
for y=minp.y, maxp.y+1 do
|
|
||||||
for x=minp.x, maxp.x do
|
|
||||||
i = i+1
|
|
||||||
i2d = i2d+1
|
|
||||||
local distort = noise_distort_map[i2d]
|
|
||||||
local xv = noise_x_map[i]*distort + x
|
|
||||||
if xv < xmin then xmin = xv end
|
|
||||||
if xv > xmax then xmax = xv end
|
|
||||||
noise_x_map[i] = xv
|
|
||||||
local zv = noise_z_map[i]*distort + z
|
|
||||||
if zv < zmin then zmin = zv end
|
|
||||||
if zv > zmax then zmax = zv end
|
|
||||||
noise_z_map[i] = zv
|
|
||||||
end
|
|
||||||
i2d = i2d-chulens.x
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local pminp = {x=floor(xmin), z=floor(zmin)}
|
|
||||||
local pmaxp = {x=floor(xmax)+1, z=floor(zmax)+1}
|
|
||||||
incr = pmaxp.x-pminp.x+1
|
|
||||||
i_origin = 1 - pminp.z*incr - pminp.x
|
|
||||||
terrain_map, lake_map = heightmaps(pminp, pmaxp)
|
|
||||||
else
|
|
||||||
terrain_map, lake_map = heightmaps(minp, maxp)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check that there is at least one position that reaches min y
|
|
||||||
if minp.y > sea_level then
|
|
||||||
local y0 = minp.y
|
|
||||||
local is_empty = true
|
|
||||||
for i=1, #terrain_map do
|
|
||||||
if terrain_map[i] >= y0 or lake_map[i] >= y0 then
|
|
||||||
is_empty = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- If not, skip chunk
|
|
||||||
if is_empty then
|
|
||||||
local t = os.clock() - t0
|
|
||||||
ngen = ngen + 1
|
|
||||||
sumtime = sumtime + t
|
|
||||||
sumtime2 = sumtime2 + t*t
|
|
||||||
|
|
||||||
minetest.log("verbose", "[mapgen_rivers] Skipping empty chunk (fully above ground level)")
|
|
||||||
minetest.log("verbose", ("[mapgen_rivers] Done in %5.3f s"):format(t))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local c_stone = minetest.get_content_id("mapgen_stone")
|
|
||||||
local c_water = minetest.get_content_id("mapgen_water_source")
|
|
||||||
local c_rwater = minetest.get_content_id("mapgen_river_water_source")
|
|
||||||
|
|
||||||
local c_dirt, c_lawn, c_dirtsnow, c_snow, c_sand, c_ice
|
|
||||||
if use_biomes then
|
|
||||||
c_dirt = minetest.get_content_id("default:dirt")
|
|
||||||
c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
|
||||||
c_dirtsnow = minetest.get_content_id("default:dirt_with_snow")
|
|
||||||
c_snow = minetest.get_content_id("default:snowblock")
|
|
||||||
c_sand = minetest.get_content_id("default:sand")
|
|
||||||
c_ice = minetest.get_content_id("default:ice")
|
|
||||||
end
|
|
||||||
|
|
||||||
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
|
||||||
vm:get_data(data)
|
|
||||||
|
|
||||||
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
|
||||||
local ystride = a.ystride -- Tip : the ystride of a VoxelArea is the number to add to the array index to get the index of the position above. It's faster because it avoids to completely recalculate the index.
|
|
||||||
|
|
||||||
local nid = mapsize.x*(mapsize.y-1) + 1
|
|
||||||
local incrY = -mapsize.x
|
|
||||||
local incrX = 1 - mapsize.y*incrY
|
|
||||||
local incrZ = mapsize.x*mapsize.y - mapsize.x*incrX - mapsize.x*mapsize.y*incrY
|
|
||||||
|
|
||||||
local i2d = 1
|
|
||||||
|
|
||||||
for z = minp.z, maxp.z do
|
|
||||||
for x = minp.x, maxp.x do
|
|
||||||
local ivm = a:index(x, maxp.y+1, z)
|
|
||||||
local ground_above = false
|
|
||||||
local temperature
|
|
||||||
if use_biomes then
|
|
||||||
temperature = noise_heat_map[i2d]+noise_heat_blend_map[i2d]
|
|
||||||
end
|
|
||||||
local terrain, lake
|
|
||||||
if not use_distort then
|
|
||||||
terrain = terrain_map[i2d]
|
|
||||||
lake = lake_map[i2d]
|
|
||||||
end
|
|
||||||
|
|
||||||
for y = maxp.y+1, minp.y, -1 do
|
|
||||||
if use_distort then
|
|
||||||
local xn = noise_x_map[nid]
|
|
||||||
local zn = noise_z_map[nid]
|
|
||||||
local x0 = floor(xn)
|
|
||||||
local z0 = floor(zn)
|
|
||||||
|
|
||||||
local i0 = i_origin + z0*incr + x0
|
|
||||||
local i1 = i0+1
|
|
||||||
local i2 = i1+incr
|
|
||||||
local i3 = i2-1
|
|
||||||
|
|
||||||
terrain = interp(terrain_map[i0], terrain_map[i1], terrain_map[i2], terrain_map[i3], xn-x0, zn-z0)
|
|
||||||
lake = min(lake_map[i0], lake_map[i1], lake_map[i2], lake_map[i3])
|
|
||||||
end
|
|
||||||
|
|
||||||
if y <= maxp.y then
|
|
||||||
|
|
||||||
local is_lake = lake > terrain
|
|
||||||
if y <= terrain then
|
|
||||||
if not use_biomes or y <= terrain-1 or ground_above then
|
|
||||||
data[ivm] = c_stone
|
|
||||||
elseif is_lake or y < sea_level then
|
|
||||||
data[ivm] = c_sand
|
|
||||||
else
|
|
||||||
local temperature_y = temperature - y*elevation_chill
|
|
||||||
if temperature_y >= 15 then
|
|
||||||
data[ivm] = c_lawn
|
|
||||||
elseif temperature_y >= 0 then
|
|
||||||
data[ivm] = c_dirtsnow
|
|
||||||
else
|
|
||||||
data[ivm] = c_snow
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif y <= lake and lake > sea_level then
|
|
||||||
if not use_biomes or temperature - y*elevation_chill >= 0 then
|
|
||||||
data[ivm] = c_rwater
|
|
||||||
else
|
|
||||||
data[ivm] = c_ice
|
|
||||||
end
|
|
||||||
elseif y <= sea_level then
|
|
||||||
data[ivm] = c_water
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
ground_above = y <= terrain
|
|
||||||
|
|
||||||
ivm = ivm - ystride
|
|
||||||
if use_distort then
|
|
||||||
nid = nid + incrY
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if use_distort then
|
|
||||||
nid = nid + incrX
|
|
||||||
end
|
|
||||||
i2d = i2d + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if use_distort then
|
|
||||||
nid = nid + incrZ
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if use_biomegen_mod then
|
|
||||||
biomegen.generate_all(data, a, vm, minp, maxp, seed)
|
|
||||||
else
|
|
||||||
vm:set_data(data)
|
|
||||||
minetest.generate_ores(vm, minp, maxp)
|
|
||||||
end
|
|
||||||
|
|
||||||
vm:set_lighting({day = 0, night = 0})
|
|
||||||
vm:calc_lighting()
|
|
||||||
vm:update_liquids()
|
|
||||||
vm:write_to_map()
|
|
||||||
|
|
||||||
local t = os.clock()-t0
|
|
||||||
ngen = ngen + 1
|
|
||||||
sumtime = sumtime + t
|
|
||||||
sumtime2 = sumtime2 + t*t
|
|
||||||
minetest.log("verbose", ("[mapgen_rivers] Done in %5.3f s"):format(t))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_generated(generate)
|
-- Setup a metatable to load grid on request if not present
|
||||||
minetest.register_on_shutdown(function()
|
local mt = {
|
||||||
local avg = sumtime / ngen
|
__index = function(_, field)
|
||||||
local std = math.sqrt(sumtime2/ngen - avg*avg)
|
if field == 'grid' then
|
||||||
minetest.log("action", ("[mapgen_rivers] Mapgen statistics:\n- Mapgen calls: %4d\n- Mean time: %5.3f s\n- Standard deviation: %5.3f s"):format(ngen, avg, std))
|
dofile(modpath .. 'load_grid.lua')
|
||||||
end)
|
return mapgen_rivers.grid
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
setmetatable(mapgen_rivers, mt)
|
||||||
|
98
load.lua
98
load.lua
@ -1,98 +0,0 @@
|
|||||||
local worldpath = mapgen_rivers.world_data_path
|
|
||||||
|
|
||||||
local floor = math.floor
|
|
||||||
local sbyte, schar = string.byte, string.char
|
|
||||||
local unpk = unpack
|
|
||||||
|
|
||||||
function mapgen_rivers.load_map(filename, bytes, signed, size, converter)
|
|
||||||
local file = io.open(worldpath .. filename, 'rb')
|
|
||||||
local data = file:read('*all')
|
|
||||||
if #data < bytes*size then
|
|
||||||
data = minetest.decompress(data)
|
|
||||||
end
|
|
||||||
|
|
||||||
local map = {}
|
|
||||||
|
|
||||||
for i=1, size do
|
|
||||||
local i0 = (i-1)*bytes+1
|
|
||||||
local elements = {data:byte(i0, i1)}
|
|
||||||
local n = sbyte(data, i0)
|
|
||||||
if signed and n >= 128 then
|
|
||||||
n = n - 256
|
|
||||||
end
|
|
||||||
|
|
||||||
for j=1, bytes-1 do
|
|
||||||
n = n*256 + sbyte(data, i0+j)
|
|
||||||
end
|
|
||||||
|
|
||||||
map[i] = n
|
|
||||||
end
|
|
||||||
file:close()
|
|
||||||
|
|
||||||
if converter then
|
|
||||||
for i=1, size do
|
|
||||||
map[i] = converter(map[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return map
|
|
||||||
end
|
|
||||||
|
|
||||||
local loader_mt = {
|
|
||||||
__index = function(loader, i)
|
|
||||||
local file = loader.file
|
|
||||||
local bytes = loader.bytes
|
|
||||||
file:seek('set', (i-1)*bytes)
|
|
||||||
local strnum = file:read(bytes)
|
|
||||||
|
|
||||||
local n = sbyte(strnum, 1)
|
|
||||||
if loader.signed and n >= 128 then
|
|
||||||
n = n - 256
|
|
||||||
end
|
|
||||||
|
|
||||||
for j=2, bytes do
|
|
||||||
n = n*256 + sbyte(strnum, j)
|
|
||||||
end
|
|
||||||
|
|
||||||
if loader.conv then
|
|
||||||
n = loader.conv(n)
|
|
||||||
end
|
|
||||||
loader[i] = n
|
|
||||||
return n
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapgen_rivers.interactive_loader(filename, bytes, signed, size, converter)
|
|
||||||
local file = io.open(worldpath .. filename, 'rb')
|
|
||||||
if file then
|
|
||||||
minetest.register_on_shutdown(function()
|
|
||||||
file:close()
|
|
||||||
end)
|
|
||||||
converter = converter or false
|
|
||||||
return setmetatable({file=file, bytes=bytes, signed=signed, size=size, conv=converter}, loader_mt)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function mapgen_rivers.write_map(filename, data, bytes)
|
|
||||||
local size = #data
|
|
||||||
local file = io.open(worldpath .. filename, 'wb')
|
|
||||||
|
|
||||||
local bytelist = {}
|
|
||||||
for j=1, bytes do
|
|
||||||
bytelist[j] = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1, size do
|
|
||||||
local n = floor(data[i])
|
|
||||||
data[i] = n
|
|
||||||
for j=bytes, 2, -1 do
|
|
||||||
bytelist[j] = n % 256
|
|
||||||
n = floor(n / 256)
|
|
||||||
end
|
|
||||||
bytelist[1] = n % 256
|
|
||||||
|
|
||||||
file:write(schar(unpk(bytelist)))
|
|
||||||
end
|
|
||||||
|
|
||||||
file:close()
|
|
||||||
end
|
|
100
load_grid.lua
Normal file
100
load_grid.lua
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
local worldpath = mapgen_rivers.world_data_path
|
||||||
|
|
||||||
|
local floor = math.floor
|
||||||
|
local sbyte = string.byte
|
||||||
|
local unpk = unpack
|
||||||
|
|
||||||
|
local load_map
|
||||||
|
|
||||||
|
if mapgen_rivers.use_interactive_loader then
|
||||||
|
local loader_mt = {
|
||||||
|
__index = function(loader, i)
|
||||||
|
local file = loader.file
|
||||||
|
local bytes = loader.bytes
|
||||||
|
file:seek('set', (i-1)*bytes)
|
||||||
|
local strnum = file:read(bytes)
|
||||||
|
|
||||||
|
local n = sbyte(strnum, 1)
|
||||||
|
if loader.signed and n >= 128 then
|
||||||
|
n = n - 256
|
||||||
|
end
|
||||||
|
|
||||||
|
for j=2, bytes do
|
||||||
|
n = n*256 + sbyte(strnum, j)
|
||||||
|
end
|
||||||
|
|
||||||
|
if loader.conv then
|
||||||
|
n = loader.conv(n)
|
||||||
|
end
|
||||||
|
loader[i] = n
|
||||||
|
return n
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
load_map = function(filename, bytes, signed, size, converter)
|
||||||
|
local file = io.open(worldpath .. filename, 'rb')
|
||||||
|
if file then
|
||||||
|
minetest.register_on_shutdown(function()
|
||||||
|
file:close()
|
||||||
|
end)
|
||||||
|
converter = converter or false
|
||||||
|
return setmetatable({file=file, bytes=bytes, signed=signed, size=size, conv=converter}, loader_mt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
load_map = function(filename, bytes, signed, size, converter)
|
||||||
|
local file = io.open(worldpath .. filename, 'rb')
|
||||||
|
local data = file:read('*all')
|
||||||
|
if #data < bytes*size then
|
||||||
|
data = minetest.decompress(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
local map = {}
|
||||||
|
|
||||||
|
for i=1, size do
|
||||||
|
local i0 = (i-1)*bytes+1
|
||||||
|
local elements = {data:byte(i0, i1)}
|
||||||
|
local n = sbyte(data, i0)
|
||||||
|
if signed and n >= 128 then
|
||||||
|
n = n - 256
|
||||||
|
end
|
||||||
|
|
||||||
|
for j=1, bytes-1 do
|
||||||
|
n = n*256 + sbyte(data, i0+j)
|
||||||
|
end
|
||||||
|
|
||||||
|
map[i] = n
|
||||||
|
end
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
if converter then
|
||||||
|
for i=1, size do
|
||||||
|
map[i] = converter(map[i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return map
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local sfile = io.open(world_data_path..'size', 'r')
|
||||||
|
assert(sfile)
|
||||||
|
local X, Z = tonumber(sfile:read('*l')), tonumber(sfile:read('*l'))
|
||||||
|
sfile:close()
|
||||||
|
|
||||||
|
local function offset_converter(o)
|
||||||
|
return (o + 0.5) * (1/256)
|
||||||
|
end
|
||||||
|
|
||||||
|
mapgen_rivers.grid = {
|
||||||
|
size = {x=X, y=Z},
|
||||||
|
dem = load_map('dem', 2, true X*Z),
|
||||||
|
lakes = load_map('lakes', 2, true, X*Z),
|
||||||
|
dirs = load_map('dirs', 1, false, X*Z),
|
||||||
|
rivers = load_map('rivers', 4, false, X*Z),
|
||||||
|
|
||||||
|
offset_x = load_map('offset_x', 1, true, X*Z, offset_converter),
|
||||||
|
offset_y = load_map('offset_y', 1, true, X*Z, offset_converter);
|
||||||
|
}
|
295
mapgen.lua
Normal file
295
mapgen.lua
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
-- Recreate mod table if we are in a separate environment
|
||||||
|
if not minetest.global_exists("mapgen_rivers") then
|
||||||
|
mapgen_rivers = {use_mapgen_thread=true, thread='mapgen'}
|
||||||
|
end
|
||||||
|
|
||||||
|
if not mapgen_rivers.grid then
|
||||||
|
dofile(minetest.get_modpath(minetest.get_current_modname()) .. '/load_grid.lua')
|
||||||
|
end
|
||||||
|
|
||||||
|
local settings = Settings(minetest.get_worldpath() .. '/mapgen_rivers.conf')
|
||||||
|
|
||||||
|
local sea_level = tonumber(settings:get('sea_level'))
|
||||||
|
local elevation_chill = tonumber(settings:get('elevation_chill'))
|
||||||
|
local use_distort = settings:get_bool('distort')
|
||||||
|
local use_biomes = settings:get_bool('biomes')
|
||||||
|
local use_biomegen_mod = use_biomes and minetest.global_exists('biomegen')
|
||||||
|
use_biomes = use_biomes and minetest.global_exists('default') and not use_biomegen_mod
|
||||||
|
|
||||||
|
local noiseparams = {
|
||||||
|
distort_x = settings:get_np_group('np_distort_x'),
|
||||||
|
distort_z = settings:get_np_group('np_distort_z'),
|
||||||
|
distort_amplitude = settings:get_np_group('np_distort_amplitude'),
|
||||||
|
}
|
||||||
|
|
||||||
|
if use_biomes then
|
||||||
|
noiseparams.heat = minetest.get_mapgen_setting_noiseparams("np_heat")
|
||||||
|
noiseparams.heat_blend = minetest.get_mapgen_setting_noiseparams("np_heat_blend")
|
||||||
|
end
|
||||||
|
|
||||||
|
if use_biomegen_mod then
|
||||||
|
biomegen.set_elevation_chill(elevation_chill)
|
||||||
|
end
|
||||||
|
|
||||||
|
local heightmaps = dofile(minetest.get_modpath(minetest.get_current_modname()) .. '/heightmap.lua')
|
||||||
|
|
||||||
|
-- Linear interpolation
|
||||||
|
local function interp(v00, v01, v11, v10, xf, zf)
|
||||||
|
local v0 = v01*xf + v00*(1-xf)
|
||||||
|
local v1 = v11*xf + v10*(1-xf)
|
||||||
|
return v1*zf + v0*(1-zf)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Localize for performance
|
||||||
|
local floor, min = math.floor, math.min
|
||||||
|
|
||||||
|
local data = {}
|
||||||
|
|
||||||
|
local noise_x_obj, noise_z_obj, noise_distort_obj, noise_heat_obj, noise_heat_blend_obj
|
||||||
|
local noise_x_map = {}
|
||||||
|
local noise_z_map = {}
|
||||||
|
local noise_distort_map = {}
|
||||||
|
local noise_heat_map = {}
|
||||||
|
local noise_heat_blend_map = {}
|
||||||
|
local mapsize
|
||||||
|
local init = false
|
||||||
|
|
||||||
|
local sumtime = 0
|
||||||
|
local sumtime2 = 0
|
||||||
|
local ngen = 0
|
||||||
|
|
||||||
|
local function init_mapgen(chulens)
|
||||||
|
mapsize = {
|
||||||
|
x = chulens.x,
|
||||||
|
y = chulens.y+1,
|
||||||
|
z = chulens.z,
|
||||||
|
}
|
||||||
|
if use_distort then
|
||||||
|
noise_x_obj = minetest.get_perlin_map(noiseparams.distort_x, mapsize)
|
||||||
|
noise_z_obj = minetest.get_perlin_map(noiseparams.distort_z, mapsize)
|
||||||
|
noise_distort_obj = minetest.get_perlin_map(noiseparams.distort_amplitude, chulens)
|
||||||
|
end
|
||||||
|
if use_biomes then
|
||||||
|
noise_heat_obj = minetest.get_perlin_map(noiseparams.heat, chulens)
|
||||||
|
noise_heat_blend_obj = minetest.get_perlin_map(noiseparams.heat_blend, chulens)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function generate(minp, maxp, seed)
|
||||||
|
minetest.log("info", ("[mapgen_rivers] Generating from %s to %s"):format(minetest.pos_to_string(minp), minetest.pos_to_string(maxp)))
|
||||||
|
|
||||||
|
local chulens = {
|
||||||
|
x = maxp.x-minp.x+1,
|
||||||
|
y = maxp.y-minp.y+1,
|
||||||
|
z = maxp.z-minp.z+1,
|
||||||
|
}
|
||||||
|
|
||||||
|
if not init then
|
||||||
|
init_mapgen(chulens)
|
||||||
|
init = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local t0 = os.clock()
|
||||||
|
local minp2d = {x=minp.x, y=minp.z}
|
||||||
|
if use_distort then
|
||||||
|
noise_x_obj:get_3d_map_flat(minp, noise_x_map)
|
||||||
|
noise_z_obj:get_3d_map_flat(minp, noise_z_map)
|
||||||
|
noise_distort_obj:get_2d_map_flat(minp2d, noise_distort_map)
|
||||||
|
end
|
||||||
|
if use_biomes then
|
||||||
|
noise_heat_obj:get_2d_map_flat(minp2d, noise_heat_map)
|
||||||
|
noise_heat_blend_obj:get_2d_map_flat(minp2d, noise_heat_blend_map)
|
||||||
|
end
|
||||||
|
|
||||||
|
local terrain_map, lake_map, incr, i_origin
|
||||||
|
|
||||||
|
if use_distort then
|
||||||
|
local xmin, xmax, zmin, zmax = minp.x, maxp.x, minp.z, maxp.z
|
||||||
|
local i = 0
|
||||||
|
local i2d = 0
|
||||||
|
for z=minp.z, maxp.z do
|
||||||
|
for y=minp.y, maxp.y+1 do
|
||||||
|
for x=minp.x, maxp.x do
|
||||||
|
i = i+1
|
||||||
|
i2d = i2d+1
|
||||||
|
local distort = noise_distort_map[i2d]
|
||||||
|
local xv = noise_x_map[i]*distort + x
|
||||||
|
if xv < xmin then xmin = xv end
|
||||||
|
if xv > xmax then xmax = xv end
|
||||||
|
noise_x_map[i] = xv
|
||||||
|
local zv = noise_z_map[i]*distort + z
|
||||||
|
if zv < zmin then zmin = zv end
|
||||||
|
if zv > zmax then zmax = zv end
|
||||||
|
noise_z_map[i] = zv
|
||||||
|
end
|
||||||
|
i2d = i2d-chulens.x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local pminp = {x=floor(xmin), z=floor(zmin)}
|
||||||
|
local pmaxp = {x=floor(xmax)+1, z=floor(zmax)+1}
|
||||||
|
incr = pmaxp.x-pminp.x+1
|
||||||
|
i_origin = 1 - pminp.z*incr - pminp.x
|
||||||
|
terrain_map, lake_map = heightmaps(pminp, pmaxp)
|
||||||
|
else
|
||||||
|
terrain_map, lake_map = heightmaps(minp, maxp)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check that there is at least one position that reaches min y
|
||||||
|
if minp.y > sea_level then
|
||||||
|
local y0 = minp.y
|
||||||
|
local is_empty = true
|
||||||
|
for i=1, #terrain_map do
|
||||||
|
if terrain_map[i] >= y0 or lake_map[i] >= y0 then
|
||||||
|
is_empty = false
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If not, skip chunk
|
||||||
|
if is_empty then
|
||||||
|
local t = os.clock() - t0
|
||||||
|
ngen = ngen + 1
|
||||||
|
sumtime = sumtime + t
|
||||||
|
sumtime2 = sumtime2 + t*t
|
||||||
|
|
||||||
|
minetest.log("verbose", "[mapgen_rivers] Skipping empty chunk (fully above ground level)")
|
||||||
|
minetest.log("verbose", ("[mapgen_rivers] Done in %5.3f s"):format(t))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local c_stone = minetest.get_content_id("mapgen_stone")
|
||||||
|
local c_water = minetest.get_content_id("mapgen_water_source")
|
||||||
|
local c_rwater = minetest.get_content_id("mapgen_river_water_source")
|
||||||
|
|
||||||
|
local c_dirt, c_lawn, c_dirtsnow, c_snow, c_sand, c_ice
|
||||||
|
if use_biomes then
|
||||||
|
c_dirt = minetest.get_content_id("default:dirt")
|
||||||
|
c_lawn = minetest.get_content_id("default:dirt_with_grass")
|
||||||
|
c_dirtsnow = minetest.get_content_id("default:dirt_with_snow")
|
||||||
|
c_snow = minetest.get_content_id("default:snowblock")
|
||||||
|
c_sand = minetest.get_content_id("default:sand")
|
||||||
|
c_ice = minetest.get_content_id("default:ice")
|
||||||
|
end
|
||||||
|
|
||||||
|
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
|
||||||
|
vm:get_data(data)
|
||||||
|
|
||||||
|
local a = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
|
||||||
|
local ystride = a.ystride -- Tip : the ystride of a VoxelArea is the number to add to the array index to get the index of the position above. It's faster because it avoids to completely recalculate the index.
|
||||||
|
|
||||||
|
local nid = mapsize.x*(mapsize.y-1) + 1
|
||||||
|
local incrY = -mapsize.x
|
||||||
|
local incrX = 1 - mapsize.y*incrY
|
||||||
|
local incrZ = mapsize.x*mapsize.y - mapsize.x*incrX - mapsize.x*mapsize.y*incrY
|
||||||
|
|
||||||
|
local i2d = 1
|
||||||
|
|
||||||
|
for z = minp.z, maxp.z do
|
||||||
|
for x = minp.x, maxp.x do
|
||||||
|
local ivm = a:index(x, maxp.y+1, z)
|
||||||
|
local ground_above = false
|
||||||
|
local temperature
|
||||||
|
if use_biomes then
|
||||||
|
temperature = noise_heat_map[i2d]+noise_heat_blend_map[i2d]
|
||||||
|
end
|
||||||
|
local terrain, lake
|
||||||
|
if not use_distort then
|
||||||
|
terrain = terrain_map[i2d]
|
||||||
|
lake = lake_map[i2d]
|
||||||
|
end
|
||||||
|
|
||||||
|
for y = maxp.y+1, minp.y, -1 do
|
||||||
|
if use_distort then
|
||||||
|
local xn = noise_x_map[nid]
|
||||||
|
local zn = noise_z_map[nid]
|
||||||
|
local x0 = floor(xn)
|
||||||
|
local z0 = floor(zn)
|
||||||
|
|
||||||
|
local i0 = i_origin + z0*incr + x0
|
||||||
|
local i1 = i0+1
|
||||||
|
local i2 = i1+incr
|
||||||
|
local i3 = i2-1
|
||||||
|
|
||||||
|
terrain = interp(terrain_map[i0], terrain_map[i1], terrain_map[i2], terrain_map[i3], xn-x0, zn-z0)
|
||||||
|
lake = min(lake_map[i0], lake_map[i1], lake_map[i2], lake_map[i3])
|
||||||
|
end
|
||||||
|
|
||||||
|
if y <= maxp.y then
|
||||||
|
|
||||||
|
local is_lake = lake > terrain
|
||||||
|
if y <= terrain then
|
||||||
|
if not use_biomes or y <= terrain-1 or ground_above then
|
||||||
|
data[ivm] = c_stone
|
||||||
|
elseif is_lake or y < sea_level then
|
||||||
|
data[ivm] = c_sand
|
||||||
|
else
|
||||||
|
local temperature_y = temperature - y*elevation_chill
|
||||||
|
if temperature_y >= 15 then
|
||||||
|
data[ivm] = c_lawn
|
||||||
|
elseif temperature_y >= 0 then
|
||||||
|
data[ivm] = c_dirtsnow
|
||||||
|
else
|
||||||
|
data[ivm] = c_snow
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif y <= lake and lake > sea_level then
|
||||||
|
if not use_biomes or temperature - y*elevation_chill >= 0 then
|
||||||
|
data[ivm] = c_rwater
|
||||||
|
else
|
||||||
|
data[ivm] = c_ice
|
||||||
|
end
|
||||||
|
elseif y <= sea_level then
|
||||||
|
data[ivm] = c_water
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ground_above = y <= terrain
|
||||||
|
|
||||||
|
ivm = ivm - ystride
|
||||||
|
if use_distort then
|
||||||
|
nid = nid + incrY
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if use_distort then
|
||||||
|
nid = nid + incrX
|
||||||
|
end
|
||||||
|
i2d = i2d + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if use_distort then
|
||||||
|
nid = nid + incrZ
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if use_biomegen_mod then
|
||||||
|
biomegen.generate_all(data, a, vm, minp, maxp, seed)
|
||||||
|
else
|
||||||
|
vm:set_data(data)
|
||||||
|
minetest.generate_ores(vm, minp, maxp)
|
||||||
|
end
|
||||||
|
|
||||||
|
vm:set_lighting({day = 0, night = 0})
|
||||||
|
vm:calc_lighting()
|
||||||
|
vm:update_liquids()
|
||||||
|
vm:write_to_map()
|
||||||
|
|
||||||
|
local t = os.clock()-t0
|
||||||
|
ngen = ngen + 1
|
||||||
|
sumtime = sumtime + t
|
||||||
|
sumtime2 = sumtime2 + t*t
|
||||||
|
minetest.log("verbose", ("[mapgen_rivers] Done in %5.3f s"):format(t))
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_generated(generate)
|
||||||
|
minetest.register_on_shutdown(function()
|
||||||
|
if ngen == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local avg = sumtime / ngen
|
||||||
|
local std = math.sqrt(sumtime2/ngen - avg*avg)
|
||||||
|
minetest.log("action", ("[mapgen_rivers] Mapgen statistics:\n- Mapgen calls: %4d\n- Mean time: %5.3f s\n- Standard deviation: %5.3f s"):format(ngen, avg, std))
|
||||||
|
end)
|
79
polygons.lua
79
polygons.lua
@ -1,80 +1,5 @@
|
|||||||
local modpath = mapgen_rivers.modpath
|
local X = mapgen_rivers.grid.size.x
|
||||||
local mod_data_path = modpath .. 'river_data/'
|
local Z = mapgen_rivers.grid.size.y
|
||||||
if not io.open(mod_data_path .. 'size', 'r') then
|
|
||||||
mod_data_path = modpath .. 'demo_data/'
|
|
||||||
end
|
|
||||||
|
|
||||||
local world_data_path = mapgen_rivers.world_data_path
|
|
||||||
minetest.mkdir(world_data_path)
|
|
||||||
|
|
||||||
dofile(modpath .. 'load.lua')
|
|
||||||
|
|
||||||
mapgen_rivers.grid = {}
|
|
||||||
|
|
||||||
local X = mapgen_rivers.settings.grid_x_size
|
|
||||||
local Z = mapgen_rivers.settings.grid_z_size
|
|
||||||
|
|
||||||
local function offset_converter(o)
|
|
||||||
return (o + 0.5) * (1/256)
|
|
||||||
end
|
|
||||||
|
|
||||||
local load_all = mapgen_rivers.settings.load_all
|
|
||||||
|
|
||||||
-- Try to read file 'size'
|
|
||||||
local sfile = io.open(world_data_path..'size', 'r')
|
|
||||||
local first_mapgen = true
|
|
||||||
if sfile then
|
|
||||||
X, Z = tonumber(sfile:read('*l')), tonumber(sfile:read('*l'))
|
|
||||||
sfile:close()
|
|
||||||
first_mapgen = false
|
|
||||||
end
|
|
||||||
|
|
||||||
if first_mapgen then
|
|
||||||
-- Generate a map!!
|
|
||||||
local pregenerate = dofile(mapgen_rivers.modpath .. '/pregenerate.lua')
|
|
||||||
minetest.register_on_mods_loaded(function()
|
|
||||||
minetest.log("action", '[mapgen_rivers] Generating grid, this may take a while...')
|
|
||||||
pregenerate(load_all)
|
|
||||||
|
|
||||||
if load_all then
|
|
||||||
local offset_x = mapgen_rivers.grid.offset_x
|
|
||||||
local offset_y = mapgen_rivers.grid.offset_y
|
|
||||||
for i=1, X*Z do
|
|
||||||
offset_x[i] = offset_converter(offset_x[i])
|
|
||||||
offset_y[i] = offset_converter(offset_y[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- if data not already loaded
|
|
||||||
if not (first_mapgen and load_all) then
|
|
||||||
local load_map
|
|
||||||
if load_all then
|
|
||||||
load_map = mapgen_rivers.load_map
|
|
||||||
else
|
|
||||||
load_map = mapgen_rivers.interactive_loader
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_mods_loaded(function()
|
|
||||||
if load_all then
|
|
||||||
minetest.log("action", '[mapgen_rivers] Loading full grid')
|
|
||||||
else
|
|
||||||
minetest.log("action", '[mapgen_rivers] Loading grid as interactive loaders')
|
|
||||||
end
|
|
||||||
local grid = mapgen_rivers.grid
|
|
||||||
|
|
||||||
grid.dem = load_map('dem', 2, true, X*Z)
|
|
||||||
grid.lakes = load_map('lakes', 2, true, X*Z)
|
|
||||||
grid.dirs = load_map('dirs', 1, false, X*Z)
|
|
||||||
grid.rivers = load_map('rivers', 4, false, X*Z)
|
|
||||||
|
|
||||||
grid.offset_x = load_map('offset_x', 1, true, X*Z, offset_converter)
|
|
||||||
grid.offset_y = load_map('offset_y', 1, true, X*Z, offset_converter)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
mapgen_rivers.grid.size = {x=X, y=Z}
|
|
||||||
|
|
||||||
local function index(x, z)
|
local function index(x, z)
|
||||||
return z*X+x+1
|
return z*X+x+1
|
||||||
|
137
pregenerate.lua
137
pregenerate.lua
@ -13,69 +13,100 @@ local time_step = mapgen_rivers.settings.evol_time_step
|
|||||||
local niter = math.ceil(time/time_step)
|
local niter = math.ceil(time/time_step)
|
||||||
time_step = time / niter
|
time_step = time / niter
|
||||||
|
|
||||||
local function pregenerate(keep_loaded)
|
-- Setup the model
|
||||||
local grid = mapgen_rivers.grid
|
local grid = mapgen_rivers.grid
|
||||||
local size = grid.size
|
local size = grid.size
|
||||||
|
|
||||||
local seed = tonumber(minetest.get_mapgen_setting("seed"))
|
local seed = tonumber(minetest.get_mapgen_setting("seed"))
|
||||||
np_base.seed = (np_base.seed or 0) + seed
|
np_base.seed = (np_base.seed or 0) + seed
|
||||||
|
|
||||||
local nobj_base = PerlinNoiseMap(np_base, {x=size.x, y=1, z=size.y})
|
local nobj_base = PerlinNoiseMap(np_base, {x=size.x, y=1, z=size.y})
|
||||||
|
|
||||||
local dem = nobj_base:get_3d_map_flat({x=0, y=0, z=0})
|
local dem = nobj_base:get_3d_map_flat({x=0, y=0, z=0})
|
||||||
dem.X = size.x
|
dem.X = size.x
|
||||||
dem.Y = size.y
|
dem.Y = size.y
|
||||||
|
|
||||||
local model = EvolutionModel(evol_params)
|
local model = EvolutionModel(evol_params)
|
||||||
model.dem = dem
|
model.dem = dem
|
||||||
local ref_dem = model:define_isostasy(dem)
|
local ref_dem = model:define_isostasy(dem)
|
||||||
|
|
||||||
local tectonic_step = tectonic_speed * time_step
|
local tectonic_step = tectonic_speed * time_step
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
for i=1, niter do
|
|
||||||
minetest.log("info", "[mapgen_rivers] Iteration " .. i .. " of " .. niter)
|
|
||||||
|
|
||||||
model:diffuse(time_step)
|
-- Run the model
|
||||||
model:flow()
|
for i=1, niter do
|
||||||
model:erode(time_step)
|
minetest.log("info", "[mapgen_rivers] Iteration " .. i .. " of " .. niter)
|
||||||
if i < niter then
|
|
||||||
if tectonic_step ~= 0 then
|
|
||||||
nobj_base:get_3d_map_flat({x=0, y=tectonic_step*i, z=0}, ref_dem)
|
|
||||||
end
|
|
||||||
model:isostasy()
|
|
||||||
end
|
|
||||||
|
|
||||||
collectgarbage()
|
model:diffuse(time_step)
|
||||||
end
|
|
||||||
model:flow()
|
model:flow()
|
||||||
|
model:erode(time_step)
|
||||||
local mfloor = math.floor
|
if i < niter then
|
||||||
local mmin, mmax = math.min, math.max
|
if tectonic_step ~= 0 then
|
||||||
local offset_x, offset_y = twist(model.dirs, model.rivers, 5)
|
nobj_base:get_3d_map_flat({x=0, y=tectonic_step*i, z=0}, ref_dem)
|
||||||
for i=1, size.x*size.y do
|
end
|
||||||
offset_x[i] = mmin(mmax(offset_x[i]*256, -128), 127)
|
model:isostasy()
|
||||||
offset_y[i] = mmin(mmax(offset_y[i]*256, -128), 127)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
mapgen_rivers.write_map('dem', model.dem, 2)
|
|
||||||
mapgen_rivers.write_map('lakes', model.lakes, 2)
|
|
||||||
mapgen_rivers.write_map('dirs', model.dirs, 1)
|
|
||||||
mapgen_rivers.write_map('rivers', model.rivers, 4)
|
|
||||||
mapgen_rivers.write_map('offset_x', offset_x, 1)
|
|
||||||
mapgen_rivers.write_map('offset_y', offset_y, 1)
|
|
||||||
local sfile = io.open(mapgen_rivers.world_data_path .. 'size', "w")
|
|
||||||
sfile:write(size.x..'\n'..size.y)
|
|
||||||
sfile:close()
|
|
||||||
|
|
||||||
if keep_loaded then
|
|
||||||
grid.dem = model.dem
|
|
||||||
grid.lakes = model.lakes
|
|
||||||
grid.dirs = model.dirs
|
|
||||||
grid.rivers = model.rivers
|
|
||||||
grid.offset_x = offset_x
|
|
||||||
grid.offset_y = offset_y
|
|
||||||
end
|
|
||||||
collectgarbage()
|
collectgarbage()
|
||||||
end
|
end
|
||||||
|
model:flow()
|
||||||
|
|
||||||
return pregenerate
|
local mfloor = math.floor
|
||||||
|
local mmin, mmax = math.min, math.max
|
||||||
|
local offset_x, offset_y = twist(model.dirs, model.rivers, 5)
|
||||||
|
for i=1, size.x*size.y do
|
||||||
|
offset_x[i] = mmin(mmax(offset_x[i]*256, -128), 127)
|
||||||
|
offset_y[i] = mmin(mmax(offset_y[i]*256, -128), 127)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Write the results in the world directory
|
||||||
|
minetest.mkdir(mapgen_rivers.world_data_path)
|
||||||
|
|
||||||
|
local function write_map(filename, data, bytes)
|
||||||
|
local size = #data
|
||||||
|
local file = io.open(worldpath .. filename, 'wb')
|
||||||
|
|
||||||
|
local bytelist = {}
|
||||||
|
for j=1, bytes do
|
||||||
|
bytelist[j] = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local unpk = unpack
|
||||||
|
local schar = string.char
|
||||||
|
local floor = math.floor
|
||||||
|
for i=1, size do
|
||||||
|
local n = floor(data[i])
|
||||||
|
data[i] = n
|
||||||
|
for j=bytes, 2, -1 do
|
||||||
|
bytelist[j] = n % 256
|
||||||
|
n = floor(n / 256)
|
||||||
|
end
|
||||||
|
bytelist[1] = n % 256
|
||||||
|
|
||||||
|
file:write(schar(unpk(bytelist)))
|
||||||
|
end
|
||||||
|
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
write_map('dem', model.dem, 2)
|
||||||
|
write_map('lakes', model.lakes, 2)
|
||||||
|
write_map('dirs', model.dirs, 1)
|
||||||
|
write_map('rivers', model.rivers, 4)
|
||||||
|
write_map('offset_x', offset_x, 1)
|
||||||
|
write_map('offset_y', offset_y, 1)
|
||||||
|
local sfile = io.open(mapgen_rivers.world_data_path .. 'size', "w")
|
||||||
|
sfile:write(size.x..'\n'..size.y)
|
||||||
|
sfile:close()
|
||||||
|
|
||||||
|
if not mapgen_rivers.settings.use_interactive_loader then
|
||||||
|
mapgen_rivers.grid = {
|
||||||
|
size = {x=size_x, y=size_y},
|
||||||
|
dem = model.dem,
|
||||||
|
lakes = model.lakes,
|
||||||
|
dirs = model.dirs,
|
||||||
|
rivers = model.rivers,
|
||||||
|
offset_x = offset_x,
|
||||||
|
offset_y = offset_y,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
@ -87,9 +87,6 @@ mapgen_rivers.settings = {
|
|||||||
load_all = mtsettings:get_bool('mapgen_rivers_load_all')
|
load_all = mtsettings:get_bool('mapgen_rivers_load_all')
|
||||||
}
|
}
|
||||||
|
|
||||||
local function write_settings()
|
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/noises.lua")
|
||||||
mgrsettings:write()
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_mods_loaded(write_settings)
|
mgrsettings:write()
|
||||||
minetest.register_on_shutdown(write_settings)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user