mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-02 16:38:41 +00:00
Improvements/fixes for noise parameter input in advanced settings
Formspec input for each individual noise parameter and flag. Allow noise flags to be set in advanced settings, previously only settable in minetest.conf. Standardise 'group format' for noise parameters set in minetest.conf, as only these support noise flags. However the older 'single line' format is still accepted to support existing minetest.conf files. Therefore auto-generate minetest.conf.example with noise parameters in 'group format'. Setting 'type' in settingtypes.txt is now either 'noise_params_2D' or 'noise_params_3D', the dimension number is displayed in the advanced settings edit page.
This commit is contained in:
parent
c60abb2aec
commit
a1e1a19ac3
9 changed files with 476 additions and 145 deletions
|
@ -25,6 +25,10 @@ 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)
|
||||
-- comment
|
||||
|
@ -111,7 +115,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 +137,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 line in default:gmatch("[+-]?[%d.-e]+") do -- All numeric characters
|
||||
index = default:find("[+-]?[%d.-e]+", index) + line:len()
|
||||
table.insert(values, line)
|
||||
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 +294,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
|
||||
|
@ -430,11 +488,61 @@ local function get_current_value(setting)
|
|||
return value
|
||||
end
|
||||
|
||||
local function get_current_np_group(setting)
|
||||
local value = core.settings:get_np_group(setting.name)
|
||||
local t = {}
|
||||
if value == nil then
|
||||
t = setting.values
|
||||
else
|
||||
table.insert(t, value.offset)
|
||||
table.insert(t, value.scale)
|
||||
table.insert(t, value.spread.x)
|
||||
table.insert(t, value.spread.y)
|
||||
table.insert(t, value.spread.z)
|
||||
table.insert(t, value.seed)
|
||||
table.insert(t, value.octaves)
|
||||
table.insert(t, value.persistence)
|
||||
table.insert(t, value.lacunarity)
|
||||
table.insert(t, value.flags)
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local function get_current_np_group_as_string(setting)
|
||||
local value = core.settings:get_np_group(setting.name)
|
||||
local t
|
||||
if value == nil then
|
||||
t = setting.default
|
||||
else
|
||||
t = value.offset .. ", " ..
|
||||
value.scale .. ", (" ..
|
||||
value.spread.x .. ", " ..
|
||||
value.spread.y .. ", " ..
|
||||
value.spread.z .. "), " ..
|
||||
value.seed .. ", " ..
|
||||
value.octaves .. ", " ..
|
||||
value.persistence .. ", " ..
|
||||
value.lacunarity .. ", " ..
|
||||
value.flags
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local checkboxes = {} -- handle checkboxes events
|
||||
|
||||
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") .. "]" ..
|
||||
local height = 5.2
|
||||
if setting.type == "noise_params_2d" or setting.type == "noise_params_3d" then
|
||||
-- Three flags, checkboxes on 2 columns, with a vertical space of 1/2 unit
|
||||
height = 8.7
|
||||
elseif setting.type == "flags" then
|
||||
-- Checkboxes on 2 columns, with a vertical space of 1/2 unit
|
||||
height = 5.2 + math.ceil(#setting.possible / 2) / 2
|
||||
end
|
||||
local formspec = "size[10," .. height .. ",true]" ..
|
||||
"button[5," .. height - 0.7 .. ";2,1;btn_done;" .. fgettext("Save") .. "]" ..
|
||||
"button[3," .. height - 0.7 .. ";2,1;btn_cancel;" .. fgettext("Cancel") .. "]" ..
|
||||
"tablecolumns[color;text]" ..
|
||||
"tableoptions[background=#00000000;highlight=#00000000;border=false]" ..
|
||||
"table[0,0;10,3;info;"
|
||||
|
@ -459,21 +567,6 @@ local function create_change_setting_formspec(dialogdata)
|
|||
formspec = formspec .. "," .. core.formspec_escape(comment_line) .. ","
|
||||
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:") .. ","
|
||||
.. "," .. fgettext("<offset>, <scale>, (<spreadX>, <spreadY>, <spreadZ>),") .. ","
|
||||
.. "," .. fgettext("<seed>, <octaves>, <persistence>, <lacunarity>") .. ","
|
||||
elseif setting.type == "v3f" then
|
||||
formspec = formspec .. ",,"
|
||||
.. "," .. fgettext_ne("Format is 3 numbers separated by commas and inside brackets.") .. ","
|
||||
end
|
||||
|
||||
formspec = formspec:sub(1, -2) -- remove trailing comma
|
||||
|
||||
formspec = formspec .. ";1]"
|
||||
|
@ -514,8 +607,91 @@ local function create_change_setting_formspec(dialogdata)
|
|||
.. core.formspec_escape(current_value) .. "]"
|
||||
.. "button[8,3.75;2,1;btn_browser_" .. setting.type .. ";" .. fgettext("Browse") .. "]"
|
||||
|
||||
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
|
||||
|
||||
formspec = formspec
|
||||
.. "label[0,2.5;(" .. dimension .. "D Noise)]"
|
||||
.. "field[0.5,4;3.3,1;te_offset;Offset;" -- Offset
|
||||
.. core.formspec_escape(t[1] or "") .. "]"
|
||||
.. "field[3.8,4;3.3,1;te_scale;Scale;" -- Scale
|
||||
.. core.formspec_escape(t[2] or "") .. "]"
|
||||
.. "field[7.1,4;3.3,1;te_seed;Seed;" -- Seed
|
||||
.. core.formspec_escape(t[6] or "") .. "]"
|
||||
.. "label[0.5,4.7;Spread]" -- Spread
|
||||
.. "field[2.0,5;2.8,1;te_spreadx;X;"
|
||||
.. core.formspec_escape(t[3] or "") .. "]"
|
||||
.. "field[4.8,5;2.8,1;te_spready;Y;"
|
||||
.. core.formspec_escape(t[4] or "") .. "]"
|
||||
.. "field[7.6,5;2.8,1;te_spreadz;Z;"
|
||||
.. core.formspec_escape(t[5] or "") .. "]"
|
||||
.. "field[0.5,6;3.3,1;te_octaves;Octaves;" -- Octaves
|
||||
.. core.formspec_escape(t[7] or "") .. "]"
|
||||
.. "field[3.8,6;3.3,1;te_persist;Persistance;" -- Persistance
|
||||
.. core.formspec_escape(t[8] or "") .. "]"
|
||||
.. "field[7.1,6;3.3,1;te_lacun;Lacunarity;" -- Lacunarity
|
||||
.. core.formspec_escape(t[9] or "") .. "]"
|
||||
|
||||
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
|
||||
-- Flags
|
||||
formspec = formspec
|
||||
.. "checkbox[0.5,6.5;cb_defaults;defaults;" -- defaults
|
||||
.. tostring(flags["defaults"] == true) .. "]" -- to get false if nil
|
||||
.. "checkbox[5,6.5;cb_eased;eased;" -- eased
|
||||
.. tostring(flags["eased"] == true) .. "]"
|
||||
.. "checkbox[5,7.0;cb_absvalue;absvalue;" -- absvalue
|
||||
.. tostring(flags["absvalue"] == true) .. "]"
|
||||
|
||||
elseif setting.type == "v3f" then
|
||||
local val = get_current_value(setting)
|
||||
local v3f = {}
|
||||
for line in val:gmatch("[+-]?[%d.-e]+") do -- All numeric characters
|
||||
table.insert(v3f, line)
|
||||
end
|
||||
|
||||
formspec = formspec
|
||||
.. "field[0.5,4;3.3,1;te_x;X;" -- X
|
||||
.. core.formspec_escape(v3f[1] or "") .. "]"
|
||||
.. "field[3.8,4;3.3,1;te_y;Y;" -- Y
|
||||
.. core.formspec_escape(v3f[2] or "") .. "]"
|
||||
.. "field[7.1,4;3.3,1;te_z;Z;" -- Z
|
||||
.. core.formspec_escape(v3f[3] or "") .. "]"
|
||||
|
||||
elseif setting.type == "flags" then
|
||||
local enabled_flags = flags_to_table(get_current_value(setting))
|
||||
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
|
||||
local flags_count = #setting.possible
|
||||
for i, name in ipairs(setting.possible) do
|
||||
local x = 0.5
|
||||
local y = 3.5 + i / 2
|
||||
if i - 1 >= flags_count / 2 then -- 2nd column
|
||||
x = 5
|
||||
y = y - flags_count / 4
|
||||
end
|
||||
local checkbox_name = "cb_" .. name
|
||||
local is_enabled = flags[name] == true -- to get false if nil
|
||||
checkboxes[checkbox_name] = is_enabled
|
||||
formspec = formspec .. "checkbox["
|
||||
.. x .. "," .. y
|
||||
.. ";" .. checkbox_name .. ";"
|
||||
.. name .. ";" .. tostring(is_enabled) .. "]"
|
||||
end
|
||||
|
||||
else
|
||||
-- TODO: fancy input for float, int, flags, noise_params, v3f
|
||||
-- TODO: fancy input for float, int
|
||||
local width = 10
|
||||
local text = get_current_value(setting)
|
||||
if dialogdata.error_message then
|
||||
|
@ -535,8 +711,8 @@ local function create_change_setting_formspec(dialogdata)
|
|||
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
|
||||
|
@ -579,17 +755,49 @@ local function handle_change_setting_buttons(this, fields)
|
|||
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 checkboxes["cb_" .. name] then
|
||||
table.insert(values, name)
|
||||
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 = {}
|
||||
|
||||
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
|
||||
|
@ -621,6 +829,16 @@ 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
|
||||
|
||||
|
@ -659,6 +877,10 @@ local function create_settings_formspec(tabview, name, tabdata)
|
|||
elseif entry.type == "key" then
|
||||
-- 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)) .. ","
|
||||
|
@ -743,7 +965,12 @@ 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)
|
||||
if setting.type == "noise_params_2d"
|
||||
or setting.type == "noise_params_3d" then
|
||||
core.settings:set_np_group(setting.name, setting.default_table)
|
||||
else
|
||||
core.settings:set(setting.name, setting.default)
|
||||
end
|
||||
core.settings:write()
|
||||
core.update_formspec(this:get_formspec())
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue