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)
target_dialog = yl_speak_up.add_new_dialog(dialog, pname, nil)
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
local result = {} --{r_value = "-default-"}
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
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
table.insert(yl_speak_up.npc_was_changed[ n_id ],
"Dialog "..d_id..": The target dialog for option "..
tostring(o_id).." was changed from "..
tostring(result.r_value or "-default-").." to "..
tostring(target_dialog)..".")
old_d.." to "..new_d..".")
-- does the result/effect of type "dialog" exist already? then we're done
if(result.r_type and result.r_type == "dialog") then
-- 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
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
if(fields[ "add_option"]) then
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]
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?
-- if nothing better can be found: keep the old dialog
local show_dialog = d_id
@ -192,6 +194,7 @@ yl_speak_up.input_talk = function(player, formname, fields)
end
end
end
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
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")
-- add buttons for previous/next dialog
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)
dialog_list = dialog_list..","..minetest.formspec_escape(d)
dialog_list = dialog_list..","..minetest.formspec_escape(d_name)
if(d == c_d_id) then
local prev_dialog = tostring(minetest.formspec_escape(sorted_list[i-1]))
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..".",
(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,
"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..".",
(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"
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")..",]")
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..
" is beeing displayed.;#FFFFFF;#000000]")
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.",
true)
@ -307,9 +325,10 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
true)
local tmp = "[0.2,6;19.6,16.8;d_text;"
-- static help text instead of text input field for d_got_item
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. "..
"It will be called when the player clicks on "..
"<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>]")
-- static help text instead of text input field for d_trade
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. "..
"It will be called when the player clicks on "..
"<b>Let's trade!</b>."..
@ -370,7 +389,7 @@ yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, d
"player."..
"\n</normal>]")
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. "..
"Each time right before this special dialog is displayed, a "..
"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. "..
"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 "..
"dialog</b> of a dialog option. Its options can do all that options of "..
"other dialogs can do. Its options they can lead back to normal static "..
"parts of the dialog."..
"dialog</b> of a dialog option. Its options can do all that which "..
"options of other dialogs can do. Its options can also lead back to "..
"normal static parts of the dialog."..
"\n</normal>]")
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 "?")..
"]")
else
table.insert(formspec, "textarea[0.2,5;19.6,17.8;d_text;;"..
table.insert(formspec, "textarea"..tmp..";"..
minetest.formspec_escape("[no text]")..
"]")
end
@ -439,9 +458,7 @@ yl_speak_up.get_fs_talkdialog_line = function(
for k, v in pairs(results) do
if v.r_type == "dialog"
and (dialog.n_dialogs[v.r_value] ~= nil
or v.r_value == "d_end"
or v.r_value == "d_trade"
or v.r_value == "d_got_item") then
or yl_speak_up.is_special_dialog(v.r_value)) then
-- there may be more than one in the data structure
target_dialog = v.r_value
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!"
end
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,
"Go to target dialog "..minetest.formspec_escape(target_dialog or "")..
" that will be shown when this option ("..oid..") is selected."..
@ -466,7 +483,7 @@ yl_speak_up.get_fs_talkdialog_line = function(
(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..";"..
dialog_list..";"..
(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
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] "..
tostring(sb_v.o_text_when_prerequisites_met))..
"]")
elseif(active_dialog.o_random) then
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] "..
tostring(sb_v.o_text_when_prerequisites_met))..
"]")
else
-- show the actual text for the option
yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
"field", tostring(10.5+offset)..","..h..";"..
tostring(field_length-2.3)..",0.9",
"field", tostring(13.5+offset)..","..h..";"..
tostring(field_length-5.3)..",0.9",
"text_option_" .. oid,
";"..minetest.formspec_escape(sb_v.o_text_when_prerequisites_met),
"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,
alternate_text)
-- 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
-- find the right index for the dialog_list dropdown above
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]
and yl_speak_up.speak_to[pname].may_edit_this_npc))
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