2025-04-05 01:19:52 +02:00
-- Luanti
-- Copyright (C) 2015 PilzAdam
-- SPDX-License-Identifier: LGPL-2.1-or-later
2022-06-25 17:33:20 +01:00
local checkboxes = { }
local function flags_to_table ( flags )
return flags : gsub ( " %s+ " , " " ) : split ( " , " , true ) -- Remove all spaces and split
end
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
local function get_formspec ( dialogdata )
local setting = dialogdata.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
2023-09-16 18:35:35 +02:00
local height = 2
local description_height = 1.5
2022-06-25 17:33:20 +01:00
local t = get_current_np_group ( setting )
local dimension = 3
if setting.type == " noise_params_2d " then
dimension = 2
end
local fields = { }
2025-09-02 12:07:50 +03:00
local function add_field ( x , name , label , value , tt )
2022-06-25 17:33:20 +01:00
fields [ # fields + 1 ] = ( " field[%f,%f;3.3,1;%s;%s;%s] " ) : format (
x , height , name , label , core.formspec_escape ( value or " " )
)
2025-09-02 12:07:50 +03:00
if tt then
fields [ # fields + 1 ] = ( " tooltip[%s;%s] " ) : format ( name , tt )
end
2022-06-25 17:33:20 +01:00
end
-- First row
height = height + 0.3
2025-09-02 12:07:50 +03:00
add_field ( 0.3 , " te_offset " , fgettext ( " Offset " ) , t [ 1 ] , fgettext ( " This value offsets the final noise. " ) )
add_field ( 3.6 , " te_scale " , fgettext ( " Scale " ) , t [ 2 ] , fgettext ( " This value multiplies the noise before the offset is added. " ) )
add_field ( 6.9 , " te_seed " , fgettext ( " Seed " ) , t [ 6 ] , fgettext ( " This value acts as a random seed for the noise. Every value will result in a different, random result. " ) )
2022-06-25 17:33:20 +01:00
height = height + 1.1
-- Second row
2025-09-02 12:07:50 +03:00
add_field ( 0.3 , " te_spreadx " , fgettext ( " X spread " ) , t [ 3 ] , fgettext ( " This value \" scales \" the noise in the X axis by this value. " ) )
2022-06-25 17:33:20 +01:00
if dimension == 3 then
2025-09-02 12:07:50 +03:00
add_field ( 3.6 , " te_spready " , fgettext ( " Y spread " ) , t [ 4 ] , fgettext ( " This value \" scales \" the noise in the Y axis by this value. " ) )
2022-06-25 17:33:20 +01:00
else
fields [ # fields + 1 ] = " label[4, " .. height - 0.2 .. " ; " ..
fgettext ( " 2D Noise " ) .. " ] "
end
2025-09-02 12:07:50 +03:00
add_field ( 6.9 , " te_spreadz " , fgettext ( " Z spread " ) , t [ 5 ] , fgettext ( " This value \" scales \" the noise in the Z axis by this value. " ) )
2022-06-25 17:33:20 +01:00
height = height + 1.1
-- Third row
2025-09-02 15:20:32 +03:00
add_field ( 0.3 , " te_octaves " , fgettext ( " Octaves " ) , t [ 7 ] , fgettext (
[ [ This value controls how many octaves the noise will have .
2025-09-02 12:07:50 +03:00
An octave is a simple noise generator . Its scale and amplitude will be multiplied based on the Persistence and Lacunarity settings .
Finally , all of the octaves will be added to generate this noise . ] ] ) )
2025-09-02 15:20:32 +03:00
add_field ( 3.6 , " te_persist " , fgettext ( " Persistence " ) , t [ 8 ] , fgettext (
[ [ This value multiplies an octave ' s amplitude by the previous octave multiplied by this value.
2025-09-02 12:07:50 +03:00
Example : If the persistence was 0.5 , the 1 st octave would be scaled by 1 , the 2 nd would be by 0.5 , the 3 rd would be by 0.25 , etc . ] ] ) )
2025-09-02 15:20:32 +03:00
add_field ( 6.9 , " te_lacun " , fgettext ( " Lacunarity " ) , t [ 9 ] , fgettext (
[ [ This value multiplies an octave ' s scale by the previous octave multiplied by this value.
2025-09-02 12:07:50 +03:00
Example : If the lacunarity was 0.5 , the 1 st octave would be scaled by 1 , the 2 nd would be by 0.5 , the 3 rd would be by 0.25 , etc . ] ] ) )
2022-06-25 17:33:20 +01:00
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
local formspec = table.concat ( fields )
.. " checkbox[0.5, " .. height - 0.6 .. " ;cb_defaults; "
--[[~ "defaults" is a noise parameter flag.
It describes the default processing options
2023-09-16 18:35:35 +02:00
for noise settings in the settings menu . ] ]
2022-06-25 17:33:20 +01:00
.. fgettext ( " defaults " ) .. " ; " -- defaults
.. tostring ( flags [ " defaults " ] == true ) .. " ] " -- to get false if nil
2025-09-02 15:20:32 +03:00
.. " tooltip[cb_defaults; " .. fgettext (
[ [ This flag overrides the eased flag based on the noise map type .
2025-09-02 12:07:50 +03:00
2 D noise will make eased on .
3 D noise will make eased off . ] ] ) .. " ] "
2022-06-25 17:33:20 +01:00
.. " 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
2023-09-16 18:35:35 +02:00
the settings menu . ] ]
2022-06-25 17:33:20 +01:00
.. fgettext ( " eased " ) .. " ; " -- eased
.. tostring ( flags [ " eased " ] == true ) .. " ] "
2025-09-02 15:20:32 +03:00
.. " tooltip[cb_eased; " .. fgettext (
[ [ This flag maps noise gradient values onto a quintic S - curve before performing interpolation .
2025-09-02 12:07:50 +03:00
This results in smooth noise instead of gridlike noise .
Making 3 D noise eased is not recommended because it significantly increases the computation load . ] ] ) .. " ] "
2022-06-25 17:33:20 +01:00
.. " 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
2023-09-16 18:35:35 +02:00
the settings menu . ] ]
2022-06-25 17:33:20 +01:00
.. fgettext ( " absvalue " ) .. " ; " -- absvalue
.. tostring ( flags [ " absvalue " ] == true ) .. " ] "
2025-09-02 15:20:32 +03:00
.. " tooltip[cb_absvalue; " .. fgettext (
[ [ This flag takes the absolute value of each octave while adding them together .
2025-09-02 12:07:50 +03:00
This results in " spiky " noise . ] ] ) .. " ] "
2022-06-25 17:33:20 +01:00
height = height + 1
-- 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 buttonhandler ( this , fields )
local setting = this.data . setting
if fields [ " btn_done " ] or fields [ " key_enter " ] 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
2023-09-16 18:35:35 +02:00
fields [ " te_spready " ] = fields [ " te_spreadz " ]
2022-06-25 17:33:20 +01:00
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 )
core.settings : write ( )
this : delete ( )
return true
end
if fields [ " btn_cancel " ] then
this : delete ( )
return true
end
2023-09-16 18:35:35 +02:00
for name , value in pairs ( fields ) do
if name : sub ( 1 , 3 ) == " cb_ " then
checkboxes [ name ] = core.is_yes ( value )
return false -- Don't update the formspec!
end
end
2022-06-25 17:33:20 +01:00
return false
end
function create_change_mapgen_flags_dlg ( setting )
assert ( type ( setting ) == " table " )
local retval = dialog_create ( " dlg_change_mapgen_flags " ,
get_formspec ,
buttonhandler ,
nil )
retval.data . setting = setting
return retval
end