diff --git a/functions.lua b/functions.lua index cc5223b..59bb6ab 100644 --- a/functions.lua +++ b/functions.lua @@ -10,23 +10,7 @@ yl_sokomine["q_apple_explorer"] = {} -- chat option: "That was all. I'm finished with giving you new orders. Remember them!" -- -> ends edit mode -- --- TODO: add the actual edit menu for options --- can be entered from the edit, conditions and effects button; --- style: Answer/Option: --- Lets the NPC answer with: [Button GOTO target dialog] --- --- Only offer this answer if all the following conditions are true: --- --- If at least one condition is not fulfilled, .. --- --- --- When this answer has been selected, apply the following effects: --- --- --- [Store] [Delete this option] [Back to dialog xyz] [GOTO target diaglog] --- -- TODO: check if security is ok (minetest.formspec_escape etc) --- TODO: actually store changed entries -- TODO: allow owner to mute/unmute npc (would be bad if players can already see what is going -- to happen while the owner creates a long quest) @@ -879,6 +863,143 @@ local function get_fs_optiondialog(player, n_id, d_id, o_id, p_id, r_id) return table.concat(formspec, "") end + +-- TODO: add buttons for options: [delete] [add] [back to dialog] [prev] [next] +-- TODO: display and allow to edit sort order (o_sort) +-- TODO: actually add functionality for this formspec +-- TODO: make sure the formspec doesn't get closed when there are unsaved modifications +-- +-- edit options (not via staff but via the "I am your owner" dialog) +local function get_fs_edit_option_dialog(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] + + -- are there any preconditions? + local list_of_preconditions = "" + local prereq = d_option.o_prerequisites + if(prereq) then + for k, v in pairs(prereq) do + list_of_preconditions = list_of_preconditions.. + minetest.formspec_escape(v.p_id)..",".. + minetest.formspec_escape(v.p_type)..",".. + minetest.formspec_escape(v.p_value).."," + end + 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 + for k, v in pairs(results) do + 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)..",".. + minetest.formspec_escape(v.r_type)..",".. + minetest.formspec_escape(v.r_value).."," + 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 + + -- offer the correct preselection for hidden/grey/show text + local alternate_answer_option = "3" + if(d_option.o_hide_when_prerequisites_not_met) then + alternate_answer_option = "1" + elseif(d_option.o_grey_when_prerequisites_not_met) then + alternate_answer_option = "2" + 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;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;option_text_met;;".. + 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 effects + "label[0.2,10.6;When this answer has been selected, apply the following (Ef)fects:]".. + -- TODO: perhaps add tooltip for the type of the conditions + "tablecolumns[text;text;text]".. + "table[1.2,11.0;19.6,2.0;table_of_effect;".. + list_of_effects..";0]".. + -- ..and what the NPC will reply to that answer + "label[0.2,13.6;The NPC will react to this answer with the following dialog:]".. + "hypertext[1.2,14.2;19.6,2.5;d_text_next;".. + minetest.formspec_escape(next_text) .. "\n".."]".. + "tooltip[1.2,14.2;19.6,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,13.2;5,0.9;target_dialog;"..dialog_list..";"..dialog_selected..",]".. + "tooltip[14.8,13.2;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]" + return formspec +end + + -- talk local function get_fs_talkdialog(player, n_id, d_id) @@ -1086,8 +1207,8 @@ local function get_fs_talkdialog(player, n_id, d_id) h = h + 1 -- add a button "o_:" that leads to an edit formspec for this option table.insert(formspec, "button[1.8," .. h .. ";2,0.9;edit_option_" .. sb_v.o_id .. ";"..sb_v.o_id..":]") - -- add a tooltip "Edit target dialog, pre(C)onditions and (E)ffects for option o_" - table.insert(formspec, "tooltip[edit_option_" .. sb_v.o_id .. ";Edit target dialog, pre(C)onditions and (E)ffects for option "..sb_v.o_id..".]") + -- add a tooltip "Edit target dialog, pre(C)onditions and (Ef)fects for option o_" + table.insert(formspec, "tooltip[edit_option_" .. sb_v.o_id .. ";Edit target dialog, pre(C)onditions and (Ef)fects for option "..sb_v.o_id..".]") -- find the right target dialog for this option (if it exists): local target_dialog = nil @@ -1110,7 +1231,7 @@ local function get_fs_talkdialog(player, n_id, d_id) -- add a tooltip "Go to target dialog d_" table.insert(formspec, "tooltip[button_" .. sb_v.o_id .. ";Go to target dialog "..target_dialog.." that will be shown when this option ("..sb_v.o_id..") is selected.]") - -- selecting an option this way MUST NOT execute the pre(C)onditions or (E)ffects! + -- selecting an option this way MUST NOT execute the pre(C)onditions or (Ef)fects! end -- allow to set a new target dialog table.insert(formspec, "dropdown[3.9,"..h..";4.7,1;d_id_"..sb_v.o_id..";"..dialog_list..";"..(d_id_to_dropdown_index[target_dialog] or "0")..",]") @@ -1126,8 +1247,8 @@ local function get_fs_talkdialog(player, n_id, d_id) end if(has_other_results) then table.insert(formspec, "button[1.1," .. h .. ";0.6,0.9;effects_"..sb_v.o_id..";Ef]") - -- label: "There are further (E)ffects (apart from switching to a new dialog) set for this option. Display them." - table.insert(formspec, "tooltip[effects_" .. sb_v.o_id .. ";There are further (E)ffects (apart from switching to a new dialog) set for this option. Display them.]") + -- label: "There are further (Ef)fects (apart from switching to a new dialog) set for this option. Display them." + table.insert(formspec, "tooltip[effects_" .. sb_v.o_id .. ";There are further (Ef)fects (apart from switching to a new dialog) set for this option. Display them.]") end -- show the actual text for the option @@ -2035,6 +2156,24 @@ minetest.register_on_player_receive_fields( local dialog = yl_speak_up.speak_to[pname].dialog + + -- 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] + + 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["effects_"..o_id]) then + minetest.show_formspec(pname, "yl_speak_up:edit_option_dialog", get_fs_edit_option_dialog(player, yl_speak_up.speak_to[pname].n_id, d_id, o_id)) + return + end + end + end + + end + -- in edit mode: another dialog was selected if ( o == "" and edit_mode) then -- if nothing better can be found: keep the old dialog