mirror of
https://gitlab.com/gaelysam/mapgen_rivers.git
synced 2024-12-28 03:40:39 +01:00
Re-organize grid management code for less dependance between files
Remove gridio.lua and move its function to appropriate files
This commit is contained in:
parent
2cf3b19167
commit
146f009684
69
gridio.lua
69
gridio.lua
@ -1,69 +0,0 @@
|
|||||||
-- Input and output functions for grid maps
|
|
||||||
|
|
||||||
local worldpath = mapgen_rivers.world_data_path
|
|
||||||
|
|
||||||
local floor = math.floor
|
|
||||||
local sbyte, schar = string.byte, string.char
|
|
||||||
local unpk = unpack
|
|
||||||
|
|
||||||
-- Loading files
|
|
||||||
|
|
||||||
-- Never load the full map during mapgen. Instead, create an empty lookup table
|
|
||||||
-- and read the file on-the-fly when an element is requested for the first time,
|
|
||||||
-- using __index metamethod.
|
|
||||||
local loader_mt = {
|
|
||||||
__index = function(loader, i) -- Called when accessing a missing key
|
|
||||||
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
|
|
||||||
-- Cache key for next use
|
|
||||||
loader[i] = n
|
|
||||||
return n
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
function mapgen_rivers.load_file(filename, bytes, signed, size, converter)
|
|
||||||
local file = io.open(worldpath .. filename, 'rb')
|
|
||||||
if file then
|
|
||||||
converter = converter or false
|
|
||||||
return setmetatable({file=file, bytes=bytes, signed=signed, size=size, conv=converter}, loader_mt)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Writing files
|
|
||||||
function mapgen_rivers.write_file(filename, data, bytes)
|
|
||||||
local file = io.open(worldpath .. filename, 'wb')
|
|
||||||
|
|
||||||
local bytelist = {}
|
|
||||||
for j=1, bytes do
|
|
||||||
bytelist[j] = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1, #data 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
|
|
@ -1,6 +1,6 @@
|
|||||||
-- Manages grid loading, writing and generation
|
-- Manages grid loading, writing and generation
|
||||||
|
|
||||||
local world_data = mapgen_rivers.world_data_path
|
local datapath = mapgen_rivers.world_data_path
|
||||||
|
|
||||||
local registered_on_grid_loaded = {}
|
local registered_on_grid_loaded = {}
|
||||||
function mapgen_rivers.register_on_grid_loaded(func)
|
function mapgen_rivers.register_on_grid_loaded(func)
|
||||||
@ -21,31 +21,64 @@ local function offset_conv(o)
|
|||||||
return (o + 0.5) * (1/256)
|
return (o + 0.5) * (1/256)
|
||||||
end
|
end
|
||||||
|
|
||||||
local grid_maps_list = {
|
local floor = math.floor
|
||||||
dem = {bytes=2, signed=true},
|
local sbyte, schar = string.byte, string.char
|
||||||
lakes = {bytes=2, signed=true},
|
local unpk = unpack
|
||||||
dirs = {bytes=1, signed=false},
|
|
||||||
rivers = {bytes=4, signed=false},
|
|
||||||
|
|
||||||
offset_x = {bytes=1, signed=true, conv=offset_conv},
|
-- Loading files
|
||||||
offset_y = {bytes=1, signed=true, conv=offset_conv},
|
|
||||||
|
-- Never load the full map during mapgen. Instead, create an empty lookup table
|
||||||
|
-- and read the file on-the-fly when an element is requested for the first time,
|
||||||
|
-- using __index metamethod.
|
||||||
|
local loader_mt = {
|
||||||
|
__index = function(loader, i) -- Called when accessing a missing key
|
||||||
|
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
|
||||||
|
-- Cache key for next use
|
||||||
|
loader[i] = n
|
||||||
|
return n
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapgen_rivers.try_load_grid(grid)
|
local function load_file(filename, bytes, signed, size, converter)
|
||||||
|
local file = io.open(datapath .. filename, 'rb')
|
||||||
|
if file then
|
||||||
|
converter = converter or false
|
||||||
|
return setmetatable({file=file, bytes=bytes, signed=signed, size=size, conv=converter}, loader_mt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function mapgen_rivers.load_or_generate_grid()
|
||||||
-- First, check whether a grid is already loaded
|
-- First, check whether a grid is already loaded
|
||||||
if mapgen_rivers.grid then
|
if mapgen_rivers.grid then
|
||||||
return true
|
return true
|
||||||
-- Then, check the provided argument is a valid grid
|
|
||||||
elseif grid then
|
|
||||||
mapgen_rivers.grid = grid
|
|
||||||
on_grid_loaded_callback(grid)
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Fall back to loading the grid from the files
|
-- If not, try to load the grid from the files
|
||||||
local sfile = io.open(world_data .. 'size', 'r')
|
local sfile = io.open(datapath .. 'size', 'r')
|
||||||
if not sfile then
|
if not sfile then
|
||||||
return false
|
dofile(mapgen_rivers.modpath .. "/pregenerate.lua")
|
||||||
|
collectgarbage()
|
||||||
|
|
||||||
|
sfile = io.open(datapath .. 'size', 'r')
|
||||||
|
if not sfile then
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local x, z = sfile:read('*n'), sfile:read('*n')
|
local x, z = sfile:read('*n'), sfile:read('*n')
|
||||||
@ -55,31 +88,18 @@ function mapgen_rivers.try_load_grid(grid)
|
|||||||
|
|
||||||
minetest.log("action", '[mapgen_rivers] Loading grid')
|
minetest.log("action", '[mapgen_rivers] Loading grid')
|
||||||
|
|
||||||
grid = {
|
local grid = {
|
||||||
size = {x=x, y=z},
|
size = {x=x, y=z},
|
||||||
|
dem = load_file('dem', 2, true, x*z),
|
||||||
|
lakes = load_file('lakes', 2, true, x*z),
|
||||||
|
dirs = load_file('dirs', 1, false, x*z),
|
||||||
|
rivers = load_file('rivers', 4, false, x*z),
|
||||||
|
offset_x = load_file('offset_x', 1, true, x*z, offset_conv),
|
||||||
|
offset_y = load_file('offset_y', 1, true, x*z, offset_conv),
|
||||||
}
|
}
|
||||||
|
|
||||||
for map, params in pairs(grid_maps_list) do
|
|
||||||
grid[map] = mapgen_rivers.load_file(map, params.bytes, params.signed, x*z, params.conv)
|
|
||||||
end
|
|
||||||
|
|
||||||
mapgen_rivers.grid = grid
|
mapgen_rivers.grid = grid
|
||||||
on_grid_loaded_callback(grid)
|
on_grid_loaded_callback(grid)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function mapgen_rivers.write_grid(grid)
|
|
||||||
minetest.mkdir(world_data)
|
|
||||||
|
|
||||||
for map, params in pairs(grid_maps_list) do
|
|
||||||
mapgen_rivers.write_file(map, grid[map], params.bytes)
|
|
||||||
end
|
|
||||||
|
|
||||||
local sfile = io.open(world_data .. 'size', "w")
|
|
||||||
sfile:write(grid.size.x..'\n'..grid.size.y)
|
|
||||||
sfile:close()
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
|
11
init.lua
11
init.lua
@ -8,17 +8,8 @@ mapgen_rivers.world_data_path = minetest.get_worldpath() .. '/river_data/'
|
|||||||
|
|
||||||
dofile(modpath .. 'settings.lua')
|
dofile(modpath .. 'settings.lua')
|
||||||
dofile(modpath .. 'gridmanager.lua')
|
dofile(modpath .. 'gridmanager.lua')
|
||||||
dofile(modpath .. 'gridio.lua')
|
|
||||||
dofile(modpath .. 'polygons.lua')
|
dofile(modpath .. 'polygons.lua')
|
||||||
dofile(modpath .. 'heightmap.lua')
|
dofile(modpath .. 'heightmap.lua')
|
||||||
dofile(modpath .. 'mapgen.lua')
|
dofile(modpath .. 'mapgen.lua')
|
||||||
|
|
||||||
minetest.register_on_mods_loaded(function()
|
minetest.register_on_mods_loaded(mapgen_rivers.load_or_generate_grid)
|
||||||
local exist = mapgen_rivers.try_load_grid()
|
|
||||||
|
|
||||||
if not exist then -- If grid does not exist yet, generate it
|
|
||||||
local grid = dofile(modpath .. 'pregenerate.lua')
|
|
||||||
mapgen_rivers.write_grid(grid)
|
|
||||||
mapgen_rivers.try_load_grid() -- Reload if needed
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
-- Generate the grid using terrainlib_lua
|
-- Generate the grid using terrainlib_lua
|
||||||
-- Only called on first mapgen, if there is no grid yet
|
-- Only called on first mapgen, if there is no grid yet
|
||||||
|
|
||||||
|
-- Constants
|
||||||
|
|
||||||
local EvolutionModel = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/erosion.lua')
|
local EvolutionModel = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/erosion.lua')
|
||||||
local twist = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/twist.lua')
|
local twist = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/twist.lua')
|
||||||
|
|
||||||
@ -52,12 +54,10 @@ local function margin(dem, width, elev)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Generate the grid
|
-- Generate grid
|
||||||
|
|
||||||
minetest.log("action", '[mapgen_rivers] Generating grid, this may take a while...')
|
minetest.log("action", '[mapgen_rivers] Generating grid, this may take a while...')
|
||||||
|
|
||||||
local grid = {size={x=X, y=Y}}
|
|
||||||
|
|
||||||
if X*Y > 4e6 then
|
if X*Y > 4e6 then
|
||||||
minetest.log("warning", "[mapgen_rivers] You are going to generate a very large grid (>4M nodes). If you experience problems, you should increase blocksize or reduce map size.")
|
minetest.log("warning", "[mapgen_rivers] You are going to generate a very large grid (>4M nodes). If you experience problems, you should increase blocksize or reduce map size.")
|
||||||
end
|
end
|
||||||
@ -103,19 +103,48 @@ model:flow()
|
|||||||
|
|
||||||
local mfloor = math.floor
|
local mfloor = math.floor
|
||||||
local mmin, mmax = math.min, math.max
|
local mmin, mmax = math.min, math.max
|
||||||
|
local unpk, schar = unpack, string.char
|
||||||
local offset_x, offset_y = twist(model.dirs, model.rivers, 5)
|
local offset_x, offset_y = twist(model.dirs, model.rivers, 5)
|
||||||
for i=1, X*Y do
|
for i=1, X*Y do
|
||||||
offset_x[i] = mmin(mmax(offset_x[i]*256, -128), 127)
|
offset_x[i] = mmin(mmax(offset_x[i]*256, -128), 127)
|
||||||
offset_y[i] = mmin(mmax(offset_y[i]*256, -128), 127)
|
offset_y[i] = mmin(mmax(offset_y[i]*256, -128), 127)
|
||||||
end
|
end
|
||||||
|
|
||||||
grid.dem = model.dem
|
-- Write data
|
||||||
grid.lakes = model.lakes
|
|
||||||
grid.dirs = model.dirs
|
|
||||||
grid.rivers = model.rivers
|
|
||||||
grid.offset_x = offset_x
|
|
||||||
grid.offset_y = offset_y
|
|
||||||
|
|
||||||
collectgarbage()
|
local datapath = mapgen_rivers.world_data_path
|
||||||
|
minetest.mkdir(datapath)
|
||||||
|
|
||||||
return grid
|
local sfile = io.open(datapath .. 'size', "w")
|
||||||
|
sfile:write(X..'\n'..Y)
|
||||||
|
sfile:close()
|
||||||
|
|
||||||
|
local function write_file(filename, data, bytes)
|
||||||
|
local file = io.open(datapath .. filename, 'wb')
|
||||||
|
|
||||||
|
local bytelist = {}
|
||||||
|
for j=1, bytes do
|
||||||
|
bytelist[j] = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1, #data do
|
||||||
|
local n = mfloor(data[i])
|
||||||
|
data[i] = n
|
||||||
|
for j=bytes, 2, -1 do
|
||||||
|
bytelist[j] = n % 256
|
||||||
|
n = mfloor(n / 256)
|
||||||
|
end
|
||||||
|
bytelist[1] = n % 256
|
||||||
|
|
||||||
|
file:write(schar(unpk(bytelist)))
|
||||||
|
end
|
||||||
|
|
||||||
|
file:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
write_file('dem', model.dem, 2)
|
||||||
|
write_file('lakes', model.lakes, 2)
|
||||||
|
write_file('dirs', model.dirs, 1)
|
||||||
|
write_file('rivers', model.rivers, 4)
|
||||||
|
write_file('offset_x', offset_x, 1)
|
||||||
|
write_file('offset_y', offset_y, 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user