From 1d06c2a825b02cad4252aa550d85c0fc1a577d98 Mon Sep 17 00:00:00 2001 From: Sokomine Date: Mon, 18 Jul 2022 19:19:21 +0200 Subject: [PATCH] reformatted fs_talkdialog.lua --- fs_talkdialog.lua | 774 +++++++++++++++++++++++----------------------- 1 file changed, 386 insertions(+), 388 deletions(-) diff --git a/fs_talkdialog.lua b/fs_talkdialog.lua index cbdf3c3..0c6327a 100644 --- a/fs_talkdialog.lua +++ b/fs_talkdialog.lua @@ -7,12 +7,12 @@ yl_speak_up.stop_talking = function(pname) end yl_speak_up.input_talk = function(player, formname, fields) - if formname ~= "yl_speak_up:talk" then - return - end + if formname ~= "yl_speak_up:talk" then + return + end - local pname = player:get_player_name() - local o = "" + local pname = player:get_player_name() + local o = "" -- error: not talking? if(not(yl_speak_up.speak_to[pname])) then @@ -28,6 +28,7 @@ yl_speak_up.input_talk = function(player, formname, fields) return end + -- mobs_redo based NPC may follow their owner, stand or wander around local new_move_order = "" if(fields.order_stand) then new_move_order = "stand" @@ -52,7 +53,7 @@ yl_speak_up.input_talk = function(player, formname, fields) -- if in edit mode: detect if something was changed; if(edit_mode or fields.button_edit_name_and_description) then local result = yl_speak_up.edit_mode_apply_changes(pname, fields) - end + end -- show which dialogs point to this one if(edit_mode and fields.show_what_points_to_this_dialog) then @@ -96,67 +97,67 @@ yl_speak_up.input_talk = function(player, formname, fields) -- start edit mode (requires npc_talk_owner) if fields.button_start_edit_mode then - -- check if this particular NPC is really owned by this player or if the player has global privs - if(not(yl_speak_up.may_edit_npc(player, n_id))) then - minetest.chat_send_player(pname, "Sorry. You do not have the npc_talk_owner or npc_master priv.") - return - end - -- the staff allows to create multiple target dialogs as result; this makes no sense - -- and is too disambigous - if(yl_speak_up.check_for_disambigous_results(n_id, pname)) then - -- this needs to be fixed by someone with a staff; we don't know which dialog is the right - -- result - return - end - -- for older formspec versions: reset scroll counter - yl_speak_up.speak_to[pname].counter = 1 - yl_speak_up.speak_to[pname].option_index = 1 - -- enter edit mode with that particular NPC - yl_speak_up.edit_mode[pname] = yl_speak_up.speak_to[pname].n_id - -- load the NPC dialog anew - but only what the NPC itself has to say, no generic dialogs - yl_speak_up.speak_to[pname].dialog = yl_speak_up.load_dialog(n_id, false) - -- start a new chat - but this time in edit mode - yl_speak_up.speak_to[pname].d_id = nil - yl_speak_up.show_fs(player, "talk", {n_id = yl_speak_up.speak_to[pname].n_id, d_id = nil}) - return - -- end edit mode (does not require the priv; will only switch back to normal behaviour) - elseif fields.button_end_edit_mode then - -- if there are any changes done: ask first and don't end edit mode yet - yl_speak_up.show_fs(player, "quit", nil) - return + -- check if this particular NPC is really owned by this player or if the player has global privs + if(not(yl_speak_up.may_edit_npc(player, n_id))) then + minetest.chat_send_player(pname, "Sorry. You do not have the npc_talk_owner or npc_master priv.") + return + end + -- the staff allows to create multiple target dialogs as result; this makes no sense + -- and is too disambigous + if(yl_speak_up.check_for_disambigous_results(n_id, pname)) then + -- this needs to be fixed by someone with a staff; we don't know which dialog is the right + -- result + return + end + -- for older formspec versions: reset scroll counter + yl_speak_up.speak_to[pname].counter = 1 + yl_speak_up.speak_to[pname].option_index = 1 + -- enter edit mode with that particular NPC + yl_speak_up.edit_mode[pname] = yl_speak_up.speak_to[pname].n_id + -- load the NPC dialog anew - but only what the NPC itself has to say, no generic dialogs + yl_speak_up.speak_to[pname].dialog = yl_speak_up.load_dialog(n_id, false) + -- start a new chat - but this time in edit mode + yl_speak_up.speak_to[pname].d_id = nil + yl_speak_up.show_fs(player, "talk", {n_id = yl_speak_up.speak_to[pname].n_id, d_id = nil}) + return + -- end edit mode (does not require the priv; will only switch back to normal behaviour) + elseif fields.button_end_edit_mode then + -- if there are any changes done: ask first and don't end edit mode yet + yl_speak_up.show_fs(player, "quit", nil) + return end - if fields.quit or fields.button_exit then - -- if there are any changes done: ask first and don't quit yet - yl_speak_up.show_fs(player, "quit", nil) - return - end + if fields.quit or fields.button_exit then + -- if there are any changes done: ask first and don't quit yet + yl_speak_up.show_fs(player, "quit", nil) + return + end -- allow the player to take the item back if(fields.show_player_offers_item and fields.show_player_offers_item ~= "") then - yl_speak_up.show_fs(player, "player_offers_item", nil) - return + yl_speak_up.show_fs(player, "player_offers_item", nil) + return end - if fields.button_up then - yl_speak_up.speak_to[pname].option_index = - yl_speak_up.speak_to[pname].option_index + yl_speak_up.max_number_of_buttons - yl_speak_up.show_fs(player, "talk", {n_id = yl_speak_up.speak_to[pname].n_id, - d_id = yl_speak_up.speak_to[pname].d_id}) - return - elseif fields.button_down then --and yl_speak_up.speak_to[pname].option_index > yl_speak_up.max_number_of_buttons then - yl_speak_up.speak_to[pname].option_index = - yl_speak_up.speak_to[pname].option_index - yl_speak_up.max_number_of_buttons - if yl_speak_up.speak_to[pname].option_index < 0 then - yl_speak_up.speak_to[pname].option_index = 1 - end - yl_speak_up.show_fs(player, "talk", {n_id = yl_speak_up.speak_to[pname].n_id, - d_id = yl_speak_up.speak_to[pname].d_id}) - return - else - yl_speak_up.speak_to[pname].option_index = 1 - end + if fields.button_up then + yl_speak_up.speak_to[pname].option_index = + yl_speak_up.speak_to[pname].option_index + yl_speak_up.max_number_of_buttons + yl_speak_up.show_fs(player, "talk", {n_id = yl_speak_up.speak_to[pname].n_id, + d_id = yl_speak_up.speak_to[pname].d_id}) + return + elseif fields.button_down then --and yl_speak_up.speak_to[pname].option_index > yl_speak_up.max_number_of_buttons then + yl_speak_up.speak_to[pname].option_index = + yl_speak_up.speak_to[pname].option_index - yl_speak_up.max_number_of_buttons + if yl_speak_up.speak_to[pname].option_index < 0 then + yl_speak_up.speak_to[pname].option_index = 1 + end + yl_speak_up.show_fs(player, "talk", {n_id = yl_speak_up.speak_to[pname].n_id, + d_id = yl_speak_up.speak_to[pname].d_id}) + return + else + yl_speak_up.speak_to[pname].option_index = 1 + end -- the player wants to see the trade list if(fields.show_trade_list) then @@ -187,33 +188,31 @@ yl_speak_up.input_talk = function(player, formname, fields) return end - for k, v in pairs(fields) do - -- only split into 2 parts at max - local s = string.split(k, "_", false, 2) + for k, v in pairs(fields) do + -- only split into 2 parts at max + local s = string.split(k, "_", false, 2) - if - s[1] == "button" and s[2] ~= nil and s[2] ~= "" and s[2] ~= "exit" and s[2] ~= "back" and s[3] ~= nil and - s[2] ~= "up" and - s[2] ~= "down" - then - o = s[2] .. "_" .. s[3] - end - end + if(s[1] == "button" + and s[2] ~= nil and s[2] ~= "" and s[2] ~= "exit" and s[2] ~= "back" and s[3] ~= nil + and s[2] ~= "up" and s[2] ~= "down") then + o = s[2] .. "_" .. s[3] + end + end if not(edit_mode) and o == "" then - return - end + return + end - -- Let's check if the button was among the "allowed buttons". Only those may be executed - if not(edit_mode) and (yl_speak_up.speak_to[pname].allowed and yl_speak_up.speak_to[pname].allowed[o] == false) then - return - end + -- Let's check if the button was among the "allowed buttons". Only those may be executed + if not(edit_mode) and (yl_speak_up.speak_to[pname].allowed and yl_speak_up.speak_to[pname].allowed[o] == false) then + return + end - -- button was clicked, now let's execute the results + -- button was clicked, now let's execute the results - local d_id = yl_speak_up.speak_to[pname].d_id + local d_id = yl_speak_up.speak_to[pname].d_id - local dialog = yl_speak_up.speak_to[pname].dialog + local dialog = yl_speak_up.speak_to[pname].dialog -- we may soon need actions and o_results from the selected_option local selected_option = {} @@ -236,35 +235,35 @@ yl_speak_up.input_talk = function(player, formname, fields) return end + -- if(edit_mode) (the other case has been dealt with above) -- all three buttons (pre(C)onditions, (Ef)fects, edit option) lead to the same new formspec - if( edit_mode ) then - local n_dialog = dialog.n_dialogs[d_id] + local n_dialog = dialog.n_dialogs[d_id] - if(n_dialog and n_dialog.d_options) then - for o_id,v in pairs(n_dialog.d_options) do - if( fields["edit_option_"..o_id] - or fields["conditions_"..o_id] - or fields["actions_"..o_id] - or fields["effects_"..o_id]) then - -- store which option we want to edit - yl_speak_up.speak_to[pname].o_id = o_id - -- if something was changed: ask for confirmation - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = yl_speak_up.speak_to[pname].n_id, - d_id = d_id, o_id = o_id, caller="button"}) - return - end + if(n_dialog and n_dialog.d_options) then + for o_id,v in pairs(n_dialog.d_options) do + if( fields["edit_option_"..o_id] + or fields["conditions_"..o_id] + or fields["actions_"..o_id] + or fields["effects_"..o_id]) then + -- store which option we want to edit + yl_speak_up.speak_to[pname].o_id = o_id + -- if something was changed: ask for confirmation + yl_speak_up.show_fs(player, "edit_option_dialog", + {n_id = yl_speak_up.speak_to[pname].n_id, + d_id = d_id, o_id = o_id, caller="button"}) + return end end + end - -- in edit mode: has another dialog been selected? - -- if nothing better can be found: keep the old dialog - local show_dialog = d_id - -- an option button was selected; - -- since we do not execute actions and effects in edit mode, we need to find out the - -- right target dialog manually (and assume all went correct) - if( o ~= "" ) then + -- in edit mode: has another dialog been selected? + -- if nothing better can be found: keep the old dialog + local show_dialog = d_id + -- an option button was selected; + -- since we do not execute actions and effects in edit mode, we need to find out the + -- right target dialog manually (and assume all went correct) + if( o ~= "" ) then -- find out the normal target dialog of this option if(selected_option and selected_option.o_results) then for k, v in pairs(selected_option.o_results) do @@ -273,24 +272,23 @@ yl_speak_up.input_talk = function(player, formname, fields) end end end - -- dropdown menu was used; provided the dialog exists (and it's not the "New dialog" option) - -- (if a new dialog was added using the "+" button, fields.d_id gets set accordingly) - elseif(fields.d_id and fields.d_id ~= show_dialog and dialog.n_dialogs[fields.d_id]) then - show_dialog = fields.d_id - -- in edit mode: prev_dialog_../next_dialog_.. was selected - else - for k,v in pairs(dialog.n_dialogs) do - if(fields["prev_dialog_"..k]) then - show_dialog = k - elseif(fields["next_dialog_"..k]) then - show_dialog = k - 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 + -- dropdown menu was used; provided the dialog exists (and it's not the "New dialog" option) + -- (if a new dialog was added using the "+" button, fields.d_id gets set accordingly) + elseif(fields.d_id and fields.d_id ~= show_dialog and dialog.n_dialogs[fields.d_id]) then + show_dialog = fields.d_id + -- in edit mode: prev_dialog_../next_dialog_.. was selected + else + for k,v in pairs(dialog.n_dialogs) do + if(fields["prev_dialog_"..k]) then + show_dialog = k + elseif(fields["next_dialog_"..k]) then + show_dialog = k + 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 end @@ -318,125 +316,125 @@ end -- recursion_depth is increased each time autoanswer is automaticly selected yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, recursion_depth) - local pname = player:get_player_name() - local dialog = yl_speak_up.speak_to[pname].dialog - local context_d_id = yl_speak_up.speak_to[pname].d_id - local active_dialog + local pname = player:get_player_name() + local dialog = yl_speak_up.speak_to[pname].dialog + local context_d_id = yl_speak_up.speak_to[pname].d_id + local active_dialog - if not player and not player:is_player() then - minetest.log( - "action", - "[MOD] yl_speak_up: User " .. - pname .. - " talked to unconfigured NPC with ID n_" .. - n_id .. ", position of user was " .. minetest.pos_to_string(player:get_pos(), 0) - ) - return yl_speak_up.get_error_message() - end + if not player and not player:is_player() then + minetest.log( + "action", + "[MOD] yl_speak_up: User " .. + pname .. + " talked to unconfigured NPC with ID n_" .. + n_id .. ", position of user was " .. minetest.pos_to_string(player:get_pos(), 0) + ) + return yl_speak_up.get_error_message() + end - -- currently no trade running (we're editing options) - yl_speak_up.trade[pname] = nil - yl_speak_up.speak_to[pname].trade_id = nil + -- currently no trade running (we're editing options) + yl_speak_up.trade[pname] = nil + yl_speak_up.speak_to[pname].trade_id = nil - --[[ If we have an explicit call for a certain d_id, we grab it from parameters. - If not, we grab in from context. - When neither are present, we grab it from d_sort - ]]-- - - local c_d_id - -- the generic start dialog contains only those options that are generic; - -- choose the right start dialog of the NPC - if(d_id ~= nil and d_id ~= "d_generic_start_dialog") then - active_dialog = dialog.n_dialogs[d_id] - c_d_id = d_id - elseif(d_id and d_id ~= "d_generic_start_dialog" and yl_speak_up.speak_to[pname].d_id ~= nil) then - c_d_id = yl_speak_up.speak_to[pname].d_id - active_dialog = dialog.n_dialogs[c_d_id] - elseif dialog.n_dialogs ~= nil then - -- Find the dialog with d_sort = 0 + --[[ If we have an explicit call for a certain d_id, we grab it from parameters. + If not, we grab in from context. + When neither are present, we grab it from d_sort + ]]-- + + local c_d_id + -- the generic start dialog contains only those options that are generic; + -- choose the right start dialog of the NPC + if(d_id ~= nil and d_id ~= "d_generic_start_dialog") then + active_dialog = dialog.n_dialogs[d_id] + c_d_id = d_id + elseif(d_id and d_id ~= "d_generic_start_dialog" and yl_speak_up.speak_to[pname].d_id ~= nil) then + c_d_id = yl_speak_up.speak_to[pname].d_id + active_dialog = dialog.n_dialogs[c_d_id] + elseif dialog.n_dialogs ~= nil then + -- Find the dialog with d_sort = 0 c_d_id = yl_speak_up.get_start_dialog_id(dialog) if(c_d_id) then active_dialog = dialog.n_dialogs[c_d_id] end - else + else -- it may be possible that this player can initialize this npc - minetest.log( - "action", - "[MOD] yl_speak_up: User " .. - pname .. - " talked to unconfigured NPC with ID n_" .. - n_id .. ", position of user was " .. minetest.pos_to_string(player:get_pos(), 0) - ) - -- this is the initial config - -- (input ends up at yl_speak_up.input_talk and needs to be rerouted) - return yl_speak_up.get_fs_initial_config(player, n_id, d_id, true) - end + minetest.log( + "action", + "[MOD] yl_speak_up: User " .. + pname .. + " talked to unconfigured NPC with ID n_" .. + n_id .. ", position of user was " .. minetest.pos_to_string(player:get_pos(), 0) + ) + -- this is the initial config + -- (input ends up at yl_speak_up.input_talk and needs to be rerouted) + return yl_speak_up.get_fs_initial_config(player, n_id, d_id, true) + end - if c_d_id == nil then return yl_speak_up.get_error_message() end + if c_d_id == nil then return yl_speak_up.get_error_message() end - yl_speak_up.speak_to[pname].d_id = c_d_id + yl_speak_up.speak_to[pname].d_id = c_d_id - -- Now we have a dialog to display to the user + -- Now we have a dialog to display to the user - -- do not crash in case of error - if(not(active_dialog)) then - return "size[6,2]".. - "label[0.2,0.5;Ups! Something went wrong. Please try again.]" - end + -- do not crash in case of error + if(not(active_dialog)) then + return "size[6,2]".. + "label[0.2,0.5;Ups! Something went wrong. Please try again.]" + end - -- 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) + -- 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) - -- evaluate the preconditions of each option and check if the option can be offered - local allowed = yl_speak_up.calculate_displayable_options(pname, active_dialog.d_options, edit_mode, + -- evaluate the preconditions of each option and check if the option can be offered + local allowed = yl_speak_up.calculate_displayable_options(pname, active_dialog.d_options, edit_mode, -- avoid loops by limiting max recoursion depths for autoanswers (recursion_depth < yl_speak_up.max_allowed_recursion_depth)) - -- abort here if needed - the autoanswer/autoselection did choose an option for us alread - if(not(edit_mode) and allowed and allowed["autoanswer"] and allowed["autoanswer"] ~= "") then - -- no actions shall be executed - local o_id = allowed["autoanswer"] - local effects = active_dialog.d_options[o_id].o_results - -- execute all effects/results - local res = yl_speak_up.execute_all_relevant_effects(player, effects, o_id, true) - local target_dialog = res.next_dialog - yl_speak_up.speak_to[pname].o_id = nil - yl_speak_up.speak_to[pname].a_id = nil - -- end the conversation? - if(target_dialog and target_dialog == "d_end") then - yl_speak_up.stop_talking(pname) - -- a formspec is expected here; provide one that has an exit button only - return "size[2,1]".. - "button_exit[0,0;1,1;Exit;exit]" + -- abort here if needed - the autoanswer/autoselection did choose an option for us alread + if(not(edit_mode) and allowed and allowed["autoanswer"] and allowed["autoanswer"] ~= "") then + -- no actions shall be executed + local o_id = allowed["autoanswer"] + local effects = active_dialog.d_options[o_id].o_results + -- execute all effects/results + local res = yl_speak_up.execute_all_relevant_effects(player, effects, o_id, true) + local target_dialog = res.next_dialog + yl_speak_up.speak_to[pname].o_id = nil + yl_speak_up.speak_to[pname].a_id = nil + -- end the conversation? + if(target_dialog and target_dialog == "d_end") then + yl_speak_up.stop_talking(pname) + -- a formspec is expected here; provide one that has an exit button only + return "size[2,1]".. + "button_exit[0,0;1,1;Exit;exit]" + end + if(not(target_dialog) + or target_dialog == "" + or not(dialog.n_dialogs[target_dialog])) then + target_dialog = yl_speak_up.speak_to[pname].d_id + end + -- show the new target dialog and exit + -- the recursion_depth will be increased by one (we did autoselect here and need to + -- avoid infinite loops) + return yl_speak_up.get_fs_talkdialog(player, n_id, target_dialog, res.alternate_text, + recursion_depth + 1) end - if(not(target_dialog) - or target_dialog == "" - or not(dialog.n_dialogs[target_dialog])) then - target_dialog = yl_speak_up.speak_to[pname].d_id - end - -- show the new target dialog and exit - -- the recursion_depth will be increased by one (we did autoselect here and need to - -- avoid infinite loops) - return yl_speak_up.get_fs_talkdialog(player, n_id, target_dialog, res.alternate_text, - recursion_depth + 1) - end - -- is the player comming back from trying to offer something to the NPC? - -- And is the NPC trying to return the item? - if(not(edit_mode) and d_id == "d_got_item") then - local pname = player:get_player_name() - local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) - if(not(trade_inv:is_empty("npc_wants"))) then - return "formspec_version[1]".. - yl_speak_up.show_fs_simple_deco(8, 2.5).. - "label[0.5,0.5;".. - minetest.formspec_escape(dialog.n_npc or "- ? -").. - " does not seem to be intrested in that.\n".. - "Please take your item back and try something else.]".. - "button[3.5,1.5;1.5,1.0;show_player_offers_item;Ok]" + -- is the player comming back from trying to offer something to the NPC? + -- And is the NPC trying to return the item? + if(not(edit_mode) and d_id == "d_got_item") then + local pname = player:get_player_name() + local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) + if(not(trade_inv:is_empty("npc_wants"))) then + return "formspec_version[1]".. + yl_speak_up.show_fs_simple_deco(8, 2.5).. + "label[0.5,0.5;".. + minetest.formspec_escape(dialog.n_npc or "- ? -").. + " does not seem to be intrested in that.\n".. + "Please take your item back and try something else.]".. + "button[3.5,1.5;1.5,1.0;show_player_offers_item;Ok]" + end end - end - yl_speak_up.speak_to[pname].allowed = allowed + yl_speak_up.speak_to[pname].allowed = allowed local pname_for_old_fs = yl_speak_up.get_pname_for_old_fs(pname) @@ -446,7 +444,7 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, rec -- this is used to build a list of all available dialogs for a dropdown menu in edit mode -- (only relevant in edit mode) - local dialog_list = yl_speak_up.text_new_dialog_id + local dialog_list = yl_speak_up.text_new_dialog_id -- find the right index for the dialog_list dropdown above local d_id_to_dropdown_index = {} @@ -457,55 +455,55 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, rec -- display the window with the text the NPC is saying if(edit_mode and dialog and dialog.n_dialogs) then - -- sort all dialogs by d_sort - 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 - -- build the list of available dialogs for the dropdown list(s) - dialog_list = dialog_list..","..minetest.formspec_escape(d) - 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, - "<", - "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, - ">", - "Go to next dialog "..next_dialog..".", - (sorted_list[ i+1 ])) - end - d_id_to_dropdown_index[d] = i + 1 - end - dialog_list = dialog_list..",d_end" - d_id_to_dropdown_index["d_end"] = #sorted_list + 2 + -- sort all dialogs by d_sort + 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 + -- build the list of available dialogs for the dropdown list(s) + dialog_list = dialog_list..","..minetest.formspec_escape(d) + 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, + "<", + "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, + ">", + "Go to next dialog "..next_dialog..".", + (sorted_list[ i+1 ])) + end + d_id_to_dropdown_index[d] = i + 1 + end + 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..";".. - d_id_to_dropdown_index[c_d_id]..",]") - table.insert(formspec, "tooltip[3.0,4.0;5,1;".. + 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..";".. + d_id_to_dropdown_index[c_d_id]..",]") + table.insert(formspec, "tooltip[3.0,4.0;5,1;".. "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", "+", "Create a new dialog.", true) - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, "button", "13.4,0.3;2,0.9", "button_edit_name_and_description", "Edit", "Edit name and description of your NPC.", true) - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, "button", "15.7,0.3;2,0.9", "button_save_dialog", "Save", "Save this dialog.", true) - table.insert(formspec, "textarea[0.2,5;19.6,17.8;d_text;;".. + table.insert(formspec, "textarea[0.2,5;19.6,17.8;d_text;;".. minetest.formspec_escape(active_dialog.d_text).. "]") end @@ -515,148 +513,148 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, rec -- empty formspec for the bottom part formspec = {} - h = -0.8 + h = -0.8 -- allow to delete entries that have no options later on local anz_options = 0 - -- Let#s sort the options by o_sort - if active_dialog ~= nil and active_dialog.d_options ~= nil then - local sorted_o_list = yl_speak_up.get_sorted_options(active_dialog.d_options, "o_sort") - for _, sb_v in ipairs(sorted_o_list) do - anz_options = anz_options + 1 - end + -- Let's sort the options by o_sort + if active_dialog ~= nil and active_dialog.d_options ~= nil then + local sorted_o_list = yl_speak_up.get_sorted_options(active_dialog.d_options, "o_sort") + for _, sb_v in ipairs(sorted_o_list) do + anz_options = anz_options + 1 + end - for _, s_o_id in ipairs(sorted_o_list) do - local sb_v = active_dialog.d_options[s_o_id] - local oid = minetest.formspec_escape(sb_v.o_id) - -- in edit_mode: show all options - if(edit_mode and yl_speak_up.old_fs_version_show_line(pname_for_old_fs)) then - local offset = 0.0 - local field_length = 44.4 - if(pname_for_old_fs) then - offset = 0.7 - field_length = 42.4 - end - h = h + 1 - -- add a button "o_:" that leads to an edit formspec for this option - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", tostring(2.3+offset).."," .. h .. ";2,0.9", "edit_option_" .. oid, - oid, - "Edit target dialog, pre(C)onditions and (Ef)fects for option "..oid..".", - true) - -- find the right target dialog for this option (if it exists): - local target_dialog = nil - local results = active_dialog.d_options[sb_v.o_id].o_results - -- has this option more results/effects than just switching to another dialog? - local has_other_results = false - if(results ~= nil) then - 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_got_item") then - -- there may be more than one in the data structure - target_dialog = v.r_value - elseif v.r_type ~= "dialog" then - has_other_results = true - end - end - end - -- add a button "-> d_" that leads to the target dialog (if one is set) - -- selecting an option this way MUST NOT execute the pre(C)onditions or (Ef)fects! - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", tostring(9.0+offset).."," .. h .. ";1,0.9", "button_" .. oid, - "->", - "Go to target dialog "..minetest.formspec_escape(target_dialog or "").. - " that will be shown when this option ("..oid..") is selected.", - (target_dialog)) - - -- allow to set a new target dialog - table.insert(formspec, "dropdown["..tostring(4.4+offset)..","..h..";4.7,1;d_id_".. - oid..";".. - dialog_list..";".. - (d_id_to_dropdown_index[(target_dialog or "?")] or "0")..",]") - -- add a tooltip "Change target dialog" - table.insert(formspec, "tooltip[4.4,"..h..";4.7,1;".. - "Change target dialog for option "..oid..".;#FFFFFF;#000000]") - - -- are there any prerequirements? - local prereq = active_dialog.d_options[sb_v.o_id].o_prerequisites - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", tostring(0.5+offset).."," .. h .. ";0.5,0.9", "conditions_"..oid, - "C", - "There are pre(C)onditions required for showing this option. Display them.", - (prereq and next(prereq))) - - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", tostring(1.6+offset).."," .. h .. ";0.6,0.9", "effects_"..oid, - "Ef", - "There are further (Ef)fects (apart from switching\n".. - "to a new dialog) set for this option. Display them.", - (has_other_results)) - - -- are there any actions defined? - local actions = active_dialog.d_options[sb_v.o_id].actions - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", tostring(1.1+offset).."," .. h .. ";0.5,0.9", "actions_"..oid, - "A", - "There is an (A)ction (i.e. a trade) that will happen\n".. - "when switching to a new dialog. Display actions and\n".. - "trade of this option.", - (actions and next(actions))) - - -- show the actual text for the option - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "field", tostring(9.9+offset).."," .. h .. ";".. - tostring(field_length)..",0.9", - "text_option_" .. oid, - ";"..minetest.formspec_escape(sb_v.o_text_when_prerequisites_met), - "Edit the text that is displayed on button "..oid..".", - true) - - -- normal mode: show an option if the prerequirements (if any are defined) are met - elseif(not(edit_mode)) then - local t = "- no text given -" - local t_alt = nil - -- the preconditions are fulfilled; showe the option - if(allowed[sb_v.o_id] == true) then - -- replace $NPC_NAME$ etc. - t = minetest.formspec_escape(yl_speak_up.replace_vars_in_text( - sb_v.o_text_when_prerequisites_met, dialog, pname)) - -- precondition not fulfilled? the option shall be hidden - elseif(sb_v.o_hide_when_prerequisites_not_met == "true") then - -- show nothing; t_alt remains nil - t = nil - -- precondition not fulfilled? the option shall be greyed out - -- default to greyed out (this option cannot be selected) - elseif(sb_v.o_grey_when_prerequisites_not_met == "true") then - local text = sb_v.o_text_when_prerequisites_not_met - if(not(text) or text == "") then - text = t or yl_speak_up.message_button_option_prerequisites_not_met_default + for _, s_o_id in ipairs(sorted_o_list) do + local sb_v = active_dialog.d_options[s_o_id] + local oid = minetest.formspec_escape(sb_v.o_id) + -- in edit_mode: show all options + if(edit_mode and yl_speak_up.old_fs_version_show_line(pname_for_old_fs)) then + local offset = 0.0 + local field_length = 44.4 + if(pname_for_old_fs) then + offset = 0.7 + field_length = 42.4 + end + h = h + 1 + -- add a button "o_:" that leads to an edit formspec for this option + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + "button", tostring(2.3+offset).."," .. h .. ";2,0.9", "edit_option_" .. oid, + oid, + "Edit target dialog, pre(C)onditions and (Ef)fects for option "..oid..".", + true) + -- find the right target dialog for this option (if it exists): + local target_dialog = nil + local results = active_dialog.d_options[sb_v.o_id].o_results + -- has this option more results/effects than just switching to another dialog? + local has_other_results = false + if(results ~= nil) then + 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_got_item") then + -- there may be more than one in the data structure + target_dialog = v.r_value + elseif v.r_type ~= "dialog" then + has_other_results = true + end + end + end + -- add a button "-> d_" that leads to the target dialog (if one is set) + -- selecting an option this way MUST NOT execute the pre(C)onditions or (Ef)fects! + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + "button", tostring(9.0+offset)..","..h..";1,0.9", "button_" .. oid, + "->", + "Go to target dialog "..minetest.formspec_escape(target_dialog or "").. + " that will be shown when this option ("..oid..") is selected.", + (target_dialog)) + + -- allow to set a new target dialog + table.insert(formspec, "dropdown["..tostring(4.4+offset)..","..h..";4.7,1;d_id_".. + oid..";".. + dialog_list..";".. + (d_id_to_dropdown_index[(target_dialog or "?")] or "0")..",]") + -- add a tooltip "Change target dialog" + table.insert(formspec, "tooltip[4.4,"..h..";4.7,1;".. + "Change target dialog for option "..oid..".;#FFFFFF;#000000]") + + -- are there any prerequirements? + local prereq = active_dialog.d_options[sb_v.o_id].o_prerequisites + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + "button", tostring(0.5+offset)..","..h..";0.5,0.9", "conditions_"..oid, + "C", + "There are pre(C)onditions required for showing this option. Display them.", + (prereq and next(prereq))) + + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + "button", tostring(1.6+offset)..","..h..";0.6,0.9", "effects_"..oid, + "Ef", + "There are further (Ef)fects (apart from switching\n".. + "to a new dialog) set for this option. Display them.", + (has_other_results)) + + -- are there any actions defined? + local actions = active_dialog.d_options[sb_v.o_id].actions + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + "button", tostring(1.1+offset)..","..h..";0.5,0.9", "actions_"..oid, + "A", + "There is an (A)ction (i.e. a trade) that will happen\n".. + "when switching to a new dialog. Display actions and\n".. + "trade of this option.", + (actions and next(actions))) + + -- show the actual text for the option + yl_speak_up.add_formspec_element_with_tooltip_if(formspec, + "field", tostring(9.9+offset)..","..h..";".. + tostring(field_length)..",0.9", + "text_option_" .. oid, + ";"..minetest.formspec_escape(sb_v.o_text_when_prerequisites_met), + "Edit the text that is displayed on button "..oid..".", + true) + + -- normal mode: show an option if the prerequirements (if any are defined) are met + elseif(not(edit_mode)) then + local t = "- no text given -" + local t_alt = nil + -- the preconditions are fulfilled; showe the option + if(allowed[sb_v.o_id] == true) then + -- replace $NPC_NAME$ etc. + t = minetest.formspec_escape(yl_speak_up.replace_vars_in_text( + sb_v.o_text_when_prerequisites_met, dialog, pname)) + -- precondition not fulfilled? the option shall be hidden + elseif(sb_v.o_hide_when_prerequisites_not_met == "true") then + -- show nothing; t_alt remains nil + t = nil + -- precondition not fulfilled? the option shall be greyed out + -- default to greyed out (this option cannot be selected) + elseif(sb_v.o_grey_when_prerequisites_not_met == "true") then + local text = sb_v.o_text_when_prerequisites_not_met + if(not(text) or text == "") then + text = t or yl_speak_up.message_button_option_prerequisites_not_met_default + end + t = nil + -- replace $NPC_NAME$ etc. + t_alt = minetest.formspec_escape(yl_speak_up.replace_vars_in_text( + text, dialog, pname)) + elseif(sb_v.o_grey_when_prerequisites_not_met == "false" + and sb_v.o_text_when_prerequisites_not_met ~= "") then + -- show in normal coor + t = minetest.formspec_escape(yl_speak_up.replace_vars_in_text( + sb_v.o_text_when_prerequisites_not_met, dialog, pname)) + end + if(t or t_alt) then + -- actually show the button + h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, + "button_" .. oid, + t, + t, + (t and not(t_alt)), + t_alt, + nil, pname_for_old_fs) end - t = nil - -- replace $NPC_NAME$ etc. - t_alt = minetest.formspec_escape(yl_speak_up.replace_vars_in_text( - text, dialog, pname)) - elseif(sb_v.o_grey_when_prerequisites_not_met == "false" - and sb_v.o_text_when_prerequisites_not_met ~= "") then - -- show in normal coor - t = minetest.formspec_escape(yl_speak_up.replace_vars_in_text( - sb_v.o_text_when_prerequisites_not_met, dialog, pname)) - end - if(t or t_alt) then - -- actually show the button - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "button_" .. oid, - t, - t, - (t and not(t_alt)), - t_alt, - nil, pname_for_old_fs) end end - end - end + end -- with automatic selection from the start dialog, it is possible that the -- real start dialog is never shown; thus, add those buttons which need to @@ -840,6 +838,6 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, rec local bottom_window_fs = table.concat(formspec, "\n") return yl_speak_up.show_fs_decorated(pname, edit_mode, h, alternate_text, - left_window_fs, bottom_window_fs, + left_window_fs, bottom_window_fs, active_dialog, h) end