-- process input from formspec created in get_fs_edit_option_dialog(..) yl_speak_up.input_edit_option_dialog = function(player, formname, fields) if formname ~= "yl_speak_up:edit_option_dialog" then return end local pname = player:get_player_name() -- Is the player working on this particular npc? local edit_mode = (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id) if(not(edit_mode) or not(fields.o_id)) then return end local n_id = yl_speak_up.speak_to[pname].n_id local d_id = yl_speak_up.speak_to[pname].d_id -- this is passed on as a hidden field local o_id = fields.o_id local dialog = yl_speak_up.speak_to[pname].dialog local n_dialog = dialog.n_dialogs[d_id] local d_option = n_dialog.d_options[o_id] -- this meny is specific to an option for a dialog; if no dialog is selected, we really -- can't know what to do if(not(d_id)) then return end -- handles changes to o_text_when_prerequisites_met, target dialog, adding of a new dialog local result = yl_speak_up.edit_mode_apply_changes(pname, fields) -- if a new option was added or the target dialog of this one changed, display the right new option if(result and result["show_next_option"] and n_dialog.d_options[result["show_next_option"]]) then yl_speak_up.show_fs(player, "edit_option_dialog", {n_id = n_id, d_id = d_id, o_id = result["show_next_option"], caller="show_next_option"}) return end -- back to the main dialog window? -- (this also happens when the last option was deleted) if(fields.show_current_dialog or fields.quit or fields.button_exit or not(d_option) or fields.del_option) then yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id}) return end -- for now, there's only trade as action if(fields.table_of_actions) then local trade_id = tostring(d_id).." "..tostring(o_id) if(dialog.trades and dialog.trades[ trade_id ]) then fields.effect_show_trade = true else fields.effect_add_trade = true end end -- add or edit the trade associated with this dialog and option if(fields.effect_add_trade) then -- remember which option was selected yl_speak_up.speak_to[pname].o_id = o_id -- do not switch target dialog (we are in edit mode) yl_speak_up.speak_to[pname].target_d_id = nil -- create a new trade for this dialog and option - with ID " " yl_speak_up.show_fs(player, "add_trade_simple", tostring(d_id).." "..tostring(o_id)) return -- the player wants to see the previous option/answer elseif(fields.edit_option_prev) then -- sort all options by o_sort local sorted_list = yl_speak_up.get_sorted_options(n_dialog.d_options, "o_sort") local o_found = o_id for i, o in ipairs(sorted_list) do if(o == o_id and sorted_list[ i-1]) then o_found = sorted_list[ i-1 ] end end -- show that dialog; fallback: show the same (o_id) again yl_speak_up.show_fs(player, "edit_option_dialog", {n_id = n_id, d_id = d_id, o_id = o_found, caller="prev option"}) return -- the player wants to see the next option/answer elseif(fields.edit_option_next) then -- sort all options by o_sort local sorted_list = yl_speak_up.get_sorted_options(n_dialog.d_options, "o_sort") local o_found = o_id for i, o in ipairs(sorted_list) do if(o == o_id and sorted_list[ i+1 ]) then o_found = sorted_list[ i+1 ] end end -- show that dialog; fallback: show the same (o_id) again yl_speak_up.show_fs(player, "edit_option_dialog", {n_id = n_id, d_id = d_id, o_id = o_found, caller="next option"}) return -- show the trade associated with this dialog and option elseif(fields.effect_show_trade) then -- remember which option was selected yl_speak_up.speak_to[pname].o_id = o_id -- do not switch target dialog (we are in edit mode) yl_speak_up.speak_to[pname].target_d_id = nil -- show the trade with ID " " yl_speak_up.show_fs(player, "trade_simple", tostring(d_id).." "..tostring(o_id)) return -- the player clicked on a precondition elseif(fields.table_of_preconditions) then -- the player clicked on an effect elseif(fields.table_of_effects) then end -- if ESC is pressed or anything else unpredicted happens: go back to the main dialog edit window -- reason: don't loose any unsaved changes to the dialog yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id}) end -- edit options (not via staff but via the "I am your owner" dialog) yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id) -- n_id, d_id and o_id have already been checked when this function is called local pname = player:get_player_name() local dialog = yl_speak_up.speak_to[pname].dialog local n_dialog = dialog.n_dialogs[d_id] local d_option = n_dialog.d_options[o_id] -- currently no trade running (we're editing options) yl_speak_up.trade[pname] = nil yl_speak_up.speak_to[pname].trade_id = nil if(not(d_option)) then return "size[6,2]".. "label[0.2,0.5;Ups! Option "..minetest.formspec_escape(tostring(o_id)).. " does not exist.]".. "button_exit[2,1.5;1,0.9;exit;Exit]" end -- are there any preconditions? local list_of_preconditions = "" local prereq = d_option.o_prerequisites if(prereq) then local sorted_key_list = yl_speak_up.sort_keys(prereq) for i, k in ipairs(sorted_key_list) do local v = prereq[ k ] list_of_preconditions = list_of_preconditions.. minetest.formspec_escape(v.p_id)..",#FFFF00,".. minetest.formspec_escape(v.p_type)..",".. minetest.formspec_escape(v.p_value).."," end end list_of_preconditions = list_of_preconditions..",#00FF00,add,Add a new pre(C)ondition" local list_of_actions = "" if(dialog.trades and dialog.trades[ tostring(d_id).." "..tostring(o_id) ]) then local tr = dialog.trades[ tostring(d_id).." "..tostring(o_id)] -- show the trade in the result/effects list list_of_actions = ",#FF8800,trade,".. -- show a reasonable overview of what is traded for what minetest.formspec_escape("NPC sells ".. table.concat(tr.buy, ";").." for ".. table.concat(tr.pay, ";")) else list_of_actions = ",#00FF00,add,Add a new (A)ction" end -- find the right target dialog for this option (if it exists) local target_dialog = nil -- and build the list of effects local list_of_effects = "" local results = d_option.o_results if(results) then local sorted_key_list = yl_speak_up.sort_keys(results) for i, k in ipairs(sorted_key_list) do local v = results[ k ] if v.r_type == "dialog" and dialog.n_dialogs[v.r_value] ~= nil then -- there may be more than one in the data structure target_dialog = v.r_value elseif v.r_type ~= "dialog" then list_of_effects = list_of_effects.. minetest.formspec_escape(v.r_id)..",#FFFF00,".. minetest.formspec_escape(v.r_type)..",".. minetest.formspec_escape(v.r_value).."," end end end list_of_effects = list_of_effects..",#00FF00,add,Add a new (Ef)fect" -- if no target dialog has been selected: default is to go to the dialog with d_sort 0 if(not(target_dialog) or target_dialog == "" or not(dialog.n_dialogs[target_dialog])) then for d, v in pairs(dialog.n_dialogs) do if(v.d_sort and tonumber(v.d_sort) == 0) then target_dialog = d end end end -- this is the text the NPC will say in reaction to this answer local next_text = "" if(target_dialog and dialog.n_dialogs[target_dialog]) then next_text = dialog.n_dialogs[target_dialog].d_text end -- build the list of available dialogs for the dropdown list(s) local dialog_list = yl_speak_up.text_new_dialog_id local dialog_selected = "1" -- if there are dialogs defined if(dialog and dialog.n_dialogs) then -- the first entry will be "New dialog" local n = 1 for k, v in pairs(dialog.n_dialogs) do dialog_list = dialog_list .. "," .. minetest.formspec_escape(v.d_id) -- which one is the current dialog? n = n + 1 if(v.d_id == target_dialog) then dialog_selected = tostring(n) end end end if(not(target_dialog)) then target_dialog = "- none -" end -- offer the correct preselection for hidden/grey/show text local alternate_answer_option = "3" if(d_option.o_hide_when_prerequisites_not_met == "true") then alternate_answer_option = "1" elseif(d_option.o_grey_when_prerequisites_not_met == "true") then alternate_answer_option = "2" end -- can the button "prev(ious)" be shown? local button_prev = "" -- can the button "next" be shown? local button_next = "" -- sort all options by o_sort local sorted_list = yl_speak_up.get_sorted_options(n_dialog.d_options, "o_sort") local o_found = o_id local anz_options = 0 for i, o in ipairs(sorted_list) do if(o == o_id and sorted_list[ i-1 ]) then button_prev = "".. "button[7.4,18.7;2.0,0.9;edit_option_prev;Prev]".. "tooltip[edit_option_prev;Go to previous option/answer ".. "(according to o_sort).]" end if(o == o_id and sorted_list[ i+1 ]) then button_next = "".. "button[12.0,18.7;2.0,0.9;edit_option_next;Next]".. "tooltip[edit_option_next;Go to next option/answer ".. "(according to o_sort).]" end anz_options = anz_options + 1 end -- less than yl_speak_up.max_number_of_options_per_dialog options? local button_add = "".. "button[2.4,18.7;2.0,0.9;add_option;Add]".. "tooltip[add_option;Add a new option/answer to this dialog.]" if(anz_options >= yl_speak_up.max_number_of_options_per_dialog) then button_add = "" end -- build up the formspec local formspec = "".. "formspec_version[3]".. "size[21,20]".. "bgcolor[#00000000;false]".. -- button back to the current dialog (of which this is an option) "button[15.8,0.2;5.0,0.9;show_current_dialog;Back to dialog ".. minetest.formspec_escape(d_id).."]".. "tooltip[show_current_dialog;Go back to dialog ".. minetest.formspec_escape(d_id).." and continue editing that dialog.]".. -- the text the NPC says "label[0.2,0.6;NPC says:]".. "hypertext[1.2,1.2;19.6,2.5;d_text;".. minetest.formspec_escape(n_dialog.d_text) .. "\n".."]".. "tooltip[1.2,1.2;19.6,3.0;This is what the NPC says to the player.]".. -- list the preconditions "label[0.2,4.2;If all of the following pre(C)onditions are fulfilled:]".. -- TODO: perhaps add tooltip for the type of the conditions "tablecolumns[text;color,span=1;text;text]".. "table[1.2,4.5;19.6,2.0;table_of_preconditions;".. list_of_preconditions..";0]".. -- answer of the player (the actual option) "label[0.2,6.8;..the player may answer with this text:]".. "label[1.2,7.6;A:]".. "field[1.7,7.1;19.1,0.9;text_option_"..minetest.formspec_escape(o_id)..";;".. minetest.formspec_escape(d_option.o_text_when_prerequisites_met).."]".. "tooltip[option_text_met;This is the answer the player may choose if the ".. "preconditions are all fulfilled.]".. -- dropdown for selecting weather to show the alternate answer or not "label[0.2,8.6;..but if at least one pre(C)ondition is not fulfilled, then...]".. "dropdown[12.0,8.2;8.6,0.9;hide_or_grey_or_alternate_answer;".. "..hide this answer.,".. "..grey out this answer.,".. "..display the following alternate answer:;".. alternate_answer_option..";]".. -- alternate answer "label[1.2,9.6;A:]".. "field[1.7,9.1;19.1,0.9;option_text_not_met;;".. minetest.formspec_escape(d_option.o_text_when_prerequisites_not_met).."]".. "tooltip[option_text_not_met;This is the answer the player may choose if the ".. "preconditions are NOT all fulfilled.]".. -- list of (A)ctions (there can only be one per option; i.e. a trade) "label[0.2,10.6;When this answer has been selected, start the following (A)ction:]".. "tablecolumns[text;color,span=1;text;text]".. "table[1.2,10.9;19.6,0.7;table_of_actions;".. list_of_actions..";0]".. -- list of effects "label[0.2,12.0;If the player completed the above action successfully, ".. "apply the following (Ef)fects:]".. -- TODO: perhaps add tooltip for the type of the conditions "tablecolumns[text;color,span=1;text;text]".. "table[1.2,12.3;21.0,2.0;table_of_effects;".. list_of_effects..";0]".. -- ..and what the NPC will reply to that answer "label[0.2,15.1;The NPC will react to this answer with the following dialog:]".. "hypertext[1.2,15.7;19.6,2.5;d_text_next;".. minetest.formspec_escape(next_text) .. "\n".."]".. "tooltip[1.2,16.8;21.0,2.5;This is what the NPC will say next when the player has ".. "selected this answer here.]".. -- allow to change the target dialog via a dropdown menu "dropdown[14.8,14.7;5,0.9;d_id_"..minetest.formspec_escape(o_id)..";".. dialog_list..";"..dialog_selected..",]".. "tooltip[14.8,14.7;5,0.9;Select the target dialog with which the NPC shall react ".. "to this answer. Currently, dialog "..minetest.formspec_escape(target_dialog).. " is beeing displayed.;#FFFFFF;#000000]".. -- button: delete "button[0.2,18.7;2.0,0.9;del_option;Delete]".. "tooltip[del_option;Delete this option/answer.]".. -- button: add new button_add.. -- button: prev/next button_prev.. button_next.. -- button: go back to dialog (repeated from top of the page) "button[15.8,18.7;5.0,0.9;show_current_dialog;Back to dialog ".. minetest.formspec_escape(d_id).."]".. "tooltip[show_current_dialog;Go back to dialog ".. minetest.formspec_escape(d_id).." and continue editing that dialog.]".. -- allow to enter o_sort "label[9.6,19.2;Sort:]".. "field[10.6,18.7;1.0,0.9;edit_option_o_sort;;".. minetest.formspec_escape(d_option.o_sort).."]".. "tooltip[edit_option_o_sort;o_sort: The lower the number, the higher up in the ".. "list this option goes\nNegative values are ignored;#FFFFFF;#000000]".. -- hidden field containing the value of o_id "field[40,40;0.1,0.1;o_id;;"..minetest.formspec_escape(o_id).."]" return formspec end