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
|
||||
|
||||
local world_data = mapgen_rivers.world_data_path
|
||||
local datapath = mapgen_rivers.world_data_path
|
||||
|
||||
local registered_on_grid_loaded = {}
|
||||
function mapgen_rivers.register_on_grid_loaded(func)
|
||||
@ -21,32 +21,65 @@ local function offset_conv(o)
|
||||
return (o + 0.5) * (1/256)
|
||||
end
|
||||
|
||||
local grid_maps_list = {
|
||||
dem = {bytes=2, signed=true},
|
||||
lakes = {bytes=2, signed=true},
|
||||
dirs = {bytes=1, signed=false},
|
||||
rivers = {bytes=4, signed=false},
|
||||
local floor = math.floor
|
||||
local sbyte, schar = string.byte, string.char
|
||||
local unpk = unpack
|
||||
|
||||
offset_x = {bytes=1, signed=true, conv=offset_conv},
|
||||
offset_y = {bytes=1, signed=true, conv=offset_conv},
|
||||
-- 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.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
|
||||
if mapgen_rivers.grid then
|
||||
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
|
||||
|
||||
-- Fall back to loading the grid from the files
|
||||
local sfile = io.open(world_data .. 'size', 'r')
|
||||
-- If not, try to load the grid from the files
|
||||
local sfile = io.open(datapath .. 'size', 'r')
|
||||
if not sfile then
|
||||
dofile(mapgen_rivers.modpath .. "/pregenerate.lua")
|
||||
collectgarbage()
|
||||
|
||||
sfile = io.open(datapath .. 'size', 'r')
|
||||
if not sfile then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local x, z = sfile:read('*n'), sfile:read('*n')
|
||||
if not x or not z then
|
||||
@ -55,31 +88,18 @@ function mapgen_rivers.try_load_grid(grid)
|
||||
|
||||
minetest.log("action", '[mapgen_rivers] Loading grid')
|
||||
|
||||
grid = {
|
||||
local grid = {
|
||||
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
|
||||
on_grid_loaded_callback(grid)
|
||||
|
||||
return true
|
||||
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 .. 'gridmanager.lua')
|
||||
dofile(modpath .. 'gridio.lua')
|
||||
dofile(modpath .. 'polygons.lua')
|
||||
dofile(modpath .. 'heightmap.lua')
|
||||
dofile(modpath .. 'mapgen.lua')
|
||||
|
||||
minetest.register_on_mods_loaded(function()
|
||||
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)
|
||||
minetest.register_on_mods_loaded(mapgen_rivers.load_or_generate_grid)
|
||||
|
@ -1,6 +1,8 @@
|
||||
-- Generate the grid using terrainlib_lua
|
||||
-- Only called on first mapgen, if there is no grid yet
|
||||
|
||||
-- Constants
|
||||
|
||||
local EvolutionModel = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/erosion.lua')
|
||||
local twist = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/twist.lua')
|
||||
|
||||
@ -52,12 +54,10 @@ local function margin(dem, width, elev)
|
||||
end
|
||||
end
|
||||
|
||||
-- Generate the grid
|
||||
-- Generate grid
|
||||
|
||||
minetest.log("action", '[mapgen_rivers] Generating grid, this may take a while...')
|
||||
|
||||
local grid = {size={x=X, y=Y}}
|
||||
|
||||
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.")
|
||||
end
|
||||
@ -103,19 +103,48 @@ model:flow()
|
||||
|
||||
local mfloor = math.floor
|
||||
local mmin, mmax = math.min, math.max
|
||||
local unpk, schar = unpack, string.char
|
||||
local offset_x, offset_y = twist(model.dirs, model.rivers, 5)
|
||||
for i=1, X*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
|
||||
|
||||
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
|
||||
-- Write data
|
||||
|
||||
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