2022-01-26 11:25:17 +01:00
|
|
|
-- Manages grid loading, writing and generation
|
|
|
|
|
2024-02-01 19:30:07 +01:00
|
|
|
local datapath = mapgen_rivers.world_data_path
|
2022-01-25 19:09:24 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2024-02-01 19:30:07 +01:00
|
|
|
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,
|
2022-01-25 19:09:24 +01:00
|
|
|
}
|
|
|
|
|
2024-02-01 19:30:07 +01:00
|
|
|
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()
|
2024-01-31 10:47:37 +01:00
|
|
|
-- First, check whether a grid is already loaded
|
|
|
|
if mapgen_rivers.grid then
|
2022-01-25 19:09:24 +01:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2024-02-01 19:30:07 +01:00
|
|
|
-- If not, try to load the grid from the files
|
|
|
|
local sfile = io.open(datapath .. 'size', 'r')
|
2022-01-25 19:09:24 +01:00
|
|
|
if not sfile then
|
2024-02-01 19:30:07 +01:00
|
|
|
dofile(mapgen_rivers.modpath .. "/pregenerate.lua")
|
|
|
|
collectgarbage()
|
|
|
|
|
|
|
|
sfile = io.open(datapath .. 'size', 'r')
|
|
|
|
if not sfile then
|
|
|
|
return false
|
|
|
|
end
|
2022-01-25 19:09:24 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
local x, z = sfile:read('*n'), sfile:read('*n')
|
|
|
|
if not x or not z then
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
2024-01-31 10:47:37 +01:00
|
|
|
minetest.log("action", '[mapgen_rivers] Loading grid')
|
2022-01-25 19:09:24 +01:00
|
|
|
|
2024-02-01 19:30:07 +01:00
|
|
|
local grid = {
|
2022-01-25 19:09:24 +01:00
|
|
|
size = {x=x, y=z},
|
2024-02-01 19:30:07 +01:00
|
|
|
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),
|
2022-01-25 19:09:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
mapgen_rivers.grid = grid
|
|
|
|
on_grid_loaded_callback(grid)
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|