From 2107b7833a2c14000ad02ab7b7134f697a7b4c9e Mon Sep 17 00:00:00 2001 From: Sokomine Date: Wed, 5 May 2021 16:39:17 +0200 Subject: [PATCH] added yl_speak_up.get_sorted_options for sorting by o_sort; used for prev and next buttons in option edit menu --- functions.lua | 67 +++++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/functions.lua b/functions.lua index ee4f736..b2c3079 100644 --- a/functions.lua +++ b/functions.lua @@ -948,24 +948,23 @@ local function get_fs_edit_option_dialog(player, n_id, d_id, o_id) local button_prev = "" -- can the button "next" be shown? local button_next = "" - for o,v in pairs(n_dialog.d_options) do - -- the button prev can appear if there is at least one option with lower o_sort - if(button_prev == "" and v.o_sort and v.o_sort ~= "" and d_option.o_sort - and tonumber(v.o_sort) < tonumber(d_option.o_sort)) then + -- sort all options by o_sort + local sorted_list = yl_speak_up.get_sorted_options(n_dialog.d_options) + local o_found = o_id + for i, o in ipairs(sorted_list) do + if(o == o_id and sorted_list[ i-1 ]) then button_prev = "".. "button[7.4,17;2.0,0.9;edit_option_prev;Prev]".. "tooltip[edit_option_prev;Go to previous option/answer ".. "(according to o_sort).]" - -- the button next can appear if there is at least one option with a higher o_sort - elseif(button_next == "" and v.o_sort and v.o_sort ~= "" and d_option.o_sort - and tonumber(v.o_sort) > tonumber(d_option.o_sort)) then + end + if(o == o_id and sorted_list[ i+1 ]) then button_next = "".. "button[12.0,17;2.0,0.9;edit_option_next;Next]".. "tooltip[edit_option_next;Go to next option/answer ".. "(according to o_sort).]" end end - -- build up the formspec local formspec = "".. "formspec_version[3]".. @@ -1026,11 +1025,11 @@ local function get_fs_edit_option_dialog(player, n_id, d_id, o_id) "to this answer. Currently, dialog "..minetest.formspec_escape(target_dialog).. " is beeing displayed.;#FFFFFF;#000000]".. -- button: delete - "button[0.2,17;2.0,0.9;edit_option_delete;Delete]".. - "tooltip[edit_option_delete;Delete this option/answer.]".. + "button[0.2,17;2.0,0.9;del_option;Delete]".. + "tooltip[del_option;Delete this option/answer.]".. -- button: add new "button[2.4,17;2.0,0.9;add_option;Add]".. - "tooltip[edit_option_add;Add a new option/answer to this dialog.]".. + "tooltip[add_option;Add a new option/answer to this dialog.]".. -- button: prev/next button_prev.. button_next.. @@ -2019,6 +2018,23 @@ yl_speak_up.save_changes_and_switch_to_other_dialog = function(player, fields, t end +-- helper function for sorting options/answers using options[o_id].o_sort +yl_speak_up.get_sorted_options = function(options) + local sorted_list = {} + for k,v in pairs(options) do + table.insert(sorted_list, k) + end + table.sort(sorted_list, + function(a,b) + return tonumber(options[a].o_sort) + and tonumber(options[b].o_sort) + and tonumber(options[a].o_sort) < tonumber(options[b].o_sort) + end + ) + return sorted_list +end + + -- helper function for formspec "yl_speak_up:talk" *and* formspec "yl_speak_up:edit_option_dialog" -- when a parameter was changed in edit mode; -- this is called when the player is in edit_mode (editing the NPC); @@ -2085,6 +2101,7 @@ yl_speak_up.edit_mode_apply_changes = function(pname, fields) result["show_next_option"] = future_o_id end + -- changes to options are not possible if there are none if(dialog.n_dialogs[ d_id ].d_options) then @@ -2281,16 +2298,12 @@ minetest.register_on_player_receive_fields( -- the player wants to see the previous option/answer if(fields.edit_option_prev) then - local cmp = 0 + -- sort all options by o_sort + local sorted_list = yl_speak_up.get_sorted_options(n_dialog.d_options) local o_found = o_id - -- lets find out if there is any option with a lower o_sort value - for o,v in pairs(n_dialog.d_options) do - -- find the largest value that is smaller than d_option.o_sort - if(v.o_sort and v.o_sort ~= "" and d_option.o_sort - and tonumber(v.o_sort) < tonumber(d_option.o_sort) - and tonumber(v.o_sort) > cmp) then - cmp = tonumber(v.o_sort) - o_found = o + 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 @@ -2299,16 +2312,12 @@ minetest.register_on_player_receive_fields( -- the player wants to see the next option/answer elseif(fields.edit_option_next) then - local cmp = 10000000 + -- sort all options by o_sort + local sorted_list = yl_speak_up.get_sorted_options(n_dialog.d_options) local o_found = o_id - -- lets find out if there is any option with a larger o_sort value - for o,v in pairs(n_dialog.d_options) do - -- find the lowest value that is larger than d_option.o_sort - if(v.o_sort and v.o_sort ~= "" and d_option.o_sort - and tonumber(v.o_sort) > tonumber(d_option.o_sort) - and tonumber(v.o_sort) < cmp) then - cmp = tonumber(v.o_sort) - o_found = o + 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