allow to name and rename dialogs

This commit is contained in:
Sokomine 2024-03-09 19:25:51 +01:00
parent f5ecb06ce6
commit 7905d9937f
4 changed files with 106 additions and 27 deletions

View File

@ -9,6 +9,8 @@ yl_speak_up.prepare_new_dialog_for_option = function(dialog, pname, n_id, d_id,
-- this dialog directly (the player may follow the -> button) -- this dialog directly (the player may follow the -> button)
target_dialog = yl_speak_up.add_new_dialog(dialog, pname, nil) target_dialog = yl_speak_up.add_new_dialog(dialog, pname, nil)
end end
-- translate name into dialog id
target_dialog = yl_speak_up.d_name_to_d_id(dialog, target_dialog)
-- is there a result/effect of the type "dialog" already? else use a fallback -- is there a result/effect of the type "dialog" already? else use a fallback
local result = {} --{r_value = "-default-"} local result = {} --{r_value = "-default-"}
if(o_results) then if(o_results) then
@ -25,12 +27,19 @@ yl_speak_up.prepare_new_dialog_for_option = function(dialog, pname, n_id, d_id,
end end
end end
end end
local old_d = tostring(result.r_value or "-default-")
if(result.r_value and dialog.n_dialogs[result.r_value] and dialog.n_dialogs[result.r_value].d_name) then
old_d = old_d..":"..tostring(dialog.n_dialogs[result.r_value].d_name)
end
local new_d = tostring(target_dialog)
if(target_dialog and dialog.n_dialogs[target_dialog] and dialog.n_dialogs[target_dialog].d_name) then
new_d = new_d..":"..tostring(dialog.n_dialogs[target_dialog].d_name)
end
-- store that a new option has been added to this dialog -- store that a new option has been added to this dialog
table.insert(yl_speak_up.npc_was_changed[ n_id ], table.insert(yl_speak_up.npc_was_changed[ n_id ],
"Dialog "..d_id..": The target dialog for option ".. "Dialog "..d_id..": The target dialog for option "..
tostring(o_id).." was changed from ".. tostring(o_id).." was changed from "..
tostring(result.r_value or "-default-").." to ".. old_d.." to "..new_d..".")
tostring(target_dialog)..".")
-- does the result/effect of type "dialog" exist already? then we're done -- does the result/effect of type "dialog" exist already? then we're done
if(result.r_type and result.r_type == "dialog") then if(result.r_type and result.r_type == "dialog") then
-- actually change the target dialog -- actually change the target dialog
@ -148,6 +157,34 @@ yl_speak_up.edit_mode_apply_changes = function(pname, fields)
dialog.n_dialogs[ d_id ].d_text = fields.d_text dialog.n_dialogs[ d_id ].d_text = fields.d_text
end end
if(fields.d_name and fields.d_name ~= "" and dialog.n_dialogs[ d_id ].d_name ~= fields.d_name) then
if(fields.d_name ~= d_id
and not(yl_speak_up.is_special_dialog(d_id))) then
local err_msg = nil
-- check if there are no duplicate names
for k, v in pairs(dialog.n_dialogs) do
if(v and v.d_name and v.d_name == fields.d_name and k ~= d_id) then
err_msg = "Sorry. That name has already been used for dialog "..
tostring(k).."."
end
end
if(dialog.n_dialogs[fields.d_name]) then
err_msg = "Sorry. There is already a dialog with a dialog id of "..
tostring(fields.d_name).."."
end
-- TODO: check if the name is allowed (only normal chars, numbers and underscore)
if(err_msg) then
minetest.chat_send_player(pname, err_msg)
else
table.insert(yl_speak_up.npc_was_changed[ n_id ],
"Dialog "..d_id..": renamed from \""..
tostring(dialog.n_dialogs[ d_id ].d_name)..
"\" to \""..tostring(fields.d_name).."\".")
dialog.n_dialogs[ d_id ].d_name = fields.d_name
end
end
end
-- add a new option/answer -- add a new option/answer
if(fields[ "add_option"]) then if(fields[ "add_option"]) then
local future_o_id = yl_speak_up.add_new_option(dialog, pname, nil, d_id, "", d_id) local future_o_id = yl_speak_up.add_new_option(dialog, pname, nil, d_id, "", d_id)

View File

@ -163,6 +163,8 @@ yl_speak_up.input_talk = function(player, formname, fields)
selected_option = dialog.n_dialogs[d_id].d_options[o] selected_option = dialog.n_dialogs[d_id].d_options[o]
end end
-- translate a dialog name into a d_id
fields.d_id = yl_speak_up.d_name_to_d_id(dialog, fields.d_id)
-- in edit mode: has another dialog been selected? -- in edit mode: has another dialog been selected?
-- if nothing better can be found: keep the old dialog -- if nothing better can be found: keep the old dialog
local show_dialog = d_id local show_dialog = d_id
@ -192,6 +194,7 @@ yl_speak_up.input_talk = function(player, formname, fields)
end end
end end
end end
yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = show_dialog}) yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = show_dialog})
-- no option was selected - so we need to end this here -- no option was selected - so we need to end this here
return return
@ -252,18 +255,19 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
local sorted_list = yl_speak_up.get_sorted_options(dialog.n_dialogs, "d_sort") local sorted_list = yl_speak_up.get_sorted_options(dialog.n_dialogs, "d_sort")
-- add buttons for previous/next dialog -- add buttons for previous/next dialog
for i, d in ipairs(sorted_list) do for i, d in ipairs(sorted_list) do
local d_name = dialog.n_dialogs[d].d_name or d
-- build the list of available dialogs for the dropdown list(s) -- build the list of available dialogs for the dropdown list(s)
dialog_list = dialog_list..","..minetest.formspec_escape(d) dialog_list = dialog_list..","..minetest.formspec_escape(d_name)
if(d == c_d_id) then if(d == c_d_id) then
local prev_dialog = tostring(minetest.formspec_escape(sorted_list[i-1])) local prev_dialog = tostring(minetest.formspec_escape(sorted_list[i-1]))
yl_speak_up.add_formspec_element_with_tooltip_if(formspec, yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"button", "8.5,4.0;2,0.9", "prev_dialog_"..prev_dialog, "button", "15.4,5.0;2,0.9", "prev_dialog_"..prev_dialog,
"<", "<",
"Go to previous dialog "..prev_dialog..".", "Go to previous dialog "..prev_dialog..".",
(sorted_list[ i-1 ])) (sorted_list[ i-1 ]))
local next_dialog = tostring(minetest.formspec_escape(sorted_list[i+1])) local next_dialog = tostring(minetest.formspec_escape(sorted_list[i+1]))
yl_speak_up.add_formspec_element_with_tooltip_if(formspec, yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"button", "11,4.0;2,0.9", "next_dialog_"..next_dialog, "button", "17.6,5.0;2,0.9", "next_dialog_"..next_dialog,
">", ">",
"Go to next dialog "..next_dialog..".", "Go to next dialog "..next_dialog..".",
(sorted_list[ i+1 ])) (sorted_list[ i+1 ]))
@ -273,15 +277,29 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
dialog_list = dialog_list..",d_end" dialog_list = dialog_list..",d_end"
d_id_to_dropdown_index["d_end"] = #sorted_list + 2 d_id_to_dropdown_index["d_end"] = #sorted_list + 2
table.insert(formspec, "label[0.2,4.6;Dialog:]") -- "..minetest.formspec_escape(c_d_id)..":]")
table.insert(formspec, "dropdown[3.0,4.0;5,1;d_id;"..dialog_list..";".. if(not(yl_speak_up.is_special_dialog(c_d_id))) then
table.insert(formspec, "label[0.2,4.2;Dialog ")
table.insert(formspec, minetest.formspec_escape(c_d_id))
table.insert(formspec, ":]")
table.insert(formspec, "field[5.0,3.6;9.8,1.2;d_name;;")
table.insert(formspec, minetest.formspec_escape(dialog.n_dialogs[c_d_id].d_name or c_d_id))
table.insert(formspec, "]")
table.insert(formspec, "tooltip[d_name;Dialogs can have a *name* that is diffrent from\n"..
"their ID (which is i.e. d_4). The name will be shown\n"..
"in the dropdown list. Save a new name by clicking on\n"..
"the dialog \"Save\" button.]")
end
table.insert(formspec, "label[0.2,5.5;Dialog:]") -- "..minetest.formspec_escape(c_d_id)..":]")
table.insert(formspec, "dropdown[5.0,5.0;9.8,1;d_id;"..dialog_list..";"..
(d_id_to_dropdown_index[c_d_id] or "1")..",]") (d_id_to_dropdown_index[c_d_id] or "1")..",]")
table.insert(formspec, "tooltip[3.0,4.0;5,1;".. table.insert(formspec, "tooltip[5.0,5.0;9.8,1;"..
"Select the dialog you want to edit. Currently, dialog "..c_d_id.. "Select the dialog you want to edit. Currently, dialog "..c_d_id..
" is beeing displayed.;#FFFFFF;#000000]") " is beeing displayed.;#FFFFFF;#000000]")
yl_speak_up.add_formspec_element_with_tooltip_if(formspec, yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"button", "13.9,4.0;1,0.9", "show_new_dialog", "button", "3.5,5.0;1,0.9", "show_new_dialog",
"+", "+",
"Create a new dialog.", "Create a new dialog.",
true) true)
@ -307,9 +325,10 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
true) true)
local tmp = "[0.2,6;19.6,16.8;d_text;"
-- static help text instead of text input field for d_got_item -- static help text instead of text input field for d_got_item
if(c_d_id == "d_got_item") then if(c_d_id == "d_got_item") then
table.insert(formspec, "hypertext[0.2,5;19.6,17.8;d_text;".. table.insert(formspec, "hypertext"..tmp..
"<normal>Note:\nThis is a special dialog. ".. "<normal>Note:\nThis is a special dialog. "..
"It will be called when the player clicks on ".. "It will be called when the player clicks on "..
"<b>I want to give you something</b>.".. "<b>I want to give you something</b>."..
@ -338,7 +357,7 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
"\n</normal>]") "\n</normal>]")
-- static help text instead of text input field for d_trade -- static help text instead of text input field for d_trade
elseif(c_d_id == "d_trade") then elseif(c_d_id == "d_trade") then
table.insert(formspec, "hypertext[0.2,5;19.6,17.8;d_text;".. table.insert(formspec, "hypertext"..tmp..
"<normal>Note:\nThis is a special dialog. ".. "<normal>Note:\nThis is a special dialog. "..
"It will be called when the player clicks on ".. "It will be called when the player clicks on "..
"<b>Let's trade!</b>.".. "<b>Let's trade!</b>."..
@ -370,7 +389,7 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
"player.".. "player."..
"\n</normal>]") "\n</normal>]")
elseif(c_d_id == "d_dynamic") then elseif(c_d_id == "d_dynamic") then
table.insert(formspec, "hypertext[0.2,5;19.6,17.8;d_text;".. table.insert(formspec, "hypertext"..tmp..
"<normal>Note:\nThis is a special dialog. ".. "<normal>Note:\nThis is a special dialog. "..
"Each time right before this special dialog is displayed, a ".. "Each time right before this special dialog is displayed, a "..
"function is called that can fill the <b>d_dynamic</b> dialog ".. "function is called that can fill the <b>d_dynamic</b> dialog "..
@ -380,16 +399,16 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
"\nThe d_dynamic dialog is <b>never saved</b> as part of the dialog. ".. "\nThe d_dynamic dialog is <b>never saved</b> as part of the dialog. "..
"It has to be dynamicly created by your function each time it is needed.".. "It has to be dynamicly created by your function each time it is needed."..
"\nThe d_dynamic dialog will always be available as a <b>legitimate target ".. "\nThe d_dynamic dialog will always be available as a <b>legitimate target "..
"dialog</b> of a dialog option. Its options can do all that options of ".. "dialog</b> of a dialog option. Its options can do all that which "..
"other dialogs can do. Its options they can lead back to normal static ".. "options of other dialogs can do. Its options can also lead back to "..
"parts of the dialog.".. "normal static parts of the dialog."..
"\n</normal>]") "\n</normal>]")
elseif(active_dialog and active_dialog.d_text) then elseif(active_dialog and active_dialog.d_text) then
table.insert(formspec, "textarea[0.2,5;19.6,17.8;d_text;;".. table.insert(formspec, "textarea"..tmp..";"..
minetest.formspec_escape(active_dialog.d_text or "?").. minetest.formspec_escape(active_dialog.d_text or "?")..
"]") "]")
else else
table.insert(formspec, "textarea[0.2,5;19.6,17.8;d_text;;".. table.insert(formspec, "textarea"..tmp..";"..
minetest.formspec_escape("[no text]").. minetest.formspec_escape("[no text]")..
"]") "]")
end end
@ -439,9 +458,7 @@ yl_speak_up.get_fs_talkdialog_line = function(
for k, v in pairs(results) do for k, v in pairs(results) do
if v.r_type == "dialog" if v.r_type == "dialog"
and (dialog.n_dialogs[v.r_value] ~= nil and (dialog.n_dialogs[v.r_value] ~= nil
or v.r_value == "d_end" or yl_speak_up.is_special_dialog(v.r_value)) then
or v.r_value == "d_trade"
or v.r_value == "d_got_item") then
-- there may be more than one in the data structure -- there may be more than one in the data structure
target_dialog = v.r_value target_dialog = v.r_value
elseif v.r_type ~= "dialog" then elseif v.r_type ~= "dialog" then
@ -458,7 +475,7 @@ yl_speak_up.get_fs_talkdialog_line = function(
only_once = "\nNote: This option can be selected only *once* per talk!" only_once = "\nNote: This option can be selected only *once* per talk!"
end end
yl_speak_up.add_formspec_element_with_tooltip_if(formspec, yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"button", tostring(9.6+offset)..","..h..";1,0.9", "button_" .. oid, "button", tostring(12.6+offset)..","..h..";1,0.9", "button_" .. oid,
arrow, arrow,
"Go to target dialog "..minetest.formspec_escape(target_dialog or "").. "Go to target dialog "..minetest.formspec_escape(target_dialog or "")..
" that will be shown when this option ("..oid..") is selected.".. " that will be shown when this option ("..oid..") is selected."..
@ -466,7 +483,7 @@ yl_speak_up.get_fs_talkdialog_line = function(
(target_dialog)) (target_dialog))
-- allow to set a new target dialog -- allow to set a new target dialog
table.insert(formspec, "dropdown["..tostring(5.0+offset)..","..h..";4.7,1;d_id_".. table.insert(formspec, "dropdown["..tostring(5.0+offset)..","..h..";7.7,1;d_id_"..
oid..";".. oid..";"..
dialog_list..";".. dialog_list..";"..
(d_id_to_dropdown_index[(target_dialog or "?")] or "0")..",]") (d_id_to_dropdown_index[(target_dialog or "?")] or "0")..",]")
@ -510,21 +527,21 @@ yl_speak_up.get_fs_talkdialog_line = function(
if(sb_v.o_autoanswer) then if(sb_v.o_autoanswer) then
table.insert(formspec, table.insert(formspec,
"label["..tostring(10.5+offset+0.2)..","..tostring(h+0.5)..";".. "label["..tostring(13.5+offset+0.2)..","..tostring(h+0.5)..";"..
minetest.formspec_escape("[Automaticly selected if preconditions are met] ".. minetest.formspec_escape("[Automaticly selected if preconditions are met] "..
tostring(sb_v.o_text_when_prerequisites_met)).. tostring(sb_v.o_text_when_prerequisites_met))..
"]") "]")
elseif(active_dialog.o_random) then elseif(active_dialog.o_random) then
table.insert(formspec, table.insert(formspec,
"label["..tostring(10.5+offset+0.2)..","..tostring(h+0.5)..";".. "label["..tostring(13.5+offset+0.2)..","..tostring(h+0.5)..";"..
minetest.formspec_escape("[One of these options is randomly selected] ".. minetest.formspec_escape("[One of these options is randomly selected] "..
tostring(sb_v.o_text_when_prerequisites_met)).. tostring(sb_v.o_text_when_prerequisites_met))..
"]") "]")
else else
-- show the actual text for the option -- show the actual text for the option
yl_speak_up.add_formspec_element_with_tooltip_if(formspec, yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"field", tostring(10.5+offset)..","..h..";".. "field", tostring(13.5+offset)..","..h..";"..
tostring(field_length-2.3)..",0.9", tostring(field_length-5.3)..",0.9",
"text_option_" .. oid, "text_option_" .. oid,
";"..minetest.formspec_escape(sb_v.o_text_when_prerequisites_met), ";"..minetest.formspec_escape(sb_v.o_text_when_prerequisites_met),
"Edit the text that is displayed on button "..oid..".", "Edit the text that is displayed on button "..oid..".",

View File

@ -518,7 +518,7 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, rec
pname, formspec, h, dialog, dialog_list, c_d_id, active_dialog, pname, formspec, h, dialog, dialog_list, c_d_id, active_dialog,
alternate_text) alternate_text)
-- we are finished with adding buttons and text etc. to the left side of the formspec -- we are finished with adding buttons and text etc. to the left side of the formspec
local left_window_fs = table.concat(res_edit_top.formspec, "\n") local left_window_fs = table.concat(res_edit_top.formspec, "")
dialog_list = res_edit_top.dialog_list dialog_list = res_edit_top.dialog_list
-- find the right index for the dialog_list dropdown above -- find the right index for the dialog_list dropdown above
local d_id_to_dropdown_index = res_edit_top.d_id_to_dropdown_index local d_id_to_dropdown_index = res_edit_top.d_id_to_dropdown_index

View File

@ -732,3 +732,28 @@ yl_speak_up.may_edit_npc = function(player, n_id)
or (yl_speak_up.speak_to[pname] or (yl_speak_up.speak_to[pname]
and yl_speak_up.speak_to[pname].may_edit_this_npc)) and yl_speak_up.speak_to[pname].may_edit_this_npc))
end end
yl_speak_up.is_special_dialog = function(d_id)
if(not(d_id)) then
return false
end
return (d_id == "d_trade" or d_id == "d_got_item" or d_id == "d_dynamic" or d_id == "d_end")
end
yl_speak_up.d_name_to_d_id = function(dialog, d_name)
if(not(dialog) or not(dialog.n_dialogs) or not(d_name) or d_name == "") then
return nil
end
-- it is already the ID of an existing dialog
if(dialog.n_dialogs[d_name]) then
return d_name
end
-- search all dialogs for one with a fitting d_name
for k,v in pairs(dialog.n_dialogs) do
if(v and v.d_name and v.d_name == d_name) then
return k
end
end
end