Refactor to use only Settings objects for settings.

Also remove globally stored path for modpath and data.
Basically use less global variables for better adaptation to multithreading.
This commit is contained in:
Gaël C 2024-01-04 22:47:50 +01:00
parent 6fa1852277
commit e5b8f2b3b8
9 changed files with 131 additions and 174 deletions

View File

@ -1,10 +1,10 @@
local modpath = mapgen_rivers.modpath local modpath = minetest.get_modpath(minetest.get_current_modname())
local make_polygons = dofile(modpath .. 'polygons.lua') local make_polygons = dofile(modpath .. '/polygons.lua')
local transform_quadri = dofile(modpath .. 'geometry.lua') local transform_quadri = dofile(modpath .. '/geometry.lua')
local sea_level = mapgen_rivers.settings.sea_level local sea_level = tonumber(minetest.get_mapgen_setting("water_level"))
local riverbed_slope = mapgen_rivers.settings.riverbed_slope * mapgen_rivers.settings.blocksize local riverbed_slope = tonumber(mapgen_rivers.settings:get("riverbed_slope")) * tonumber(mapgen_rivers.settings:get("blocksize"))
local MAP_BOTTOM = -31000 local MAP_BOTTOM = -31000

View File

@ -1,9 +1,5 @@
mapgen_rivers = {} mapgen_rivers = {}
local modpath = minetest.get_modpath(minetest.get_current_modname()) .. '/'
mapgen_rivers.modpath = modpath
mapgen_rivers.world_data_path = minetest.get_worldpath() .. '/river_data/'
if minetest.get_mapgen_setting("mg_name") ~= "singlenode" then if minetest.get_mapgen_setting("mg_name") ~= "singlenode" then
minetest.set_mapgen_setting("mg_name", "singlenode", true) minetest.set_mapgen_setting("mg_name", "singlenode", true)
minetest.log("warning", "[mapgen_rivers] Mapgen set to singlenode") minetest.log("warning", "[mapgen_rivers] Mapgen set to singlenode")
@ -11,7 +7,7 @@ end
dofile(modpath .. 'settings.lua') dofile(modpath .. 'settings.lua')
local sfile = io.open(mapgen_rivers.world_data_path .. 'size') local sfile = io.open(minetest.get_worldpath() .. '/river_data/size')
if sfile then if sfile then
sfile:close() sfile:close()
else else

View File

@ -1,10 +1,16 @@
local worldpath = mapgen_rivers.world_data_path local datapath = minetest.get_worldpath() .. "/river_data/"
local floor = math.floor local floor = math.floor
local sbyte = string.byte local sbyte = string.byte
local unpk = unpack local unpk = unpack
local load_map local load_map
local use_interactive_loader
if minetest.settings:has("mapgen_rivers_use_interactive_loader") then
use_interactive_loader = minetest.settings:get_bool("mapgen_rivers_use_interactive_loader")
else
use_interactive_loader = not minetest.settings:get_bool("mapgen_rivers_load_all")
end
if mapgen_rivers.use_interactive_loader then if mapgen_rivers.use_interactive_loader then
local loader_mt = { local loader_mt = {
@ -32,7 +38,7 @@ if mapgen_rivers.use_interactive_loader then
} }
load_map = function(filename, bytes, signed, size, converter) load_map = function(filename, bytes, signed, size, converter)
local file = io.open(worldpath .. filename, 'rb') local file = io.open(datapath .. filename, 'rb')
if file then if file then
minetest.register_on_shutdown(function() minetest.register_on_shutdown(function()
file:close() file:close()
@ -45,7 +51,7 @@ if mapgen_rivers.use_interactive_loader then
else else
load_map = function(filename, bytes, signed, size, converter) load_map = function(filename, bytes, signed, size, converter)
local file = io.open(worldpath .. filename, 'rb') local file = io.open(datapath .. filename, 'rb')
local data = file:read('*all') local data = file:read('*all')
if #data < bytes*size then if #data < bytes*size then
data = minetest.decompress(data) data = minetest.decompress(data)

View File

@ -25,6 +25,7 @@ local noiseparams = {
if use_biomes then if use_biomes then
noiseparams.heat = minetest.get_mapgen_setting_noiseparams("np_heat") noiseparams.heat = minetest.get_mapgen_setting_noiseparams("np_heat")
noiseparams.heat.offset = noiseparams.heat.offset + sea_level / elevation_chill
noiseparams.heat_blend = minetest.get_mapgen_setting_noiseparams("np_heat_blend") noiseparams.heat_blend = minetest.get_mapgen_setting_noiseparams("np_heat_blend")
end end

View File

@ -1,80 +0,0 @@
local def_setting = mapgen_rivers.define_setting
mapgen_rivers.noise_params = {
base = def_setting('np_base', 'noise', {
offset = 0,
scale = 300,
seed = 2469,
octaves = 8,
spread = {x=2048, y=2048, z=2048},
persist = 0.6,
lacunarity = 2,
flags = "eased",
}),
distort_x = def_setting('np_distort_x', 'noise', {
offset = 0,
scale = 1,
seed = -4574,
spread = {x=64, y=32, z=64},
octaves = 3,
persistence = 0.75,
lacunarity = 2,
}),
distort_z = def_setting('np_distort_z', 'noise', {
offset = 0,
scale = 1,
seed = -7940,
spread = {x=64, y=32, z=64},
octaves = 3,
persistence = 0.75,
lacunarity = 2,
}),
distort_amplitude = def_setting('np_distort_amplitude', 'noise', {
offset = 0,
scale = 10,
seed = 676,
spread = {x=1024, y=1024, z=1024},
octaves = 5,
persistence = 0.5,
lacunarity = 2,
flags = "absvalue",
}),
heat = minetest.get_mapgen_setting_noiseparams('mg_biome_np_heat'),
heat_blend = minetest.get_mapgen_setting_noiseparams('mg_biome_np_heat_blend'),
}
-- Convert to number because Minetest API is not able to do it cleanly...
for name, np in pairs(mapgen_rivers.noise_params) do
for field, value in pairs(np) do
if field ~= 'flags' and type(value) == 'string' then
np[field] = tonumber(value) or value
elseif field == 'spread' then
for dir, v in pairs(value) do
value[dir] = tonumber(v) or v
end
end
end
end
local heat = mapgen_rivers.noise_params.heat
local base = mapgen_rivers.noise_params.base
local settings = mapgen_rivers.settings
heat.offset = heat.offset + settings.sea_level * settings.elevation_chill
base.spread.x = base.spread.x / settings.blocksize
base.spread.y = base.spread.y / settings.blocksize
base.spread.z = base.spread.z / settings.blocksize
for name, np in pairs(mapgen_rivers.noise_params) do
local lac = np.lacunarity or 2
if lac > 1 then
local omax = math.floor(math.log(math.min(np.spread.x, np.spread.y, np.spread.z)) / math.log(lac))+1
if np.octaves > omax then
minetest.log("warning", "[mapgen_rivers] Noise " .. name .. ": 'octaves' reduced to " .. omax)
np.octaves = omax
end
end
end

View File

@ -9,7 +9,6 @@ local settings = mapgen_rivers.settings
local blocksize = tonumber(settings:get('blocksize')) local blocksize = tonumber(settings:get('blocksize'))
local min_catchment = tonumber(settings:get('min_catchment')) local min_catchment = tonumber(settings:get('min_catchment'))
local max_catchment = tonumber(settings:get('max_catchment'))
local map_offset = {x=0, z=0} local map_offset = {x=0, z=0}
if settings:get_bool('center') then if settings:get_bool('center') then

View File

@ -1,15 +1,24 @@
local EvolutionModel = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/erosion.lua') local modpath = minetest.get_modpath(minetest.get_current_modname())
local twist = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/twist.lua')
local blocksize = mapgen_rivers.settings.blocksize local EvolutionModel = dofile(modpath .. '/terrainlib_lua/erosion.lua')
local tectonic_speed = mapgen_rivers.settings.tectonic_speed local twist = dofile(modpath .. '/terrainlib_lua/twist.lua')
local np_base = table.copy(mapgen_rivers.noise_params.base) local blocksize = tonumber(mapgen_rivers.settings:get("blocksize"))
local tectonic_speed = tonumber(mapgen_rivers.settings:get("tectonic_speed"))
local evol_params = mapgen_rivers.settings.evol_params local np_base = mapgen_rivers.settings:get_np_group("np_base")
np_base.spread.x = np_base.spread.x / blocksize
np_base.spread.y = np_base.spread.y / blocksize
np_base.spread.z = np_base.spread.z / blocksize
local time = mapgen_rivers.settings.evol_time local evol_params = {
local time_step = mapgen_rivers.settings.evol_time_step K = tonumber(mapgen_rivers.settings:get("river_erosion_coef")),
m = tonumber(mapgen_rivers.settings:get("river_erosion_power")),
d = tonumber(mapgen_rivers.settings:get("difusive_erosion")),
}
local time = tonumber(mapgen_rivers.settings:get("evol_time"))
local time_step = tonumber(mapgen_rivers.settings:get("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
@ -60,11 +69,12 @@ for i=1, size.x*size.y do
end end
-- Write the results in the world directory -- Write the results in the world directory
minetest.mkdir(mapgen_rivers.world_data_path) local datapath = minetest.get_worldpath .. "/river_data/"
minetest.mkdir(datapath)
local function write_map(filename, data, bytes) local function write_map(filename, data, bytes)
local size = #data local size = #data
local file = io.open(worldpath .. filename, 'wb') local file = io.open(datapath .. filename, 'wb')
local bytelist = {} local bytelist = {}
for j=1, bytes do for j=1, bytes do
@ -95,11 +105,18 @@ write_map('dirs', model.dirs, 1)
write_map('rivers', model.rivers, 4) write_map('rivers', model.rivers, 4)
write_map('offset_x', offset_x, 1) write_map('offset_x', offset_x, 1)
write_map('offset_y', offset_y, 1) write_map('offset_y', offset_y, 1)
local sfile = io.open(mapgen_rivers.world_data_path .. 'size', "w") local sfile = io.open(datapath .. 'size', "w")
sfile:write(size.x..'\n'..size.y) sfile:write(size.x..'\n'..size.y)
sfile:close() sfile:close()
if not mapgen_rivers.settings.use_interactive_loader then local use_interactive_loader
if minetest.settings:has("mapgen_rivers_use_interactive_loader") then
use_interactive_loader = minetest.settings:get_bool("mapgen_rivers_use_interactive_loader")
else
use_interactive_loader = not minetest.settings:get_bool("mapgen_rivers_load_all")
end
if not use_interactive_loader then
mapgen_rivers.grid = { mapgen_rivers.grid = {
size = {x=size_x, y=size_y}, size = {x=size_x, y=size_y},
dem = model.dem, dem = model.dem,

View File

@ -1,11 +1,11 @@
local mtsettings = minetest.settings local mtsettings = minetest.settings
local mgrsettings = Settings(minetest.get_worldpath() .. '/mapgen_rivers.conf') local settings = Settings(minetest.get_worldpath() .. '/mapgen_rivers.conf')
mapgen_rivers.version = "1.0.2" mapgen_rivers.version = "1.0.2"
mapgen_rivers.settings = settings mapgen_rivers.settings = settings
local previous_version_mt = mtsettings:get("mapgen_rivers_version") or "0.0" local previous_version_mt = mtsettings:get("mapgen_rivers_version") or "0.0"
local previous_version_mgr = mgrsettings:get("version") or "0.0" local previous_version_mgr = settings:get("version") or "0.0"
if mapgen_rivers.version ~= previous_version_mt or mapgen_rivers.version ~= previous_version_mgr then if mapgen_rivers.version ~= previous_version_mt or mapgen_rivers.version ~= previous_version_mgr then
local compat_mt, compat_mgr = dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/compatibility.lua") local compat_mt, compat_mgr = dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/compatibility.lua")
@ -13,81 +13,103 @@ if mapgen_rivers.version ~= previous_version_mt or mapgen_rivers.version ~= prev
compat_mt(mtsettings) compat_mt(mtsettings)
end end
if mapgen_rivers.version ~= previous_version_mgr then if mapgen_rivers.version ~= previous_version_mgr then
compat_mgr(mgrsettings) compat_mgr(settings)
end end
end end
mtsettings:set("mapgen_rivers_version", mapgen_rivers.version) mtsettings:set("mapgen_rivers_version", mapgen_rivers.version)
mgrsettings:set("version", mapgen_rivers.version) settings:set("version", mapgen_rivers.version)
function mapgen_rivers.define_setting(name, dtype, default) local modified = false
local function verify_setting(name, dtype, default)
if settings:has(name) then
return
end
modified = true
local v = default
local mtname = 'mapgen_rivers_' .. name
local mthas = mtsettings:has(mtname)
if dtype == "number" or dtype == "string" then if dtype == "number" or dtype == "string" then
local v = mgrsettings:get(name) if mthas then
if v == nil then v = mtsettings:get(mtname)
v = mtsettings:get('mapgen_rivers_' .. name) if dtype == "number" and tonumber(v) == nil then
if v == nil then
v = default v = default
end end
mgrsettings:set(name, v)
end
if dtype == "number" then
return tonumber(v)
else
return v
end end
settings:set(name, v)
elseif dtype == "bool" then elseif dtype == "bool" then
local v = mgrsettings:get_bool(name) if mthas then
if v == nil then v = mtsettings:get(mtname)
v = mtsettings:get_bool('mapgen_rivers_' .. name)
if v == nil then
v = default
end
mgrsettings:set_bool(name, v)
end end
return v settings:set_bool(name, v)
elseif dtype == "noise" then elseif dtype = "noise" then
local v = mgrsettings:get_np_group(name) if mthas then
if v == nil then v = mtsettings:get_np_group(mtname)
v = mtsettings:get_np_group('mapgen_rivers_' .. name)
if v == nil then
v = default
end
mgrsettings:set_np_group(name, v)
end end
return v settings:set_np_group(name, v)
end end
end end
local def_setting = mapgen_rivers.define_setting verify_setting('center', 'bool', true)
verify_setting('blocksize', 'number', 15)
verify_setting('min_catchment', 'number', 3600)
verify_setting('river_widening_power', 'number', 0.5)
verify_setting('riverbed_slope', 'number', 0.4)
verify_setting('distort', 'bool', true)
verify_setting('biomes', 'bool', true)
verify_setting('glaciers', 'bool', false)
verify_setting('glacier_factor', 'number', 8)
verify_setting('elevation_chill', 'number', 0.25)
verify_setting('grid_x_size', 'number', 1000)
verify_setting('grid_z_size', 'number', 1000)
verify_setting('river_erosion_coef', 'number', 0.5)
verify_setting('river_erosion_power', 'number', 0.4)
verify_setting('diffusive_erosion', 'number', 0.5)
verify_setting('compensation_radius', 'number', 50)
verify_setting('tectonic_speed', 'number', 70)
verify_setting('evol_time', 'number', 10)
verify_setting('evol_time_step', 'number', 1)
mapgen_rivers.settings = { verify_setting('np_base', 'noise', {
center = def_setting('center', 'bool', true), offset = 0,
blocksize = def_setting('blocksize', 'number', 15), scale = 300,
sea_level = tonumber(minetest.get_mapgen_setting('water_level')), seed = 2469,
min_catchment = def_setting('min_catchment', 'number', 3600), octaves = 8,
river_widening_power = def_setting('river_widening_power', 'number', 0.5), spread = {x=2048, y=2048, z=2048},
riverbed_slope = def_setting('riverbed_slope', 'number', 0.4), persist = 0.6,
distort = def_setting('distort', 'bool', true), lacunarity = 2,
biomes = def_setting('biomes', 'bool', true), flags = "eased",
glaciers = def_setting('glaciers', 'bool', false), })
glacier_factor = def_setting('glacier_factor', 'number', 8), verify_setting('np_distort_x', 'noise', {
elevation_chill = def_setting('elevation_chill', 'number', 0.25), offset = 0,
scale = 1,
seed = -4574,
spread = {x=64, y=32, z=64},
octaves = 3,
persistence = 0.75,
lacunarity = 2,
})
verify_setting('np_distort_z', 'noise', {
offset = 0,
scale = 1,
seed = -7940,
spread = {x=64, y=32, z=64},
octaves = 3,
persistence = 0.75,
lacunarity = 2,
})
verify_setting('np_distort_amplitude', 'noise', {
offset = 0,
scale = 10,
seed = 676,
spread = {x=1024, y=1024, z=1024},
octaves = 5,
persistence = 0.5,
lacunarity = 2,
flags = "absvalue",
})
grid_x_size = def_setting('grid_x_size', 'number', 1000), if modified then
grid_z_size = def_setting('grid_z_size', 'number', 1000), settings:write()
evol_params = { end
K = def_setting('river_erosion_coef', 'number', 0.5),
m = def_setting('river_erosion_power', 'number', 0.4),
d = def_setting('diffusive_erosion', 'number', 0.5),
compensation_radius = def_setting('compensation_radius', 'number', 50),
},
tectonic_speed = def_setting('tectonic_speed', 'number', 70),
evol_time = def_setting('evol_time', 'number', 10),
evol_time_step = def_setting('evol_time_step', 'number', 1),
load_all = mtsettings:get_bool('mapgen_rivers_load_all')
}
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/noises.lua")
mgrsettings:write()

View File

@ -123,11 +123,7 @@ end
local modpath = "" local modpath = ""
if minetest then if minetest then
if minetest.global_exists('mapgen_rivers') then modpath = minetest.get_modpath(minetest.get_current_modname()) .. "terrainlib_lua/"
modpath = mapgen_rivers.modpath .. "terrainlib_lua/"
else
modpath = minetest.get_modpath(minetest.get_current_modname()) .. "terrainlib_lua/"
end
end end
local rivermapper = dofile(modpath .. "rivermapper.lua") local rivermapper = dofile(modpath .. "rivermapper.lua")