diff --git a/generate.lua b/generate.lua index ddfdb3e..79c4ef4 100644 --- a/generate.lua +++ b/generate.lua @@ -1,21 +1,15 @@ local EvolutionModel = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/erosion.lua') local twist = dofile(mapgen_rivers.modpath .. '/terrainlib_lua/twist.lua') -local blocksize = 12 -local variation_speed = 70 +local blocksize = mapgen_rivers.settings.blocksize +local tectonic_speed = mapgen_rivers.settings.tectonic_speed -local np_base = { - offset = 0, - scale = 200, - seed = 2469, - octaves = 8, - spread = {x=4000/blocksize, y=4000/blocksize, z=4000/blocksize}, - persist = 0.6, - lacunarity = 2, -} +local np_base = table.copy(mapgen_rivers.noise_params.base) -local time = 10 -local time_step = 1 +local evol_params = mapgen_rivers.settings.evol_params + +local time = mapgen_rivers.settings.evol_time +local time_step = mapgen_rivers.settings.evol_time_step local niter = math.ceil(time/time_step) time_step = time / niter @@ -34,19 +28,23 @@ local function generate() dem.X = size.x dem.Y = size.y - local model = EvolutionModel() + local model = EvolutionModel(evol_params) model.dem = dem local ref_dem = model:define_isostasy(dem) - local variation_step = variation_speed * time_step + local tectonic_step = tectonic_speed * time_step for i=1, niter do --nobj_base:get_map_slice({z=i+1}, {z=1}, ref_dem) - nobj_base:get_3d_map_flat({x=0, y=variation_step*i, z=0}, ref_dem) model:diffuse(time_step) model:flow() model:erode(time_step) - model:isostasy() + if i < niter then + if tectonic_step ~= 0 then + nobj_base:get_3d_map_flat({x=0, y=tectonic_step*i, z=0}, ref_dem) + end + model:isostasy() + end end model:flow() diff --git a/heightmap.lua b/heightmap.lua index 9ffec1b..b41236c 100644 --- a/heightmap.lua +++ b/heightmap.lua @@ -3,9 +3,8 @@ local modpath = mapgen_rivers.modpath local make_polygons = dofile(modpath .. 'polygons.lua') local transform_quadri = dofile(modpath .. 'geometry.lua') -local blocksize = mapgen_rivers.blocksize -local sea_level = mapgen_rivers.sea_level -local riverbed_slope = mapgen_rivers.riverbed_slope +local sea_level = mapgen_rivers.settings.sea_level +local riverbed_slope = mapgen_rivers.settings.riverbed_slope * mapgen_rivers.settings.blocksize local MAP_BOTTOM = -31000 diff --git a/init.lua b/init.lua index 5e0faea..cd2ab57 100644 --- a/init.lua +++ b/init.lua @@ -6,12 +6,10 @@ mapgen_rivers.world_data_path = minetest.get_worldpath() .. '/river_data/' dofile(modpath .. 'settings.lua') -local blocksize = mapgen_rivers.blocksize -local sea_level = mapgen_rivers.sea_level -local riverbed_slope = mapgen_rivers.riverbed_slope -local elevation_chill = mapgen_rivers.elevation_chill -local use_distort = mapgen_rivers.distort -local use_biomes = mapgen_rivers.biomes +local sea_level = mapgen_rivers.settings.sea_level +local elevation_chill = mapgen_rivers.settings.elevation_chill +local use_distort = mapgen_rivers.settings.distort +local use_biomes = mapgen_rivers.settings.biomes local use_biomegen_mod = use_biomes and minetest.global_exists('biomegen') use_biomes = use_biomes and not use_biomegen_mod diff --git a/noises.lua b/noises.lua index a6d96bb..89f16c1 100644 --- a/noises.lua +++ b/noises.lua @@ -1,5 +1,17 @@ +local def_setting = mapgen_rivers.define_setting + mapgen_rivers.noise_params = { - distort_x = { + base = def_setting('np_base', 'noise', { + offset = 0, + scale = 200, + seed = 2469, + octaves = 8, + spread = {x=4000, y=4000, z=4000}, + persist = 0.6, + lacunarity = 2, + }), + + distort_x = def_setting('np_distort_x', 'noise', { offset = 0, scale = 1, seed = -4574, @@ -7,9 +19,9 @@ mapgen_rivers.noise_params = { octaves = 3, persistence = 0.75, lacunarity = 2, - }, + }), - distort_z = { + distort_z = def_setting('np_distort_z', 'noise', { offset = 0, scale = 1, seed = -7940, @@ -17,9 +29,9 @@ mapgen_rivers.noise_params = { octaves = 3, persistence = 0.75, lacunarity = 2, - }, + }), - distort_amplitude = { + distort_amplitude = def_setting('np_distort_amplitude', 'noise', { offset = 0, scale = 10, seed = 676, @@ -28,10 +40,40 @@ mapgen_rivers.noise_params = { 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'), } -mapgen_rivers.noise_params.heat.offset = mapgen_rivers.noise_params.heat.offset + mapgen_rivers.sea_level*mapgen_rivers.elevation_chill +-- 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 + print("[mapgen_rivers] Noise " .. name .. ": 'octaves' reduced to " .. omax) + np.octaves = omax + end + end +end diff --git a/polygons.lua b/polygons.lua index 1459b45..2e4c57e 100644 --- a/polygons.lua +++ b/polygons.lua @@ -49,12 +49,12 @@ local function index(x, z) return z*X+x+1 end -local blocksize = mapgen_rivers.blocksize -local min_catchment = mapgen_rivers.min_catchment -local max_catchment = mapgen_rivers.max_catchment +local blocksize = mapgen_rivers.settings.blocksize +local min_catchment = mapgen_rivers.settings.min_catchment +local max_catchment = mapgen_rivers.settings.max_catchment local map_offset = {x=0, z=0} -if mapgen_rivers.center then +if mapgen_rivers.settings.center then map_offset.x = blocksize*X/2 map_offset.z = blocksize*Z/2 end @@ -74,14 +74,14 @@ local function river_width(flow) end local noise_heat -- Need a large-scale noise here so no heat blend -local elevation_chill = mapgen_rivers.elevation_chill +local elevation_chill = mapgen_rivers.settings.elevation_chill local function get_temperature(x, y, z) local pos = {x=x, y=z} return noise_heat:get2d(pos) - y*elevation_chill end -local glaciers = mapgen_rivers.glaciers -local glacier_factor = mapgen_rivers.glacier_factor +local glaciers = mapgen_rivers.settings.glaciers +local glacier_factor = mapgen_rivers.settings.glacier_factor local init = false diff --git a/settings.lua b/settings.lua index a02bd6f..a49832c 100644 --- a/settings.lua +++ b/settings.lua @@ -1,58 +1,71 @@ -local storage = minetest.get_mod_storage() -local settings = minetest.settings - -local function get_settings(key, dtype, default) - if storage:contains(key) then - if dtype == "string" then - return storage:get_string(key) - elseif dtype == "int" then - return storage:get_int(key) - elseif dtype == "float" then - return storage:get_float(key) - elseif dtype == "bool" then - return storage:get_string(key) == 'true' - end - end - - local conf_val = settings:get('mapgen_rivers_' .. key) - if conf_val then - if dtype == "int" then - conf_val = tonumber(conf_val) - storage:set_int(key, conf_val) - elseif dtype == "float" then - conf_val = tonumber(conf_val) - storage:set_float(key, conf_val) - else - storage:set_string(key, conf_val) - if dtype == "bool" then - conf_val = conf_val == 'true' +local mtsettings = minetest.settings +local mgrsettings = Settings(minetest.get_worldpath() .. '/mapgen_rivers.conf') +function mapgen_rivers.define_setting(name, dtype, default) + if dtype == "number" or dtype == "string" then + local v = mgrsettings:get(name) + if v == nil then + v = mtsettings:get('mapgen_rivers_' .. name) + if v == nil then + v = default end + mgrsettings:set(name, v) end - - return conf_val - else - if dtype == "int" then - storage:set_int(key, default) - elseif dtype == "float" then - storage:set_float(key, default) - elseif dtype == "string" then - storage:set_string(key, default) - elseif dtype == "bool" then - storage:set_string(key, tostring(default)) + if dtype == "number" then + return tonumber(v) + else + return v end - - return default + elseif dtype == "bool" then + local v = mgrsettings:get_bool(name) + if v == nil then + v = mtsettings:get_bool('mapgen_rivers_' .. name) + if v == nil then + v = default + end + mgrsettings:set_bool(name, v) + end + return v + elseif dtype == "noise" then + local v = mgrsettings:get_np_group(name) + if v == nil then + v = mtsettings:get_np_group('mapgen_rivers_' .. name) + if v == nil then + v = default + end + mgrsettings:set_np_group(name, v) + end + return v end end -mapgen_rivers.center = get_settings('center', 'bool', false) -mapgen_rivers.blocksize = get_settings('blocksize', 'int', 12) -mapgen_rivers.sea_level = get_settings('sea_level', 'int', 1) -mapgen_rivers.min_catchment = get_settings('min_catchment', 'float', 25) -mapgen_rivers.max_catchment = get_settings('max_catchment', 'float', 40000) -mapgen_rivers.riverbed_slope = get_settings('riverbed_slope', 'float', 0.4) * mapgen_rivers.blocksize -mapgen_rivers.distort = get_settings('distort', 'bool', true) -mapgen_rivers.biomes = get_settings('biomes', 'bool', true) -mapgen_rivers.glaciers = get_settings('glaciers', 'bool', false) -mapgen_rivers.glacier_factor = get_settings('glacier_factor', 'float', 8) -mapgen_rivers.elevation_chill = get_settings('elevation_chill', 'float', 0.25) +local def_setting = mapgen_rivers.define_setting + +mapgen_rivers.settings = { + center = def_setting('center', 'bool', false), + blocksize = def_setting('blocksize', 'number', 12), + sea_level = tonumber(minetest.get_mapgen_setting('water_level')), + min_catchment = def_setting('min_catchment', 'number', 25), + max_catchment = def_setting('max_catchment', 'number', 40000), + riverbed_slope = def_setting('riverbed_slope', 'number', 0.4), + distort = def_setting('distort', 'bool', true), + biomes = def_setting('biomes', 'bool', true), + glaciers = def_setting('glaciers', 'bool', false), + glacier_factor = def_setting('glacier_factor', 'number', 8), + elevation_chill = def_setting('elevation_chill', 'number', 0.25), + + evol_params = { + 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), + }, + 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), +} + +local function write_settings() + mgrsettings:write() +end + +minetest.register_on_mods_loaded(write_settings) +minetest.register_on_shutdown(write_settings)