]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - builtin/mainmenu/dlg_settings_advanced.lua
Merge branch 'master' of https://github.com/minetest/minetest
[dragonfireclient.git] / builtin / mainmenu / dlg_settings_advanced.lua
index cac9f6983f5b05768e635b3d75dd5f02e6e2fc7e..d6f485cf73d29c2176b1c16a51bf8b2e94e9b2d4 100644 (file)
@@ -25,8 +25,16 @@ local CHAR_CLASSES = {
        FLAGS = "[%w_%-%.,]",
 }
 
+local function flags_to_table(flags)
+       return flags:gsub("%s+", ""):split(",", true) -- Remove all spaces and split
+end
+
 -- returns error message, or nil
 local function parse_setting_line(settings, line, read_all, base_level, allow_secure)
+
+       -- strip carriage returns (CR, /r)
+       line = line:gsub("\r", "")
+
        -- comment
        local comment = line:match("^#" .. CHAR_CLASSES.SPACE .. "*(.*)$")
        if comment then
@@ -111,7 +119,7 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se
                return
        end
 
-       if setting_type == "string" or setting_type == "noise_params"
+       if setting_type == "string"
                        or setting_type == "key" or setting_type == "v3f" then
                local default = remaining_line:match("^(.*)$")
 
@@ -133,6 +141,60 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se
                return
        end
 
+       if setting_type == "noise_params_2d"
+                       or setting_type == "noise_params_3d" then
+               local default = remaining_line:match("^(.*)$")
+
+               if not default then
+                       return "Invalid string setting"
+               end
+
+               local values = {}
+               local ti = 1
+               local index = 1
+               for match in default:gmatch("[+-]?[%d.-e]+") do -- All numeric characters
+                       index = default:find("[+-]?[%d.-e]+", index) + match:len()
+                       table.insert(values, match)
+                       ti = ti + 1
+                       if ti > 9 then
+                               break
+                       end
+               end
+               index = default:find("[^, ]", index)
+               local flags = ""
+               if index then
+                       flags = default:sub(index)
+                       default = default:sub(1, index - 3) -- Make sure no flags in single-line format
+               end
+               table.insert(values, flags)
+
+               table.insert(settings, {
+                       name = name,
+                       readable_name = readable_name,
+                       type = setting_type,
+                       default = default,
+                       default_table = {
+                               offset = values[1],
+                               scale = values[2],
+                               spread = {
+                                       x = values[3],
+                                       y = values[4],
+                                       z = values[5]
+                               },
+                               seed = values[6],
+                               octaves = values[7],
+                               persistence = values[8],
+                               lacunarity = values[9],
+                               flags = values[10]
+                       },
+                       values = values,
+                       comment = current_comment,
+                       noise_params = true,
+                       flags = flags_to_table("defaults,eased,absvalue")
+               })
+               return
+       end
+
        if setting_type == "bool" then
                if remaining_line ~= "false" and remaining_line ~= "true" then
                        return "Invalid boolean setting"
@@ -236,7 +298,7 @@ local function parse_setting_line(settings, line, read_all, base_level, allow_se
                        readable_name = readable_name,
                        type = "flags",
                        default = default,
-                       possible = possible,
+                       possible = flags_to_table(possible),
                        comment = current_comment,
                })
                return
@@ -264,29 +326,32 @@ end
 -- read_all: whether to ignore certain setting types for GUI or not
 -- parse_mods: whether to parse settingtypes.txt in mods and games
 local function parse_config_file(read_all, parse_mods)
-       local builtin_path = core.get_builtin_path() .. DIR_DELIM .. FILENAME
-       local file = io.open(builtin_path, "r")
        local settings = {}
-       if not file then
-               core.log("error", "Can't load " .. FILENAME)
-               return settings
-       end
 
-       parse_single_file(file, builtin_path, read_all, settings, 0, true)
+       do
+               local builtin_path = core.get_builtin_path() .. FILENAME
+               local file = io.open(builtin_path, "r")
+               if not file then
+                       core.log("error", "Can't load " .. FILENAME)
+                       return settings
+               end
+
+               parse_single_file(file, builtin_path, read_all, settings, 0, true)
 
-       file:close()
+               file:close()
+       end
 
        if parse_mods then
                -- Parse games
                local games_category_initialized = false
                local index = 1
-               local game = gamemgr.get_game(index)
+               local game = pkgmgr.get_game(index)
                while game do
                        local path = game.path .. DIR_DELIM .. FILENAME
                        local file = io.open(path, "r")
                        if file then
                                if not games_category_initialized then
-                                       local translation = fgettext_ne("Games"), -- not used, but needed for xgettext
+                                       fgettext_ne("Games") -- not used, but needed for xgettext
                                        table.insert(settings, {
                                                name = "Games",
                                                level = 0,
@@ -307,19 +372,19 @@ local function parse_config_file(read_all, parse_mods)
                        end
 
                        index = index + 1
-                       game = gamemgr.get_game(index)
+                       game = pkgmgr.get_game(index)
                end
 
                -- Parse mods
                local mods_category_initialized = false
                local mods = {}
-               get_mods(core.get_modpath(), mods)
+               get_mods(core.get_modpath(), "mods", mods)
                for _, mod in ipairs(mods) do
                        local path = mod.path .. DIR_DELIM .. FILENAME
                        local file = io.open(path, "r")
                        if file then
                                if not mods_category_initialized then
-                                       local translation = fgettext_ne("Mods"), -- not used, but needed for xgettext
+                                       fgettext_ne("Mods") -- not used, but needed for xgettext
                                        table.insert(settings, {
                                                name = "Mods",
                                                level = 0,
@@ -330,6 +395,37 @@ local function parse_config_file(read_all, parse_mods)
 
                                table.insert(settings, {
                                        name = mod.name,
+                                       readable_name = mod.title,
+                                       level = 1,
+                                       type = "category",
+                               })
+
+                               parse_single_file(file, path, read_all, settings, 2, false)
+
+                               file:close()
+                       end
+               end
+
+               -- Parse clientmods
+               local clientmods_category_initialized = false
+               local clientmods = {}
+               get_mods(core.get_clientmodpath(), "clientmods", clientmods)
+               for _, clientmod in ipairs(clientmods) do
+                       local path = clientmod.path .. DIR_DELIM .. FILENAME
+                       local file = io.open(path, "r")
+                       if file then
+                               if not clientmods_category_initialized then
+                                       fgettext_ne("Clientmods") -- not used, but needed for xgettext
+                                       table.insert(settings, {
+                                               name = "Clientmods",
+                                               level = 0,
+                                               type = "category",
+                                       })
+                                       clientmods_category_initialized = true
+                               end
+
+                               table.insert(settings, {
+                                       name = clientmod.name,
                                        level = 1,
                                        type = "category",
                                })
@@ -430,67 +526,69 @@ local function get_current_value(setting)
        return value
 end
 
-local function create_change_setting_formspec(dialogdata)
-       local setting = settings[selected_setting]
-       local formspec = "size[10,5.2,true]" ..
-                       "button[5,4.5;2,1;btn_done;" .. fgettext("Save") .. "]" ..
-                       "button[3,4.5;2,1;btn_cancel;" .. fgettext("Cancel") .. "]" ..
-                       "tablecolumns[color;text]" ..
-                       "tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
-                       "table[0,0;10,3;info;"
-
-       if setting.readable_name then
-               formspec = formspec .. "#FFFF00," .. fgettext(setting.readable_name)
-                               .. " (" .. core.formspec_escape(setting.name) .. "),"
-       else
-               formspec = formspec .. "#FFFF00," .. core.formspec_escape(setting.name) .. ","
-       end
-
-       formspec = formspec .. ",,"
-
-       local comment_text = ""
-
-       if setting.comment == "" then
-               comment_text = fgettext_ne("(No description of setting given)")
-       else
-               comment_text = fgettext_ne(setting.comment)
-       end
-       for _, comment_line in ipairs(comment_text:split("\n", true)) do
-               formspec = formspec .. "," .. core.formspec_escape(comment_line) .. ","
+local function get_current_np_group(setting)
+       local value = core.settings:get_np_group(setting.name)
+       if value == nil then
+               return setting.values
        end
+       local p = "%g"
+       return {
+               p:format(value.offset),
+               p:format(value.scale),
+               p:format(value.spread.x),
+               p:format(value.spread.y),
+               p:format(value.spread.z),
+               p:format(value.seed),
+               p:format(value.octaves),
+               p:format(value.persistence),
+               p:format(value.lacunarity),
+               value.flags
+       }
+end
 
-       if setting.type == "flags" then
-               formspec = formspec .. ",,"
-                               .. "," .. fgettext("Please enter a comma seperated list of flags.") .. ","
-                               .. "," .. fgettext("Possible values are: ")
-                               .. core.formspec_escape(setting.possible:gsub(",", ", ")) .. ","
-       elseif setting.type == "noise_params" then
-               formspec = formspec .. ",,"
-                               .. "," .. fgettext("Format: <offset>, <scale>, (<spreadX>, <spreadY>, <spreadZ>), <seed>, <octaves>, <persistence>") .. ","
-                               .. "," .. fgettext("Optionally the lacunarity can be appended with a leading comma.") .. ","
-       elseif setting.type == "v3f" then
-               formspec = formspec .. ",,"
-                               .. "," .. fgettext_ne("Format is 3 numbers separated by commas and inside brackets.") .. ","
+local function get_current_np_group_as_string(setting)
+       local value = core.settings:get_np_group(setting.name)
+       if value == nil then
+               return setting.default
        end
+       return ("%g, %g, (%g, %g, %g), %g, %g, %g, %g"):format(
+               value.offset,
+               value.scale,
+               value.spread.x,
+               value.spread.y,
+               value.spread.z,
+               value.seed,
+               value.octaves,
+               value.persistence,
+               value.lacunarity
+       ) .. (value.flags ~= "" and (", " .. value.flags) or "")
+end
 
-       formspec = formspec:sub(1, -2) -- remove trailing comma
-
-       formspec = formspec .. ";1]"
+local checkboxes = {} -- handle checkboxes events
 
+local function create_change_setting_formspec(dialogdata)
+       local setting = settings[selected_setting]
+       -- Final formspec will be created at the end of this function
+       -- Default values below, may be changed depending on setting type
+       local width = 10
+       local height = 3.5
+       local description_height = 3
+       local formspec = ""
+
+       -- Setting-specific formspec elements
        if setting.type == "bool" then
-               local selected_index
+               local selected_index = 1
                if core.is_yes(get_current_value(setting)) then
                        selected_index = 2
-               else
-                       selected_index = 1
                end
-               formspec = formspec .. "dropdown[0.5,3.5;3,1;dd_setting_value;"
+               formspec = "dropdown[3," .. height .. ";4,1;dd_setting_value;"
                                .. fgettext("Disabled") .. "," .. fgettext("Enabled") .. ";"
                                .. selected_index .. "]"
+               height = height + 1.25
 
        elseif setting.type == "enum" then
                local selected_index = 0
-               formspec = formspec .. "dropdown[0.5,3.5;3,1;dd_setting_value;"
+               formspec = "dropdown[3," .. height .. ";4,1;dd_setting_value;"
                for index, value in ipairs(setting.values) do
                        -- translating value is not possible, since it's the value
                        --  that we set the setting to
@@ -503,39 +601,232 @@ local function create_change_setting_formspec(dialogdata)
                        formspec = formspec:sub(1, -2) -- remove trailing comma
                end
                formspec = formspec .. ";" .. selected_index .. "]"
+               height = height + 1.25
 
        elseif setting.type == "path" or setting.type == "filepath" then
                local current_value = dialogdata.selected_path
                if not current_value then
                        current_value = get_current_value(setting)
                end
-               formspec = formspec .. "field[0.5,4;7.5,1;te_setting_value;;"
+               formspec = "field[0.28," .. height + 0.15 .. ";8,1;te_setting_value;;"
                                .. core.formspec_escape(current_value) .. "]"
-                               .. "button[8,3.75;2,1;btn_browser_" .. setting.type .. ";" .. fgettext("Browse") .. "]"
+                               .. "button[8," .. height - 0.15 .. ";2,1;btn_browser_"
+                               .. setting.type .. ";" .. fgettext("Browse") .. "]"
+               height = height + 1.15
+
+       elseif setting.type == "noise_params_2d" or setting.type == "noise_params_3d" then
+               local t = get_current_np_group(setting)
+               local dimension = 3
+               if setting.type == "noise_params_2d" then
+                       dimension = 2
+               end
+
+               -- More space for 3x3 fields
+               description_height = description_height - 1.5
+               height = height - 1.5
+
+               local fields = {}
+               local function add_field(x, name, label, value)
+                       fields[#fields + 1] = ("field[%f,%f;3.3,1;%s;%s;%s]"):format(
+                               x, height, name, label, core.formspec_escape(value or "")
+                       )
+               end
+               -- First row
+               height = height + 0.3
+               add_field(0.3, "te_offset", fgettext("Offset"), t[1])
+               add_field(3.6, "te_scale",  fgettext("Scale"),  t[2])
+               add_field(6.9, "te_seed",   fgettext("Seed"),   t[6])
+               height = height + 1.1
+
+               -- Second row
+               add_field(0.3, "te_spreadx", fgettext("X spread"), t[3])
+               if dimension == 3 then
+                       add_field(3.6, "te_spready", fgettext("Y spread"), t[4])
+               else
+                       fields[#fields + 1] = "label[4," .. height - 0.2 .. ";" ..
+                                       fgettext("2D Noise") .. "]"
+               end
+               add_field(6.9, "te_spreadz", fgettext("Z spread"), t[5])
+               height = height + 1.1
+
+               -- Third row
+               add_field(0.3, "te_octaves", fgettext("Octaves"),     t[7])
+               add_field(3.6, "te_persist", fgettext("Persistence"), t[8])
+               add_field(6.9, "te_lacun",   fgettext("Lacunarity"),  t[9])
+               height = height + 1.1
+
+
+               local enabled_flags = flags_to_table(t[10])
+               local flags = {}
+               for _, name in ipairs(enabled_flags) do
+                       -- Index by name, to avoid iterating over all enabled_flags for every possible flag.
+                       flags[name] = true
+               end
+               for _, name in ipairs(setting.flags) do
+                       local checkbox_name = "cb_" .. name
+                       local is_enabled = flags[name] == true -- to get false if nil
+                       checkboxes[checkbox_name] = is_enabled
+               end
+               -- Flags
+               formspec = table.concat(fields)
+                               .. "checkbox[0.5," .. height - 0.6 .. ";cb_defaults;"
+                               --[[~ "defaults" is a noise parameter flag.
+                               It describes the default processing options
+                               for noise settings in main menu -> "All Settings". ]]
+                               .. fgettext("defaults") .. ";" -- defaults
+                               .. tostring(flags["defaults"] == true) .. "]" -- to get false if nil
+                               .. "checkbox[5," .. height - 0.6 .. ";cb_eased;"
+                               --[[~ "eased" is a noise parameter flag.
+                               It is used to make the map smoother and
+                               can be enabled in noise settings in
+                               main menu -> "All Settings". ]]
+                               .. fgettext("eased") .. ";" -- eased
+                               .. tostring(flags["eased"] == true) .. "]"
+                               .. "checkbox[5," .. height - 0.15 .. ";cb_absvalue;"
+                               --[[~ "absvalue" is a noise parameter flag.
+                               It is short for "absolute value".
+                               It can be enabled in noise settings in
+                               main menu -> "All Settings". ]]
+                               .. fgettext("absvalue") .. ";" -- absvalue
+                               .. tostring(flags["absvalue"] == true) .. "]"
+               height = height + 1
+
+       elseif setting.type == "v3f" then
+               local val = get_current_value(setting)
+               local v3f = {}
+               for line in val:gmatch("[+-]?[%d.+-eE]+") do -- All numeric characters
+                       table.insert(v3f, line)
+               end
+
+               height = height + 0.3
+               formspec = formspec
+                               .. "field[0.3," .. height .. ";3.3,1;te_x;"
+                               .. fgettext("X") .. ";" -- X
+                               .. core.formspec_escape(v3f[1] or "") .. "]"
+                               .. "field[3.6," .. height .. ";3.3,1;te_y;"
+                               .. fgettext("Y") .. ";" -- Y
+                               .. core.formspec_escape(v3f[2] or "") .. "]"
+                               .. "field[6.9," .. height .. ";3.3,1;te_z;"
+                               .. fgettext("Z") .. ";" -- Z
+                               .. core.formspec_escape(v3f[3] or "") .. "]"
+               height = height + 1.1
+
+       elseif setting.type == "flags" then
+               local current_flags = flags_to_table(get_current_value(setting))
+               local flags = {}
+               for _, name in ipairs(current_flags) do
+                       -- Index by name, to avoid iterating over all enabled_flags for every possible flag.
+                       if name:sub(1, 2) == "no" then
+                               flags[name:sub(3)] = false
+                       else
+                               flags[name] = true
+                       end
+               end
+               local flags_count = #setting.possible / 2
+               local max_height = math.ceil(flags_count / 2) / 2
+
+               -- More space for flags
+               description_height = description_height - 1
+               height = height - 1
+
+               local fields = {} -- To build formspec
+               local j = 1
+               for _, name in ipairs(setting.possible) do
+                       if name:sub(1, 2) ~= "no" then
+                               local x = 0.5
+                               local y = height + j / 2 - 0.75
+                               if j - 1 >= flags_count / 2 then -- 2nd column
+                                       x = 5
+                                       y = y - max_height
+                               end
+                               j = j + 1;
+                               local checkbox_name = "cb_" .. name
+                               local is_enabled = flags[name] == true -- to get false if nil
+                               checkboxes[checkbox_name] = is_enabled
+
+                               fields[#fields + 1] = ("checkbox[%f,%f;%s;%s;%s]"):format(
+                                       x, y, checkbox_name, name, tostring(is_enabled)
+                               )
+                       end
+               end
+               formspec = table.concat(fields)
+               height = height + max_height + 0.25
 
        else
-               -- TODO: fancy input for float, int, flags, noise_params, v3f
-               local width = 10
+               -- TODO: fancy input for float, int
                local text = get_current_value(setting)
-               if dialogdata.error_message then
-                       formspec = formspec .. "tablecolumns[color;text]" ..
-                       "tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
-                       "table[5,3.9;5,0.6;error_message;#FF0000,"
-                                       .. core.formspec_escape(dialogdata.error_message) .. ";0]"
-                       width = 5
-                       if dialogdata.entered_text then
-                               text = dialogdata.entered_text
-                       end
+               if dialogdata.error_message and dialogdata.entered_text then
+                       text = dialogdata.entered_text
                end
-               formspec = formspec .. "field[0.5,4;" .. width .. ",1;te_setting_value;;"
+               formspec = "field[0.28," .. height + 0.15 .. ";" .. width .. ",1;te_setting_value;;"
                                .. core.formspec_escape(text) .. "]"
+               height = height + 1.15
        end
-       return formspec
+
+       -- Box good, textarea bad. Calculate textarea size from box.
+       local function create_textfield(size, label, text, bg_color)
+               local textarea = {
+                       x = size.x + 0.3,
+                       y = size.y,
+                       w = size.w + 0.25,
+                       h = size.h * 1.16 + 0.12
+               }
+               return ("box[%f,%f;%f,%f;%s]textarea[%f,%f;%f,%f;;%s;%s]"):format(
+                       size.x, size.y, size.w, size.h, bg_color or "#000",
+                       textarea.x, textarea.y, textarea.w, textarea.h,
+                       core.formspec_escape(label), core.formspec_escape(text)
+               )
+
+       end
+
+       -- When there's an error: Shrink description textarea and add error below
+       if dialogdata.error_message then
+               local error_box = {
+                       x = 0,
+                       y = description_height - 0.4,
+                       w = width - 0.25,
+                       h = 0.5
+               }
+               formspec = formspec ..
+                       create_textfield(error_box, "", dialogdata.error_message, "#600")
+               description_height = description_height - 0.75
+       end
+
+       -- Get description field
+       local description_box = {
+               x = 0,
+               y = 0.2,
+               w = width - 0.25,
+               h = description_height
+       }
+
+       local setting_name = setting.name
+       if setting.readable_name then
+               setting_name = fgettext_ne(setting.readable_name) ..
+                       " (" .. setting.name .. ")"
+       end
+
+       local comment_text
+       if setting.comment == "" then
+               comment_text = fgettext_ne("(No description of setting given)")
+       else
+               comment_text = fgettext_ne(setting.comment)
+       end
+
+       return (
+               "size[" .. width .. "," .. height + 0.25 .. ",true]" ..
+               create_textfield(description_box, setting_name, comment_text) ..
+               formspec ..
+               "button[" .. width / 2 - 2.5 .. "," .. height - 0.4 .. ";2.5,1;btn_done;" ..
+                       fgettext("Save") .. "]" ..
+               "button[" .. width / 2 .. "," .. height - 0.4 .. ";2.5,1;btn_cancel;" ..
+                       fgettext("Cancel") .. "]"
+       )
 end
 
 local function handle_change_setting_buttons(this, fields)
+       local setting = settings[selected_setting]
        if fields["btn_done"] or fields["key_enter"] then
-               local setting = settings[selected_setting]
                if setting.type == "bool" then
                        local new_value = fields["dd_setting_value"]
                        -- Note: new_value is the actual (translated) value shown in the dropdown
@@ -575,20 +866,71 @@ local function handle_change_setting_buttons(this, fields)
                                core.update_formspec(this:get_formspec())
                                return true
                        end
+                       if setting.min and new_value < setting.min then
+                               this.data.error_message = fgettext_ne("The value must be at least $1.", setting.min)
+                               this.data.entered_text = fields["te_setting_value"]
+                               core.update_formspec(this:get_formspec())
+                               return true
+                       end
+                       if setting.max and new_value > setting.max then
+                               this.data.error_message = fgettext_ne("The value must not be larger than $1.", setting.max)
+                               this.data.entered_text = fields["te_setting_value"]
+                               core.update_formspec(this:get_formspec())
+                               return true
+                       end
                        core.settings:set(setting.name, new_value)
 
                elseif setting.type == "flags" then
-                       local new_value = fields["te_setting_value"]
-                       for _,value in ipairs(new_value:split(",", true)) do
-                               value = value:trim()
-                               local possible = "," .. setting.possible .. ","
-                               if not possible:find("," .. value .. ",", 0, true) then
-                                       this.data.error_message = fgettext_ne("\"$1\" is not a valid flag.", value)
-                                       this.data.entered_text = fields["te_setting_value"]
-                                       core.update_formspec(this:get_formspec())
-                                       return true
+                       local values = {}
+                       for _, name in ipairs(setting.possible) do
+                               if name:sub(1, 2) ~= "no" then
+                                       if checkboxes["cb_" .. name] then
+                                               table.insert(values, name)
+                                       else
+                                               table.insert(values, "no" .. name)
+                                       end
                                end
                        end
+
+                       checkboxes = {}
+
+                       local new_value = table.concat(values, ", ")
+                       core.settings:set(setting.name, new_value)
+
+               elseif setting.type == "noise_params_2d" or setting.type == "noise_params_3d" then
+                       local np_flags = {}
+                       for _, name in ipairs(setting.flags) do
+                               if checkboxes["cb_" .. name] then
+                                       table.insert(np_flags, name)
+                               end
+                       end
+
+                       checkboxes = {}
+
+                       if setting.type == "noise_params_2d" then
+                                fields["te_spready"] = fields["te_spreadz"]
+                       end
+                       local new_value = {
+                               offset = fields["te_offset"],
+                               scale = fields["te_scale"],
+                               spread = {
+                                       x = fields["te_spreadx"],
+                                       y = fields["te_spready"],
+                                       z = fields["te_spreadz"]
+                               },
+                               seed = fields["te_seed"],
+                               octaves = fields["te_octaves"],
+                               persistence = fields["te_persist"],
+                               lacunarity = fields["te_lacun"],
+                               flags = table.concat(np_flags, ", ")
+                       }
+                       core.settings:set_np_group(setting.name, new_value)
+
+               elseif setting.type == "v3f" then
+                       local new_value = "("
+                                       .. fields["te_x"] .. ", "
+                                       .. fields["te_y"] .. ", "
+                                       .. fields["te_z"] .. ")"
                        core.settings:set(setting.name, new_value)
 
                else
@@ -620,22 +962,32 @@ local function handle_change_setting_buttons(this, fields)
                core.update_formspec(this:get_formspec())
        end
 
+       if setting.type == "flags"
+                       or setting.type == "noise_params_2d"
+                       or setting.type == "noise_params_3d" then
+               for name, value in pairs(fields) do
+                       if name:sub(1, 3) == "cb_" then
+                               checkboxes[name] = value == "true"
+                       end
+               end
+       end
+
        return false
 end
 
-local function create_settings_formspec(tabview, name, tabdata)
-       local formspec = "size[12,6.5;true]" ..
-                       "tablecolumns[color;tree;text,width=32;text]" ..
+local function create_settings_formspec(tabview, _, tabdata)
+       local formspec = "size[12,5.4;true]" ..
+                       "tablecolumns[color;tree;text,width=28;text]" ..
                        "tableoptions[background=#00000000;border=false]" ..
                        "field[0.3,0.1;10.2,1;search_string;;" .. core.formspec_escape(search_string) .. "]" ..
                        "field_close_on_enter[search_string;false]" ..
                        "button[10.2,-0.2;2,1;search;" .. fgettext("Search") .. "]" ..
-                       "table[0,0.8;12,4.5;list_settings;"
+                       "table[0,0.8;12,3.5;list_settings;"
 
        local current_level = 0
        for _, entry in ipairs(settings) do
                local name
-               if not core.settings:get_bool("main_menu_technical_settings") and entry.readable_name then
+               if not core.settings:get_bool("show_technical_names") and entry.readable_name then
                        name = fgettext_ne(entry.readable_name)
                else
                        name = entry.name
@@ -655,9 +1007,13 @@ local function create_settings_formspec(tabview, name, tabdata)
                        formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. ","
                                        .. value .. ","
 
-               elseif entry.type == "key" then
+               elseif entry.type == "key" then --luacheck: ignore
                        -- ignore key settings, since we have a special dialog for them
 
+               elseif entry.type == "noise_params_2d" or entry.type == "noise_params_3d" then
+                       formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. ","
+                                       .. core.formspec_escape(get_current_np_group_as_string(entry)) .. ","
+
                else
                        formspec = formspec .. "," .. (current_level + 1) .. "," .. core.formspec_escape(name) .. ","
                                        .. core.formspec_escape(get_current_value(entry)) .. ","
@@ -668,11 +1024,11 @@ local function create_settings_formspec(tabview, name, tabdata)
                formspec = formspec:sub(1, -2) -- remove trailing comma
        end
        formspec = formspec .. ";" .. selected_setting .. "]" ..
-                       "button[0,6;4,1;btn_back;".. fgettext("< Back to Settings page") .. "]" ..
-                       "button[10,6;2,1;btn_edit;" .. fgettext("Edit") .. "]" ..
-                       "button[7,6;3,1;btn_restore;" .. fgettext("Restore Default") .. "]" ..
-                       "checkbox[0,5.3;cb_tech_settings;" .. fgettext("Show technical names") .. ";"
-                                       .. dump(core.settings:get_bool("main_menu_technical_settings")) .. "]"
+                       "button[0,4.9;4,1;btn_back;".. fgettext("< Back to Settings page") .. "]" ..
+                       "button[10,4.9;2,1;btn_edit;" .. fgettext("Edit") .. "]" ..
+                       "button[7,4.9;3,1;btn_restore;" .. fgettext("Restore Default") .. "]" ..
+                       "checkbox[0,4.3;cb_tech_settings;" .. fgettext("Show technical names") .. ";"
+                                       .. dump(core.settings:get_bool("show_technical_names")) .. "]"
 
        return formspec
 end
@@ -730,8 +1086,8 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
        if fields["btn_edit"] or list_enter then
                local setting = settings[selected_setting]
                if setting and setting.type ~= "category" then
-                       local edit_dialog = dialog_create("change_setting", create_change_setting_formspec,
-                                       handle_change_setting_buttons)
+                       local edit_dialog = dialog_create("change_setting",
+                                       create_change_setting_formspec, handle_change_setting_buttons)
                        edit_dialog:set_parent(this)
                        this:hide()
                        edit_dialog:show()
@@ -742,7 +1098,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
        if fields["btn_restore"] then
                local setting = settings[selected_setting]
                if setting and setting.type ~= "category" then
-                       core.settings:set(setting.name, setting.default)
+                       core.settings:remove(setting.name)
                        core.settings:write()
                        core.update_formspec(this:get_formspec())
                end
@@ -755,7 +1111,7 @@ local function handle_settings_buttons(this, fields, tabname, tabdata)
        end
 
        if fields["cb_tech_settings"] then
-               core.settings:set("main_menu_technical_settings", fields["cb_tech_settings"])
+               core.settings:set("show_technical_names", fields["cb_tech_settings"])
                core.settings:write()
                core.update_formspec(this:get_formspec())
                return true
@@ -773,6 +1129,9 @@ function create_adv_settings_dlg()
                                return dlg
 end
 
--- Generate minetest.conf.example and settings_translation_file.cpp
+-- Uncomment to generate 'minetest.conf.example' and 'settings_translation_file.cpp'.
+-- For RUN_IN_PLACE the generated files may appear in the 'bin' folder.
+-- See comment and alternative line at the end of 'generate_from_settingtypes.lua'.
 
---assert(loadfile(core.get_builtin_path()..DIR_DELIM.."mainmenu"..DIR_DELIM.."generate_from_settingtypes.lua"))(parse_config_file(true, false))
+--assert(loadfile(core.get_builtin_path().."mainmenu"..DIR_DELIM..
+--             "generate_from_settingtypes.lua"))(parse_config_file(true, false))