2022-01-26 11:25:17 +01:00
|
|
|
-- Manages grid loading, writing and generation
|
|
|
|
|
2022-01-25 19:09:24 +01:00
|
|
|
local world_data = mapgen_rivers.world_data_path
|
|
|
|
|
|
|
|
local registered_on_grid_loaded = {}
|
|
|
|
function mapgen_rivers.register_on_grid_loaded(func)
|
|
|
|
if type(func) == "function" then
|
|
|
|
registered_on_grid_loaded[#registered_on_grid_loaded+1] = func
|
|
|
|
else
|
|
|
|
minetest.log("error", "[mapgen_rivers] register_on_grid_loaded can only register functions!")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function on_grid_loaded_callback(grid)
|
|
|
|
for _, func in ipairs(registered_on_grid_loaded) do
|
|
|
|
func(grid)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
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},
|
|
|
|
|
|
|
|
offset_x = {bytes=1, signed=true, conv=offset_conv},
|
|
|
|
offset_y = {bytes=1, signed=true, conv=offset_conv},
|
|
|
|
}
|
|
|
|
|
|
|
|
local function apply_grid_conversion(grid)
|
|
|
|
if grid.load_method ~= "full" then
|
|
|
|
minetest.log("warning", ("Could not apply data conversion for load method %s"):format(grid.load_method))
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
if grid.conv_applied then
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
local size = grid.size.x * grid.size.y
|
|
|
|
for mapname, params in pairs(grid_maps_list) do
|
|
|
|
local conv = params.conv
|
|
|
|
if conv then
|
|
|
|
local map = grid[mapname]
|
|
|
|
for i=1, size do
|
|
|
|
map[i] = conv(map[i])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
grid.conv_applied = true
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function mapgen_rivers.try_load_grid(grid)
|
|
|
|
local load_method = mapgen_rivers.settings.load_method
|
|
|
|
|
|
|
|
-- First, check whether a grid is already loaded with the appropriate method
|
|
|
|
if mapgen_rivers.grid and mapgen_rivers.grid.load_method == load_method then
|
|
|
|
if not mapgen_rivers.grid.conv_applied then
|
|
|
|
apply_grid_conversion(mapgen_rivers.grid)
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
-- Then, check the provided argument is a valid grid
|
|
|
|
elseif grid and grid.load_method == load_method then
|
|
|
|
if not mapgen_rivers.grid.conv_applied then
|
|
|
|
apply_grid_conversion(grid)
|
|
|
|
end
|
|
|
|
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 sfile then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
local x, z = sfile:read('*n'), sfile:read('*n')
|
|
|
|
if not x or not z then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
if load_method == "full" then
|
|
|
|
minetest.log("action", '[mapgen_rivers] Loading full grid')
|
|
|
|
elseif load_method == "interactive" then
|
|
|
|
minetest.log("action", '[mapgen_rivers] Loading grid as interactive loaders')
|
|
|
|
end
|
|
|
|
|
|
|
|
grid = {
|
|
|
|
load_method = load_method,
|
|
|
|
size = {x=x, y=z},
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
grid.conv_applied = true
|
|
|
|
|
|
|
|
mapgen_rivers.grid = grid
|
|
|
|
on_grid_loaded_callback(grid)
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
function mapgen_rivers.generate_grid()
|
|
|
|
minetest.log("action", '[mapgen_rivers] Generating grid, this may take a while...')
|
|
|
|
local grid = {}
|
|
|
|
|
|
|
|
local blocksize = mapgen_rivers.settings.blocksize
|
|
|
|
local xsize = math.floor(mapgen_rivers.settings.map_x_size / blocksize)
|
|
|
|
local zsize = math.floor(mapgen_rivers.settings.map_z_size / blocksize)
|
|
|
|
grid.size = {x=xsize, y=zsize}
|
|
|
|
grid.conv_applied = false
|
|
|
|
|
|
|
|
if not mapgen_rivers.pregenerate then
|
|
|
|
minetest.log("error", "[mapgen_rivers] Pre-generation function is not available.")
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
mapgen_rivers.pregenerate(grid)
|
|
|
|
|
|
|
|
return grid
|
|
|
|
end
|
|
|
|
|
|
|
|
function mapgen_rivers.write_grid(grid)
|
|
|
|
minetest.mkdir(world_data)
|
|
|
|
|
|
|
|
if grid.conv_applied then
|
|
|
|
minetest.log("error", '[mapgen_rivers] Could not write grid if data conversion is already done')
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
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
|
|
|
|
|