diff --git a/editor/api/api_alternate_text.lua b/editor/api/api_alternate_text.lua deleted file mode 100644 index be6b321..0000000 --- a/editor/api/api_alternate_text.lua +++ /dev/null @@ -1,434 +0,0 @@ --- helper function for yl_speak_up.handle_input_fs_edit_option_related --- (handle editing of alternate texts that are shown instead of the normal dialog) -yl_speak_up.handle_edit_actions_alternate_text = function( - player, pname, n_id, d_id, o_id, x_id, id_prefix, - formspec_input_to, data, fields, tmp_data_cache) - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(dialog) - or not(dialog.n_dialogs) - or not(dialog.n_dialogs[ d_id ]) - or not(dialog.n_dialogs[ d_id ].d_options) - or not(dialog.n_dialogs[ d_id ].d_options[ o_id ])) then - return - end - -- edit_dialog_options: these first two buttons can only be pressed in this dialog - -- action failed: want to edit the text that is shown when switching to the next dialog? - if(fields.button_edit_action_failed_dialog) then - -- the target effect is the (failed) action - local target_action = {} - local actions = dialog.n_dialogs[ d_id ].d_options[ o_id ].actions - if(actions) then - for a_id, a in pairs(actions) do - if(a and a.a_id) then - target_action = a - end - end - end - if(not(target_action)) then - return - end - -- remember what we're working at - yl_speak_up.speak_to[pname].edit_alternate_text_for = target_action - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.extend_fs_edit_dialog_modification( - dialog, target_action.a_on_failure, target_action.alternate_text, - "if the action \""..tostring(target_action.a_id).. - "\" of option \""..tostring(o_id).. - "\" of dialog \""..tostring(d_id).. - "\" failed because the player did something wrong") - }) - -- showing new formspec - the calling function shall return as well - return true - - -- action was successful: want to edit the text that is shown when switching to the next dialog? - elseif(fields.button_edit_action_success_dialog) then - -- the target effect is the "dialog" effect - local target_effect = {} - local results = dialog.n_dialogs[ d_id ].d_options[ o_id ].o_results - if(results) then - for r_id, r in pairs(results) do - if(r and r.r_type and r.r_type == "dialog") then - target_effect = r - end - end - end - if(not(target_effect)) then - return - end - -- remember what we're working at - yl_speak_up.speak_to[pname].edit_alternate_text_for = target_effect - -- this only happens in edit_options_dialog; log it directly - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.extend_fs_edit_dialog_modification( - dialog, target_effect.r_value, target_effect.alternate_text, - "if the action ".. - "of option \""..tostring(o_id).. - "\" of dialog \""..tostring(d_id).. - "\" was successful - or if there was no action") - }) - -- showing new formspec - the calling function shall return as well - return true - - -- in edit action dialog: edit alternate text for a failed action - elseif(fields.button_edit_action_on_failure_text_change) then - local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs) - local failure_id = "" - -- action is beeing edited; data.action_failure_dialog points to an index - if(data and data.action_failure_dialog) then - failure_id = sorted_dialog_list[ data.action_failure_dialog ] - end - -- remember what we edit - data.x_id = x_id - data.id_prefix = id_prefix - yl_speak_up.speak_to[pname].edit_alternate_text_for = data - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.extend_fs_edit_dialog_modification( - dialog, failure_id, data.alternate_text, - "if the action \""..tostring(x_id).. - "\" of option \""..tostring(o_id).. - "\" of dialog \""..tostring(d_id).. - "\" failed because the player did something wrong") - }) - -- showing new formspec - the calling function shall return as well - return true - - -- edit alternate text for an on_failure effect - elseif(fields.button_edit_effect_on_failure_text_change) then - -- remember what we edit - data.x_id = x_id - data.id_prefix = id_prefix - yl_speak_up.speak_to[pname].edit_alternate_text_for = data - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.extend_fs_edit_dialog_modification( - dialog, data.on_failure, data.alternate_text, - "if the effect \""..tostring(x_id).. - "\" of option \""..tostring(o_id).. - "\" of dialog \""..tostring(d_id).. - "\" failed to execute correctly") - }) - -- showing new formspec - the calling function shall return as well - return true - - -- edit alternate text for when the player has failed to do the action too many times - elseif(fields.button_edit_limit_action_failed_repeat) then - local timer_name = "timer_on_failure_"..tostring(d_id).."_"..tostring(o_id) - local timer_data = yl_speak_up.get_variable_metadata( timer_name, "parameter", true) - local alternate_text = yl_speak_up.standard_text_if_action_failed_too_often - if(timer_data and timer_data["alternate_text"]) then - alternate_text = timer_data["alternate_text"] - end - -- remember what we're working at - yl_speak_up.speak_to[pname].edit_alternate_text_for = "timer_on_failure" - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.extend_fs_edit_dialog_modification( - dialog, d_id, alternate_text, - "if the player failed to complete the action ".. - "\" of option \""..tostring(o_id).. - "\" of dialog \""..tostring(d_id).. - "\" too many times", - true) -- forbid_turn_into_new_dialog - }) - -- showing new formspec - the calling function shall return as well - return true - -- edit alternate text whent he player has to wait a bit until he's allowed to repeat the - -- action (to avoid i.e. unlimited quest item handout) - elseif(fields.button_edit_limit_action_success_repeat) then - local timer_name = "timer_on_success_"..tostring(d_id).."_"..tostring(o_id) - local timer_data = yl_speak_up.get_variable_metadata( timer_name, "parameter", true) - local alternate_text = yl_speak_up.standard_text_if_action_repeated_too_soon - if(timer_data and timer_data["alternate_text"]) then - alternate_text = timer_data["alternate_text"] - end - -- remember what we're working at - yl_speak_up.speak_to[pname].edit_alternate_text_for = "timer_on_success" - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.extend_fs_edit_dialog_modification( - dialog, d_id, alternate_text, - "if the player has complete the action ".. - "\" of option \""..tostring(o_id).. - "\" of dialog \""..tostring(d_id).. - "\" just not long enough ago", - true) -- forbid_turn_into_new_dialog - }) - -- showing new formspec - the calling function shall return as well - return true - - -- save the changes - elseif(fields.save_dialog_modification) then - local old_text = "-none-" - local target_element = yl_speak_up.speak_to[pname].edit_alternate_text_for - if(target_element - and (target_element == "timer_on_failure" or target_element == "timer_on_success")) then - -- we're changing a timer (both can be handled the same way here) - local timer_name = target_element.."_"..tostring(d_id).."_"..tostring(o_id) - local timer_data = yl_speak_up.get_variable_metadata( timer_name, "parameter", true) - local alternate_text = yl_speak_up.standard_text_if_action_failed_too_often - if(target_element == "timer_on_success") then - alternate_text = yl_speak_up.standard_text_if_action_repeated_too_soon - end - if(timer_data and timer_data["alternate_text"]) then - alternate_text = timer_data["alternate_text"] - end - -- store the modified alternate text - if(fields.d_text_new and fields.d_text_new ~= "" - and fields.d_text_new ~= alternate_text) then - -- make sure the variable exists - if(yl_speak_up.add_time_based_variable(timer_name)) then - yl_speak_up.set_variable_metadata(timer_name, nil, "parameter", - "alternate_text", fields.d_text_new) - -- log the change - yl_speak_up.log_change(pname, n_id, - "Dialog "..d_id..", option "..tostring(o_id).. - ": The text displayed for "..tostring(target_element).. - " was changed from ".. - "["..tostring(alternate_text).."] to [".. - tostring(fields.d_text_new).."].") - end - end - elseif(target_element) then - data = target_element - id_prefix = "a_" - if(target_element.r_id) then - id_prefix = "r_" - end - old_text = target_element.alternate_text - else - old_text = data.alternate_text - end - if(data and fields.d_text_new and fields.d_text_new ~= "$TEXT$" - and fields.d_text_new ~= data.alternate_text) then - -- store modification - -- not necessary for edit_option_dialog - if(tmp_data_cache) then - data.alternate_text = fields.d_text_new - yl_speak_up.speak_to[pname][ tmp_data_cache ] = data - else - target_element.alternate_text = fields.d_text_new - end - if(id_prefix == "r_") then - local failure_id = data.on_failure - -- effect is beeing edited; data.on_failure contains the dialog name - if(data and data.on_failure) then - failure_id = data.on_failure - -- edit_option_dialog: data.r_value contains the dialog name - elseif(target_element and target_element.r_value) then - failure_id = target_element.r_value - end - -- record the change - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The text displayed for dialog ".. - tostring(failure_id).." when selecting option ".. - tostring(o_id).." in dialog "..tostring( d_id ).. - " and effect "..tostring(x_id).." failed ".. - " was changed from ".. - "["..tostring(old_text).."] to ["..tostring(fields.d_text_new).."].") - elseif(id_prefix == "a_") then - local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs) - local failure_id = "" - -- action is beeing edited; data.action_failure_dialog points to an index - if(data and data.action_failure_dialog) then - failure_id = sorted_dialog_list[ data.action_failure_dialog ] - -- edit_option_dialog: data.a_on_failure contains the dialog name - elseif(target_element and target_element.a_on_failure) then - failure_id = target_element.a_on_failure - end - -- record the change - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The text displayed for dialog ".. - tostring(failure_id).." when the action ".. - tostring(x_id).." of option ".. - tostring( o_id ).." in dialog "..tostring( d_id ).. - " failed, was changed from ".. - "["..tostring(old_text).."] to ["..tostring(fields.d_text_new).."].") - end - -- saved; finished editing - yl_speak_up.speak_to[pname].edit_alternate_text_for = nil - end - -- turn this alternate answer into a new dialog - elseif(fields.turn_alternate_text_into_new_dialog) then - local target_element = yl_speak_up.speak_to[pname].edit_alternate_text_for - if(target_element) then - data = target_element - if(data.id_prefix and data.x_id) then - id_prefix = data.id_prefix - x_id = data.x_id - else - id_prefix = "a_" - x_id = target_element.a_id - if(target_element.r_id) then - id_prefix = "r_" - x_id = target_element.r_id - end - end - end - -- create the new dialog - local new_dialog_id = yl_speak_up.add_new_dialog(dialog, pname, nil) - -- set the text (the previous alternate text) - dialog.n_dialogs[ new_dialog_id ].d_text = data.alternate_text - -- edit option: effect dialog - this is the normal progression from this dialog to the next - if( data.r_id and data.r_type and data.r_type == "dialog") then - data.r_value = new_dialog_id - data.alternate_text = nil - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The alternate text for effect "..tostring(x_id).. - " (dialog) of option "..tostring(o_id).." was turned into the new dialog ".. - tostring(new_dialog_id).." (edit option).") - - -- edit option: the action failed - elseif(data.a_id and data.a_on_failure) then - data.a_on_failure = new_dialog_id - data.alternate_text = nil - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The alternate text for action "..tostring(data.a_id).. - " of option "..tostring(o_id).." was turned into the new dialog ".. - tostring(new_dialog_id).." (edit option).") - - -- edit action: the action failed - elseif(data.what and data.what == 6 and data.action_failure_dialog) then - local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs) - data.action_failure_dialog = math.max(1, - table.indexof(sorted_dialog_list, new_dialog_id)) - data.a_on_failure = new_dialog_id - data.alternate_text = nil - -- make sure its stored correctly - dialog.n_dialogs[d_id].d_options[o_id].actions[x_id].a_on_failure = new_dialog_id - dialog.n_dialogs[d_id].d_options[o_id].actions[x_id].alternate_text = nil - yl_speak_up.speak_to[pname][ tmp_data_cache ] = data - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The alternate text for action "..tostring(x_id).. - " of option "..tostring(o_id).." was turned into the new dialog ".. - tostring(new_dialog_id).." (edit action).") - - -- edit effect: on_failure - the previous effect failed - elseif(data.what and data.what == 5 and data.on_failure) then - data.on_failure = new_dialog_id - data.alternate_text = nil - -- make sure its stored correctly - dialog.n_dialogs[d_id].d_options[o_id].o_results[x_id].on_failure = new_dialog_id - dialog.n_dialogs[d_id].d_options[o_id].o_results[x_id].alternate_text = nil - yl_speak_up.speak_to[pname][ tmp_data_cache ] = data - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The alternate text for effect "..tostring(x_id).. - " of option "..tostring(o_id).." was turned into the new dialog ".. - tostring(new_dialog_id).." (edit effect).") - end - end -end - - -yl_speak_up.show_colored_dialog_text = function(dialog, data, d_id, hypertext_pos, - alternate_label_text, postfix, button_name) - if(not(data)) then - return "" - end - -- if(math.random(1,2)==1) then data.alternate_text = "This is an alternate text.\n$TEXT$" end - -- slightly red in order to indicate that this is an on_failure dialog - local color = "776666" - -- ..except for normal redirecting to the next dialog with the dialog effect - -- (slightly yellow there) - if(data.r_id and data.r_type and data.r_type == "dialog") then - color = "777766" - end - local add_info_alternate_text = "" - local text = "" - if(dialog and dialog.n_dialogs and dialog.n_dialogs[ d_id ]) then - text = dialog.n_dialogs[ d_id ].d_text - end - if(d_id == "d_got_item") then - color = "777777" - text = "[This dialog shall only have automatic options. The text is therefore irrelevant.]" - end - if(d_id == "d_end") then - color = "777777" - text = "[The NPC will end this conversation.]" - end - if(not(text)) then - text = "[ERROR: No text!]" - end - if(data and data.alternate_text and data.alternate_text ~= "") then - add_info_alternate_text = alternate_label_text - -- replace $TEXT$ with the normal dialog text and make the new text yellow - text = "").. - "" - -- slightly blue in order to indicate that this is a modified text - color = "333366" - end - -- fallback - if(not(text)) then - text = "ERROR: No dialog text found for dialog \""..tostring(d_id).."\"!" - end - -- display the variables in orange - text = yl_speak_up.replace_vars_in_text(text, - -- fake dialog; just adds the colors - -- also MY_NAME..but we can easily replace just one - { n_npc = "", - npc_owner = ""}, - -- pname - "") - - local edit_button = "" - -- if there is the possibility that an alternate text may be displayed: allow to edit it - -- and calculate the position of the button from the hypertext_pos position and size - if(button_name and button_name ~= "") then - local parts = string.split(hypertext_pos, ";") - local start = string.split(parts[1], ",") - local size = string.split(parts[2], ",") - edit_button = "button_exit[".. - tostring(tonumber(start[1]) + tonumber(size[1]) - 3.5)..",".. - tostring(tonumber(start[2]) + tonumber(size[2]) - 0.9)..";".. - "3.0,0.7;"..button_name..";Edit this text]" - end - return add_info_alternate_text.. - postfix.. - "hypertext["..hypertext_pos..";".. - minetest.formspec_escape(text or "?").. - "\n]".. - -- display the edit button *inside*/on top of the hypertext field - edit_button -end - --- this allows to edit modifications of a dialog that are applied when a given option --- is choosen - i.e. when the NPC wants to answer some questions - but those answers --- do not warrant their own dialog -yl_speak_up.extend_fs_edit_dialog_modification = function(dialog, d_id, alternate_dialog_text, explanation, - forbid_turn_into_new_dialog) - - local nd = "button[9.0,12.3;6,0.7;turn_alternate_text_into_new_dialog;Turn this into a new dialog]" - if(forbid_turn_into_new_dialog) then - nd = "" - end - return table.concat({"size[20,13.5]", - "label[6.0,0.5;Edit alternate text]", - "label[0.2,1.0;The alternate text which you can edit here will be shown instead of ".. - "the normal text of the dialog \"", tostring(d_id), "\" - but *only*\n", - tostring(explanation or "- missing explanation -"), ".]", - "label[0.2,2.3;This is the normal text of dialog \"", - minetest.formspec_escape(tostring(d_id)), "\", shown for reference:]", - yl_speak_up.show_colored_dialog_text( - dialog, - {r_id = "", r_type = "dialog"}, - d_id, - "1.2,2.6;18.0,4.0;d_text_orig", - "", -- no modifications possible at this step - "", - ""), -- no edit button here as this text cannot be changed here - "label[0.2,7.3;Enter the alternate text here. $TEXT$ will be replaced with the normal ".. - "dialog text above:]", - "textarea[1.2,7.6;18.0,4.5;d_text_new;;", - minetest.formspec_escape(alternate_dialog_text or "$TEXT$"), "]", - "button[3.0,12.3;1,0.7;back_from_edit_dialog_modification;Abort]", - "button[6.0,12.3;1,0.7;save_dialog_modification;Save]", - nd - }, "") -end - diff --git a/editor/api/api_quest_steps.lua b/editor/api/api_quest_steps.lua deleted file mode 100644 index 4290725..0000000 --- a/editor/api/api_quest_steps.lua +++ /dev/null @@ -1,270 +0,0 @@ - --- returns a table with helpful information *if* the player is working on a quest; --- else error_msg is set -yl_speak_up.player_is_working_on_quest = function(player) - if(not(player)) then - return - end - local t = {} - t.pname = player:get_player_name() - if(not(t.pname)) then - return {error_msg = "Player not found."} - end - if(not(yl_speak_up.speak_to or not(yl_speak_up.speak_to[t.pname]))) then - return {error_msg = "Player not working on a quest."} - end - t.q_id = yl_speak_up.speak_to[t.pname].q_id - if(not(t.q_id) or not(yl_speak_up.quests) or not(yl_speak_up.quests[t.q_id])) then - return {error_msg = "No quest selected or quest not found."} - end - t.quest = yl_speak_up.quests[t.q_id] - if(not(t.quest.step_data) or type(t.quest.step_data) ~= "table") then - yl_speak_up.quests[t.q_id].step_data = {} - end - -- TODO: check if the player has access to that data - t.step_data = yl_speak_up.quests[t.q_id].step_data - t.current_step = yl_speak_up.speak_to[t.pname].quest_step - -- check here if the step exists - if(t.current_step and not(t.step_data[t.current_step])) then - yl_speak_up.speak_to[t.pname].quest_step = nil - t.current_step = nil - end - -- t contains pname, q_id, quest, step_data and current_step - or error_msg - return t -end - - --- show the error message created above -yl_speak_up.build_fs_quest_edit_error = function(error_msg, back_button_name) - return "size[10,3]".. - "label[0.2,0.5;Error:]".. - "label[0.5,1.0;"..minetest.colorize("#FFFF00", - minetest.formspec_escape( - minetest.wrap_text(tostring(error_msg), 80))).. - "]button[3.5,2.0;2,0.9;"..tostring(back_button_name)..";Back]" -end - - --- for which other quest steps is this_step needed for? -yl_speak_up.quest_step_required_for = function(step_data, this_step) - -- find out the next quest step - local required_for = {} - for s, d in pairs(step_data) do - if(s and d and d.one_step_required and type(d.one_step_required) == "table" - and table.indexof(d.one_step_required, this_step) ~= -1) then - table.insert(required_for, s) - end - if(s and d and d.all_steps_required and type(d.all_steps_required) == "table" - and table.indexof(d.all_steps_required, this_step) ~= -1) then - table.insert(required_for, s) - end - end - table.sort(required_for) - return required_for -end - - --- sorts quest steps into lists: start, middle, end, unconnected -yl_speak_up.quest_step_get_start_end_unconnected_lists = function(step_data) - local start_steps = {} - local end_steps = {} - local unconnected_steps = {} - -- construct tables of *candidates* for start/end steps first - for s, d in pairs(step_data) do - if(#d.one_step_required == 0 and #d.all_steps_required == 0) then - start_steps[s] = true - end - end_steps[s] = true - end - for s, d in pairs(step_data) do - -- anything that is required somewhere cannot be an end step - for i, s2 in ipairs(d.one_step_required or {}) do - end_steps[s2] = nil - end - for i, s2 in ipairs(d.all_steps_required or {}) do - end_steps[s2] = nil - end - end - local lists = {} - lists.start_steps = {} - lists.end_steps = {} - lists.unconnected_steps = {} - lists.middle_steps = {} - for s, d in pairs(step_data) do - -- if it's both a start and end step, then it's an unconnected step - if(start_steps[s] and end_steps[s]) then - table.insert(lists.unconnected_steps, s) - elseif(start_steps[s]) then - table.insert(lists.start_steps, s) - elseif(end_steps[s]) then - table.insert(lists.end_steps, s) - else - table.insert(lists.middle_steps, s) - end - end - return lists -end - - --- some lists are offered in diffrent formspecs for selection; --- this function will display the right quest step if possible --- res needs to be yl_speak_up.player_is_working_on_quest(player) -yl_speak_up.handle_input_routing_show_a_quest_step = function(player, formname, fields, back_field_name, res) - if(not(player) or not(fields) or (fields and fields.back) or not(res)) then - return false - end - - if(res.error_msg) then - yl_speak_up.show_fs(player, "msg", { - input_to = formname, - formspec = yl_speak_up.build_fs_quest_edit_error(error_msg, back_field_name) - }) - return true - end - local step_data = res.step_data or {} - - -- which quest step to show next? (if any) - local show_step = "" - -- was a quest step selected from the start/end/unconnected lists? - local list = {} - local field_name = "" - local row_offset = 0 - if( fields.select_from_start_steps and fields.select_from_start_steps ~= "") then - -- selected a start quest step - list = yl_speak_up.quest_step_get_start_end_unconnected_lists(step_data).start_steps - field_name = "select_from_start_steps" - elseif(fields.select_from_end_steps and fields.select_from_end_steps ~= "") then - -- selected an end quest step - list = yl_speak_up.quest_step_get_start_end_unconnected_lists(step_data).end_steps - field_name = "select_from_end_steps" - elseif(fields.select_from_unconnected_steps and fields.select_from_unconnected_steps ~= "") then - -- selected an unconnected/unused quest step - list = yl_speak_up.quest_step_get_start_end_unconnected_lists(step_data).unconnected_steps - field_name = "select_from_unconnected_steps" - elseif(res.current_step and step_data[res.current_step] and fields.one_step_required) then - list = step_data[res.current_step].one_step_required - field_name = "one_step_required" - elseif(res.current_step and step_data[res.current_step] and fields.all_steps_required) then - list = step_data[res.current_step].all_steps_required - field_name = "all_steps_required" - elseif(res.current_step and step_data[res.current_step] and fields.next_steps_show) then - list = yl_speak_up.quest_step_required_for(step_data, res.current_step) - field_name = "next_steps_show" - elseif(fields.add_from_available) then - -- selected a quest step from the list of available steps offered - list = yl_speak_up.speak_to[res.pname].available_quest_steps or {} - field_name = "add_from_available" - -- this table has a header - row_offset = 1 - - -- show prev logical step - elseif(fields.show_prev_step and res.current_step and step_data[res.current_step]) then - if( #step_data[res.current_step].one_step_required > 0) then - show_step = step_data[res.current_step].one_step_required[1] - elseif(#step_data[res.current_step].all_steps_required > 0) then - show_step = step_data[res.current_step].all_steps_required[1] - end - -- show next logical step - elseif(fields.show_next_step) then - local list = yl_speak_up.quest_step_required_for(res.step_data, res.current_step) - if(list and #list > 0) then - show_step = list[1] - end - end - - if(list and field_name) then - local selected = minetest.explode_table_event(fields[field_name]) - -- if a table uses a header, row_offset will be 1; else 0 - if(selected and selected.row and selected.row > row_offset and selected.row <= #list + row_offset) then - show_step = list[selected.row - row_offset] - end - end - -- actually show the selected quest step - if(show_step and show_step ~= "") then - yl_speak_up.speak_to[res.pname].quest_step = show_step - yl_speak_up.show_fs(player, "manage_quest_steps", show_step) - return true - -- show the entire list - elseif(fields.show_step_list) then - yl_speak_up.speak_to[res.pname].tmp_index_general = -1 - yl_speak_up.speak_to[res.pname].quest_step = nil - yl_speak_up.show_fs(player, "manage_quest_steps", nil) - return true - end - return false -end - - --- describe a location where a quest step can be set; also used by yl_speak_up.fs_manage_quest_steps -yl_speak_up.quest_step_show_where_set = function(pname, formspec, label, n_id, d_id, o_id, box_color, nr) - if(not(pname)) then - return - end - -- what are we talking about? - local dialog = nil - if(yl_speak_up.speak_to[pname] and yl_speak_up.speak_to[pname].n_id == n_id) then - dialog = yl_speak_up.speak_to[pname].dialog - else - dialog = yl_speak_up.load_dialog(n_id, false) - end - local name_txt = "- ? -" - local dialog_txt = "- ? -" - local option_txt = "- ? -" - if(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id)) then - dialog_txt = dialog.n_dialogs[d_id].d_text or "- ? -" - option_txt = dialog.n_dialogs[d_id].d_options[o_id].o_text_when_prerequisites_met or "- ? -" - name_txt = (dialog.n_npc or "- ? -") - if(dialog.n_description and dialog.n_description ~= "") then - name_txt = name_txt..", "..tostring(dialog.n_description) - end - end - -- are we dealing with an NPC? - local id_label = "the block at position " - if(n_id and string.sub(n_id, 1, 2) == "n_") then - id_label = "NPC " - end - - if(box_color) then - name_txt = name_txt.." ["..tostring(n_id).."]" - table.insert(formspec, "label[0.2,0.2;") - if(nr) then - table.insert(formspec, tostring(nr)..". ") - end - table.insert(formspec, id_label) - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(name_txt))) - table.insert(formspec, " says in dialog ") - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(d_id)..":]")) - table.insert(formspec, "]") - table.insert(formspec, "box[1.0,0.4;16,1.8;") - table.insert(formspec, box_color) - table.insert(formspec, "]") - table.insert(formspec, "textarea[1.0,0.4;16,1.8;;;") - table.insert(formspec, minetest.formspec_escape(dialog_txt)) - table.insert(formspec, "]") - table.insert(formspec, "label[1.0,2.4;Answer ") - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(o_id..": "))) - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(option_txt))) - table.insert(formspec, "]") - return - end - table.insert(formspec, "label[0.2,0;") - table.insert(formspec, label or "which will be set by ") - table.insert(formspec, id_label) - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(n_id))) - table.insert(formspec, ":]") - table.insert(formspec, "label[1.0,0.4;") - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(name_txt))) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,0.9;when answering to dialog ") - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(d_id))) - table.insert(formspec, ":]") - table.insert(formspec, "textarea[1.0,1.1;16,1.8;;;") - table.insert(formspec, minetest.formspec_escape(dialog_txt)) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,3.2;with the following answer/option ") - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(o_id))) - table.insert(formspec, ":]") - table.insert(formspec, "label[1.0,3.6;") - table.insert(formspec, minetest.colorize("#AAAAFF", minetest.formspec_escape(option_txt))) - table.insert(formspec, "]") -end diff --git a/editor/api/formspec_helpers.lua b/editor/api/formspec_helpers.lua deleted file mode 100644 index c659645..0000000 --- a/editor/api/formspec_helpers.lua +++ /dev/null @@ -1,318 +0,0 @@ - --- helper function: --- create a formspec dropdown list with player names (first entry: Add player) and --- an option to delete players from that list --- Note: With the what_is_the_list_about-parameter, it is possible to handle i.e. variables as well -yl_speak_up.create_dropdown_playerlist = function(player, pname, - table_of_names, index_selected, - start_x, start_y, stretch_x, h, dropdown_name, what_is_the_list_about, delete_button_text, - field_name_for_adding_player, explain_add_player, - field_name_for_deleting_player, explain_delete_player) - - local text = "dropdown["..tostring(start_x)..","..tostring(start_y)..";".. - tostring(3.8 + stretch_x)..","..tostring(h)..";".. - tostring(dropdown_name)..";Add "..tostring(what_is_the_list_about)..":" - -- table_of_names is a table with the playernames as keys - -- we want to work with indices later on; in order to be able to do that reliably, we - -- need a defined order of names - local tmp_list = yl_speak_up.sort_keys(table_of_names, true) - for i, p in ipairs(tmp_list) do - text = text..","..minetest.formspec_escape(p) - end - -- has an entry been selected? - if(not(index_selected) or index_selected < 0 or index_selected > #tmp_list+1) then - index_selected = 1 - end - text = text..";"..tostring(index_selected)..";]" - if(index_selected == 1) then - -- first index "Add player" selected? Then offer a field for entering the name - text = text.."field["..tostring(start_x + 4.0 + stretch_x)..","..tostring(start_y).. - ";"..tostring(3.5 + stretch_x)..","..tostring(h)..";".. - tostring(field_name_for_adding_player)..";;]".. - "tooltip["..tostring(field_name_for_adding_player)..";".. - tostring(explain_add_player).."]" - else - text = text.."button["..tostring(start_x + 3.8 + stretch_x)..","..tostring(start_y).. - ";"..tostring(3.4 + stretch_x)..","..tostring(h)..";".. - tostring(field_name_for_deleting_player)..";".. - tostring(delete_button_text).."]".. - "tooltip["..tostring(field_name_for_deleting_player)..";".. - tostring(explain_delete_player).."]" - end - return text -end - - - --- manages back, exit, prev, next, add_list_entry, del_entry_general --- --- if a new entry is to be added, the following function that is passed as a parmeter --- is called: --- function_add_new_entry(pname, fields.add_entry_general) --- expected return value: index of fields.add_entry_general in the new list --- --- if an entry is to be deleted, the following function that is passed as a parameter --- is called: --- function_del_old_entry(pname, entry_name) --- expected return value: text describing weather the removal worked or not --- --- if any other fields are set that this function does not process, the following --- function that is passed on as a parameter can be used: --- function_input_check_fields(player, formname, fields, entry_name, list_of_entries) --- expected return value: nil if the function found work; else entry_name --- -yl_speak_up.handle_input_fs_manage_general = function(player, formname, fields, - what_is_the_list_about, min_length, max_length, function_add_new_entry, - list_of_entries, function_del_old_entry, function_input_check_fields) - local pname = player:get_player_name() - local what = minetest.formspec_escape(what_is_the_list_about or "?") - local fs_name = formname - if(formname and string.sub(formname, 0, 12) == "yl_speak_up:") then - formname = string.sub(formname, 13) - end - if(fields and fields.back_from_msg) then - yl_speak_up.show_fs(player, formname, fields.stored_value_for_player) - return - end - -- leave this formspec - if(fields and (fields.quit or fields.exit or fields.back)) then - local last_fs = yl_speak_up.speak_to[pname][ "working_at" ] - local last_params = yl_speak_up.speak_to[pname][ "working_at_params" ] - yl_speak_up.speak_to[pname].tmp_index_general = nil - yl_speak_up.show_fs(player, last_fs, last_params) - return - -- add a new entry? - elseif(fields and fields.add_list_entry) then - local error_msg = "" - if(not(fields.add_entry_general) or fields.add_entry_general == "" - or fields.add_entry_general:trim() == "") then - error_msg = "Please enter the name of the "..what.." you want to create!" - -- limit names to something more sensible - elseif(string.len(fields.add_entry_general) > max_length) then - error_msg = "The name of your new "..what.." is too long.\n".. - "Only up to "..tostring(max_length).." characters are allowed." - elseif(string.len(fields.add_entry_general:trim()) < min_length) then - error_msg = "The name of your new "..what.." is too short.\n".. - "It has to be at least "..tostring(min_length).." characters long." - elseif(table.indexof(list_of_entries, fields.add_entry_general:trim()) > 0) then - error_msg = "A "..what.." with the name\n \"".. - minetest.formspec_escape(fields.add_entry_general:trim()).. - "\"\nexists already." - else - fields.add_entry_general = fields.add_entry_general:trim() - -- this depends on what is created - local res = function_add_new_entry(pname, fields.add_entry_general) - -- not really an error msg here - but fascilitates output - error_msg = "A new "..what.." named\n \"".. - minetest.formspec_escape(fields.add_entry_general).. - "\"\nhas been created." - if(not(res) or (type(res) == "number" and res == -1)) then - error_msg = "Failed to create "..what.." named\n \"".. - minetest.formspec_escape(fields.add_entry_general).."\"." - -- pass on any error messages - elseif(type(res) == "string") then - error_msg = res - else - -- select this new entry (add 1 because the first entry of our - -- list is adding a new entry) - yl_speak_up.speak_to[pname].tmp_index_general = res + 1 - end - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formname, - formspec = "size[10,2]".. - "label[0.2,0.0;"..error_msg.."]".. - "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) - return - -- scroll through the variables with prev/next buttons - elseif(fields and (fields["prev"] or fields["next"])) then - local index = yl_speak_up.speak_to[pname].tmp_index_general - if(not(index)) then - yl_speak_up.speak_to[pname].tmp_index_general = 1 - elseif(fields["prev"] and index > 1) then - yl_speak_up.speak_to[pname].tmp_index_general = index - 1 - elseif(fields["next"] and index <= #list_of_entries) then - yl_speak_up.speak_to[pname].tmp_index_general = index + 1 - end - yl_speak_up.show_fs(player, formname, fields.stored_value_for_player) - return - end - - -- an entry was selected in the dropdown list - if(fields and fields.list_of_entries and fields.list_of_entries ~= "") then - local index = table.indexof(list_of_entries, fields.list_of_entries) - -- show the "Add :" entry - if(fields.list_of_entries == "Add "..what..":") then - index = 0 - yl_speak_up.speak_to[pname].tmp_index_general = 1 - yl_speak_up.show_fs(player, formname, fields.stored_value_for_player) - return - end - if(index and index > -1) then - yl_speak_up.speak_to[pname].tmp_index_general = index + 1 - end - end - local entry_name = list_of_entries[ yl_speak_up.speak_to[pname].tmp_index_general - 1] - - -- delete entry - if(fields and ((fields.del_entry_general and fields.del_entry_general ~= "")) - and entry_name and entry_name ~= "") then - local text = function_del_old_entry(pname, entry_name) - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formname, - formspec = "size[10,2]".. - "label[0.2,0.0;Trying to delete "..what.." \"".. - minetest.formspec_escape(tostring(entry_name)).. - "\":\n"..text.."]".. - "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) - return - - -- maybe the custom function knows what to do with this - elseif(fields - and not(function_input_check_fields(player, formname, fields, entry_name, list_of_entries))) then - -- the function_input_check_fields managed to handle this input - return - - -- an entry was selected in the dropdown list - elseif(entry_name and entry_name ~= "") then - -- show the same formspec again, with a diffrent variable selected - yl_speak_up.show_fs(player, formname) - return - end - -- try to go back to the last formspec shown before this one - if(not(yl_speak_up.speak_to[pname])) then - return - end - local last_fs = yl_speak_up.speak_to[pname][ "working_at" ] - local last_params = yl_speak_up.speak_to[pname][ "working_at_params" ] - yl_speak_up.show_fs(player, last_fs, last_params) -end - - --- inserts buttons into formspec which allow to select previous/next entry, to go back, --- create new entries, delete entries and select entries from a dropdown menu; --- returns the currently selected entry or nil (=create new entry) --- Note: Designed for a formspec of size "size[18,12]" -yl_speak_up.build_fs_manage_general = function(player, param, - formspec, list_of_entries, - text_add_new, tooltip_add_new, - what_is_the_list_about, - tooltip_add_entry_general, tooltip_del_entry_general, - optional_add_space) - if(not(optional_add_space)) then - optional_add_space = 0 - end - local selected = nil - local pname = player:get_player_name() - -- the yl_speak_up.create_dropdown_playerlist function needs a table - not a list - local table_of_entries = {} - for i, k in ipairs(list_of_entries) do - table_of_entries[ k ] = true - end - -- "Add variable:" is currently selected - if(not(yl_speak_up.speak_to[pname].tmp_index_general) - or yl_speak_up.speak_to[pname].tmp_index_general == 1 - or not(list_of_entries[ yl_speak_up.speak_to[pname].tmp_index_general - 1])) then - yl_speak_up.speak_to[pname].tmp_index_general = 1 - table.insert(formspec, "button[") - table.insert(formspec, tostring(12.2 + 2 * optional_add_space)) - table.insert(formspec, ",2.15;") - table.insert(formspec, tostring(2.5 + 2 * optional_add_space)) - table.insert(formspec, ",0.6;add_list_entry;") - table.insert(formspec, minetest.formspec_escape(text_add_new)) - table.insert(formspec, "]") - table.insert(formspec, "tooltip[add_list_entry;") - table.insert(formspec, minetest.formspec_escape(tooltip_add_new)) - table.insert(formspec, "]") - else - -- index 1 is "Add variable:" - selected = list_of_entries[ yl_speak_up.speak_to[pname].tmp_index_general - 1] - end - if(yl_speak_up.speak_to[pname].tmp_index_general > 1) then - table.insert(formspec, "button[4.0,0.2;2.0,0.6;prev;< Prev]".. - "button[4.0,11.0;2.0,0.6;prev;< Prev]") - end - if(yl_speak_up.speak_to[pname].tmp_index_general <= #list_of_entries) then - table.insert(formspec, "button[12.0,0.2;2.0,0.6;next;Next >]".. - "button[12.0,11.0;2.0,0.6;next;Next >]") - end - table.insert(formspec, "button[0.0,0.2;2.0,0.6;back;Back]".. - "button[8.0,11.0;2.0,0.6;back;Back]") - local what = minetest.formspec_escape(what_is_the_list_about) - table.insert(formspec, "label[7.0,0.4;* Manage your ") - table.insert(formspec, what) - table.insert(formspec, "s *]") - table.insert(formspec, "label[0.2,2.45;Your ") - table.insert(formspec, what) - table.insert(formspec, ":]") - -- offer a dropdown list and a text input field for new varialbe names for adding - table.insert(formspec, yl_speak_up.create_dropdown_playerlist( - player, pname, - table_of_entries, - yl_speak_up.speak_to[pname].tmp_index_general, - 2.6 + (optional_add_space), 2.15, 1.0, 0.6, - "list_of_entries", - what, - "Delete selected "..what, - "add_entry_general", - minetest.formspec_escape(tooltip_add_entry_general), - "del_entry_general", - minetest.formspec_escape(tooltip_del_entry_general) - )) - - -- either nil or the text of the selected entry - return selected -end - - - --- small helper function for the function below -yl_speak_up.get_sub_fs_colorize_table = function(formspec, table_specs, liste, color) - table.insert(formspec, "tablecolumns[color;text]table[") - table.insert(formspec, table_specs) - local tmp = {} - for k, v in pairs(liste) do - table.insert(tmp, color or "#FFFFFF") - table.insert(tmp, minetest.formspec_escape(v)) - end - table.insert(formspec, table.concat(tmp, ",")) - table.insert(formspec, ";]") -end - - -yl_speak_up.get_sub_fs_show_list_in_box = function(formspec, - label, field_name, liste, start_x, start_y, width, height, label_ident, - box_color, column_color, - tooltip_text, add_lines) - local dim_str = tostring(width)..","..tostring(height) - table.insert(formspec, "container[") - table.insert(formspec, tostring(start_x)..","..tostring(start_y)..";") - table.insert(formspec, dim_str) - table.insert(formspec, "]") - table.insert(formspec, "box[0,0;") - table.insert(formspec, dim_str) - table.insert(formspec, ";") - table.insert(formspec, box_color or "#666666") - table.insert(formspec, "]") - -- add buttons etc. first so that the label remains visible on top - if(add_lines) then - table.insert(formspec, add_lines) - end - table.insert(formspec, "label[") - table.insert(formspec, tostring(0.1 + label_ident)) - table.insert(formspec, ",0.5;") - table.insert(formspec, label) - table.insert(formspec, "]") - yl_speak_up.get_sub_fs_colorize_table(formspec, - "0.1,0.7;"..tostring(width-0.2)..","..tostring(height-0.8)..";"..tostring(field_name)..";", - liste or {}, column_color) - if(tooltip_text and tooltip_text ~= "") then - table.insert(formspec, "tooltip[") - table.insert(formspec, field_name) - table.insert(formspec, ";") - table.insert(formspec, tooltip_text) - table.insert(formspec, "\n\nClick on an element to select it.") - table.insert(formspec, "]") - end - table.insert(formspec, "container_end[]") -end diff --git a/editor/api/fs_edit_general.lua b/editor/api/fs_edit_general.lua deleted file mode 100644 index 1916c0f..0000000 --- a/editor/api/fs_edit_general.lua +++ /dev/null @@ -1,2554 +0,0 @@ - --- helper function; get a formspec with the inventory of the player (for selecting items) -yl_speak_up.fs_your_inventory_select_item = function(pname, data) - return "label[0.2,4.2;Name of the item(stack):]".. - "field[4.0,4.0;16.0,0.6;inv_stack_name;;"..(data.inv_stack_name or "").."]".. - "tooltip[inv_stack_name;Enter name of the block and amount.\n".. - "Example: \"default:apple 3\" for three apples,\n".. - " \"farming:bread\" for a bread.]".. - "label[0.2,5.7;Or put the item in here\nand click on \"Update\":]".. - "button[5.5,5.5;1.5,0.9;store_item_name;Update]".. - "list[detached:yl_speak_up_player_"..pname..";npc_wants;4.0,5.5;1,1;]".. - "label[8,4.9;Your inventory:]".. - "list[current_player;main;8,5.3;8,4;]" -end - - --- helper function: get the names of the inventory lists of the node at position --- pos on the map and return the index of search_for_list_name in that index -yl_speak_up.get_node_inv_lists = function(pos, search_for_list_name) - if(not(pos)) then - return {inv_lists = {"- no inventory -"}, index = "1"} - end - local meta = minetest.get_meta(pos) - if(not(meta)) then - return {inv_lists = {"- no inventory -"}, index = "1"} - end - local inv_lists = {} - local index = -1 - local inv = meta:get_inventory() - - table.insert(inv_lists, minetest.formspec_escape("- please select -")) - for k,v in pairs(inv:get_lists()) do - table.insert(inv_lists, k) - if(search_for_list_name == k) then - index = #inv_lists - end - end - return {inv_lists = inv_lists, index = tostring(index)} -end - - --- helper function for yl_speak_up.handle_input_fs_edit_option_related -yl_speak_up.delete_element_p_or_a_or_e = function( - player, pname, n_id, d_id, o_id, x_id, id_prefix, - element_list_name, element_desc, formspec_input_to) - -- does the dialog we want to modify exist? - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(dialog and dialog.n_dialogs - and x_id - and dialog.n_dialogs[d_id] - and dialog.n_dialogs[d_id].d_options - and dialog.n_dialogs[d_id].d_options[o_id])) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2]".. - "label[0.2,0.5;The dialog that is supposed to contain the\n".. - "element that you want to delete does not exist.]".. - "button[1.5,1.5;2,0.9;back_from_cannot_be_edited;Back]"}) - return - end - local old_elem = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ][ x_id ] - if(id_prefix == "r_" and old_elem and old_elem.r_type == "dialog") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2]".. - "label[0.2,0.5;Effects of the type \"dialog\" cannot be deleted.\n".. - "Use the edit options or dialog menu to change the target dialog.]".. - "button[1.5,1.5;2,0.9;back_from_cannot_be_edited;Back]"}) - return - end - -- actually delete the element - dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ][ x_id ] = nil - -- record this as a change, but do not save do disk yet - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..tostring(d_id)..": "..element_desc.." "..tostring( x_id ).. - " deleted for option "..tostring(o_id)..".") - -- TODO: when trying to save: save to disk as well? - -- show the new/changed element - -- go back to the edit option dialog (after all we just deleted the prerequirement) - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[6,2]".. - "label[0.2,0.5;"..element_desc.." \"".. - minetest.formspec_escape(tostring( x_id )).. - "\" has been deleted.]".. - "button[1.5,1.5;2,0.9;back_from_delete_element;Back]"}) - return -end - - --- helper function for yl_speak_up.save_element_p_or_a_or_e -yl_speak_up.save_element_check_priv = function(player, priv_name, formspec_input_to, explanation) - local priv_list = {} - priv_list[priv_name] = true - if(not(minetest.check_player_privs(player, priv_list))) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2]".. - "label[0.2,0.5;Error: You need the \"".. - tostring(priv_name).."\" priv".. - tostring(explanation)..".]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return false - end - return true -end - --- helper function for yl_speak_up.handle_input_fs_edit_option_related -yl_speak_up.save_element_p_or_a_or_e = function( - player, pname, n_id, d_id, o_id, x_id, id_prefix, tmp_data_cache, - element_list_name, element_desc, max_entries_allowed, - values_what, values_operator, values_block, values_trade, values_inv, - formspec_input_to, data, fields) - - -- for creating the new prerequirement; normal elements: p_type, p_value, p_id - local v = {} - -- determine p_type - v[ id_prefix.."type" ] = values_what[ data.what ] - -- so that we don't have to compare number values of data.what - local what_type = values_what[ data.what ] - - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(dialog) or not(dialog.n_dialogs) - or not(dialog.n_dialogs[d_id]) - or not(dialog.n_dialogs[d_id].d_options) - or not(dialog.n_dialogs[d_id].d_options[o_id])) then - -- this really should not happen during the normal course of operation - -- (only if the player sends forged formspec data or a bug occoured) - minetest.chat_send_player(pname, "Dialog or option does not exist.") - return - end - local elements = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] - if(not(elements)) then - dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] = {} - elements = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] - x_id = "new" - end - -- set x_id appropriately - if(not(x_id) or x_id == "new") then - x_id = id_prefix..yl_speak_up.find_next_id(elements) - end - v[ id_prefix.."id" ] = x_id - - -- if needed: show a message after successful save so that the player can take - -- his items back from the trade_inv slots - local show_save_msg = nil - local sorted_key_list = yl_speak_up.sort_keys(elements) - if( x_id == "new" and #sorted_key_list >= max_entries_allowed) then - -- this really should not happen during the normal course of operation - -- (only if the player sends forged formspec data or a bug occoured) - minetest.chat_send_player(pname, "Maximum number of allowed entries exceeded.") - return - end - -- "an internal state (i.e. of a quest)", -- 2 - if(what_type == "state" and id_prefix ~= "a_") then - v[ id_prefix.."value" ] = "expression" - v[ id_prefix.."operator" ] = values_operator[ data.operator ] - v[ id_prefix.."var_cmp_value" ] = (data.var_cmp_value or "") - -- if it is a custom server function,then do not preifx it with $ playername - if(id_prefix == "p_") then - local idx = table.indexof(yl_speak_up.custom_server_functions.precondition_descriptions, - data.variable_name) - if(idx > -1) then - v[ id_prefix.."variable" ] = data.variable_name - else - v[ id_prefix.."variable" ] = yl_speak_up.add_pname_to_var(data.variable_name, pname) - end - else - v[ id_prefix.."variable" ] = yl_speak_up.add_pname_to_var(data.variable_name, pname) - end - - -- "the value of a property of the NPC (for generic NPC)" - elseif(what_type == "property" and id_prefix ~= "a_") then - v[ id_prefix.."value" ] = (data.property or "") - v[ id_prefix.."operator" ] = values_operator[ data.operator ] - v[ id_prefix.."var_cmp_value" ] = (data.var_cmp_value or "") - - -- "something that has to be calculated or evaluated (=call a function)" - elseif(what_type == "evaluate") then - v[ id_prefix.."value" ] = (data.function_name or "") - v[ id_prefix.."operator" ] = values_operator[ data.operator ] - v[ id_prefix.."var_cmp_value" ] = (data.var_cmp_value or "") - -- transfer the parameters - for i = 1, 9 do - local s = "param"..tostring(i) - v[ id_prefix..s ] = (data[s] or "") - end - - -- "a block somewhere", -- 3 - elseif(what_type == "block" and id_prefix ~= "a_") then - v[ id_prefix.."value" ] = values_block[ data.block ] - if(not(data.block_pos) or not(data.node_data) or not(data.node_data.name)) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: Please select a block first!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - -- for "node_is_air", there is no need to store node name and parameter - if(v[ id_prefix.."value" ] - and (v[ id_prefix.."value" ] == "node_is_like" - or v[ id_prefix.."value" ] == "node_is_diffrent_from") - or v[ id_prefix.."value" ] == "place" - or v[ id_prefix.."value" ] == "dig" - or v[ id_prefix.."value" ] == "punch" - or v[ id_prefix.."value" ] == "right-click") then - v[ id_prefix.."node" ] = data.node_data.name - v[ id_prefix.."param2" ] = data.node_data.param2 - end - -- preconditions can be applied to all blocks; effects may be more limited - if(id_prefix == "r_" - and yl_speak_up.check_blacklisted(v[id_prefix.."value"], - -- we don't know yet which node will be there later on - data.node_data.name, data.node_data.name)) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: Blocks of type \"".. - tostring(data.node_data.name).."\" do not allow\n".. - "interaction of type \""..tostring(v[id_prefix.."value"]).. - "\" for NPC.]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - -- we also need to store the position of the node - v[ id_prefix.."pos" ] = {x = data.block_pos.x, y = data.block_pos.y, z = data.block_pos.z } - -- "I can't punch it. The block is as the block *above* the one I punched.", - if(id_prefix == "p_" and data.block == 5) then - v.p_pos.y = v.p_pos.y + 1 - end - - -- "a trade", -- 4 - -- (only for preconditions; not for effects) - elseif(what_type == "trade" and id_prefix == "p_") then - -- this depends on the trade associated with that option; therefore, - -- it does not need any more parameters (they come dynamicly from the - -- trade) - v.p_value = values_trade[ data.trade ] - - -- "the inventory of the player", -- 5 - -- "the inventory of the NPC", -- 6 - -- "the inventory of a block somewhere", -- 7 - -- (only for preconditions; not for effects) - elseif((id_prefix == "p_" - and (what_type == "player_inv" or what_type == "npc_inv" or what_type == "block_inv")) - or(id_prefix == "r_" - and (what_type == "put_into_block_inv" or what_type == "take_from_block_inv"))) then - -- changing the inventory of a block? we need to set p_value to something - if(id_prefix == "r_") then - -- just to be sure something is stored there... - v.r_value = data.inv_stack_name - -- for easier access in the formspec - v.r_itemstack = data.inv_stack_name - -- store in p_value what we want to check regarding the inv (contains/contains not/empty/..) - else - v.p_value = values_inv[ data.inv ] - end - if(v.p_value and v.p_value ~= "inv_is_empty") then - if(not(data.inv_stack_name) or data.inv_stack_name == "") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: Please provide the name of the ".. - "\nitem you want to check for!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - -- we have checked this value earlier on - v[ id_prefix.."itemstack" ] = data.inv_stack_name - end - - if(data and data.what_type == "player_inv") then - data.inv_list_name = "main" - elseif(data and data.what_type == "npc_inv") then - data.inv_list_name = "npc_main" - elseif(data and data.what_type == "block_inv") then - data.inv_list_name = "main" - end - if(not(data.inv_list_name) or data.inv_list_name == "") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: Please provide the name of the ".. - "\ninventory you want to access!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - -- the name of the inventory list we want to access - v[ id_prefix.."inv_list_name" ] = data.inv_list_name - - -- the inventory of a block - if(what_type == "block_inv" - or what_type == "put_into_block_inv" - or what_type == "take_from_block_inv") then - if(not(data.block_pos) or not(data.node_data) or not(data.node_data.name)) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: Please select a block first!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - -- we also need to store the position of the node - v[ id_prefix.."pos" ] = {x = data.block_pos.x, y = data.block_pos.y, z = data.block_pos.z } - end - - -- "give item (created out of thin air) to player (requires yl_speak_up.npc_privs_priv priv)", -- 9 - -- "take item from player and destroy it (requires yl_speak_up.npc_privs_priv priv)", -- 10 - elseif(id_prefix == "r_" and (what_type == "give_item" or what_type == "take_item")) then - if(not(data.inv_stack_name) or data.inv_stack_name == "") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: Please provide the name of the ".. - "\nitem you want to give or take!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - local priv_list = {} - if(not(yl_speak_up.save_element_check_priv(player, yl_speak_up.npc_privs_priv, - formspec_input_to, " in order to set this effect"))) then - return - end - v[ "r_value" ] = data.inv_stack_name - - - -- "move the player to a given position (requires yl_speak_up.npc_privs_priv priv)", -- 11 - elseif(what_type == "move" and id_prefix == "r_") then - if(not(data.move_to_x) or not(data.move_to_y) or not(data.move_to_z)) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2]".. - "label[0.2,0.5;Error: Please provide valid coordinates ".. - " x, y and z!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - if(not(yl_speak_up.save_element_check_priv(player, yl_speak_up.npc_privs_priv, - formspec_input_to, " in order to set this effect"))) then - return - end - v[ "r_value" ] = minetest.pos_to_string( - {x = data.move_to_x, y = data.move_to_y, z = data.move_to_z}) - - -- effect "execute Lua code (requires npc_master priv)", -- precondition: 8; effect: 12 - elseif((what_type == "function" and id_prefix == "p_") - or (what_type == "function" and id_prefix == "r_")) then - if(not(data.lua_code) or data.lua_code == "") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2]".. - "label[0.2,0.5;Error: Please enter the Lua code you want ".. - "to execute!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - if(not(yl_speak_up.save_element_check_priv(player, "npc_master", - formspec_input_to, " in order to set this"))) then - return - end - v[ id_prefix.."value" ] = data.lua_code - - -- "NPC crafts something", -- 6 - -- (only for effects; not for preconditions) - elseif(what_type == "craft" and id_prefix == "r_") then - local player_inv = player:get_inventory() - if(player_inv:get_stack("craftpreview", 1):is_empty()) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: Please prepare your craft grid first!".. - "\nYour NPC needs to know what to craft.]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - -- store the craft result (Note: the craft result may change in the future - -- if the server changes its craft result, making this craft invalid) - v[ "r_value" ] = player_inv:get_stack("craftpreview", 1):to_string() - v[ "r_craft_grid"] = {} - for i = 1, 9 do - -- store all the indigrents of the craft grid - table.insert( v[ "r_craft_grid" ], - player_inv:get_stack("craft", i):to_string()) - end - - -- "go to other dialog if the *previous* effect failed", -- 7 - -- (only for effects; not for preconditions) - elseif(what_type == "on_failure" and id_prefix == "r_") then - v[ "r_value" ] = data.on_failure - - -- "send a chat message to all players", -- 8 - -- (only for effects; not for preconditions) - elseif(what_type == "chat_all" and id_prefix == "r_") then - data.chat_msg_text = fields.chat_msg_text - -- allow saving only if the placeholders are all present - -- (reason for requiring them: players and server owners ought to - -- be able to see who is responsible for a message) - if(not(string.find(data.chat_msg_text, "%$NPC_NAME%$")) - or not(string.find(data.chat_msg_text, "%$PLAYER_NAME%$")) - or not(string.find(data.chat_msg_text, "%$OWNER_NAME%$"))) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;Error: Your chat message needs to contain ".. - "the following\nplaceholders: $NPC_NAME$, ".. - "$PLAYER_NAME$ and $OWNER_NAME$.\nThat way, other ".. - "players will know who sent the message.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - v[ "r_value" ] = data.chat_msg_text - - -- "Normal trade - one item(stack) for another item(stack).", -- 3 - -- (only for actions) - elseif(what_type == "trade" and id_prefix == "a_") 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 - -- just to make sure that the trade_id is properly set... - if(not(data.trade_id)) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;Error: Missing trade ID.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - -- the button is called store_trade_simple instead of save_element in - -- the trade simple function(s); we want to store a trade - fields.store_trade_simple = true - local res = yl_speak_up.input_add_trade_simple(player, "", fields, nil) - -- the above function sets: - -- dialog.trades[ trade_id ] = {pay={ps},buy={bs}, d_id = d_id, o_id = o_id} - -- store the trade as an action: - local dialog = yl_speak_up.speak_to[pname].dialog - if(res and dialog.trades and dialog.trades[ data.trade_id ]) then - v[ "a_value" ] = data.trade_id - v[ "a_pay" ] = dialog.trades[ data.trade_id ].pay - v[ "a_buy" ] = dialog.trades[ data.trade_id ].buy - yl_speak_up.edit_mode_set_a_on_failure(data, pname, v) - end - - -- "The NPC gives something to the player (i.e. a quest item).", -- 4 - -- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5 - -- (only for actions) - elseif(((what_type == "npc_gives" or what_type == "npc_wants") and id_prefix == "a_") - or (what_type == "player_offered_item" and id_prefix == "p_")) then - local trade_inv_list = what_type - if(id_prefix == "p_") then - trade_inv_list = "npc_wants" - end - local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) - if(not(trade_inv) or trade_inv:is_empty( trade_inv_list )) then - local what = "give to" - if(id_prefix == "p_") then - what = "accept from" - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;Please insert an item first! Your NPC ".. - "needs\nto know what it shall "..what.." the player.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - yl_speak_up.edit_mode_set_a_on_failure(data, pname, v) - -- change the node in the slot - local stack = trade_inv:get_stack( trade_inv_list, 1) - if(not(stack) or not(minetest.registered_items[ stack:get_name() ])) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;This item is unkown. Please use only known".. - "items.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - -- is this particular item blacklisted on this server? - -- this is only relevant for actions, not for preconditions - if(id_prefix ~= "p_" and yl_speak_up.blacklist_action_quest_item[ stack:get_name() ]) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;Sorry. This item is blacklisted on this ".. - "server.\nYou can't use it as a quest item.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - local meta = stack:get_meta() - -- what does the NPC want to give? - v[ id_prefix.."value" ] = stack:get_name().." "..stack:get_count() - -- for displaying as a background image - data.item_string = v[ id_prefix.."value" ] - if(what_type == "npc_wants" or what_type == "player_offered_item") then - -- try to reconstruct $PLAYER_NAME$ (may not always work) - local item_was_for = meta:get_string("yl_speak_up:quest_item_for") - local new_desc = meta:get_string("description") - if(item_was_for and item_was_for ~= "") then - new_desc = string.gsub(new_desc, item_was_for, "$PLAYER_NAME$") - end - data.item_desc = new_desc - end - -- set new description if there is one set (optional) - if(data.item_desc - and data.item_desc ~= "" - and data.item_desc ~= "- none set -") then - if(what_type == "npc_gives") then - meta:set_string("description", data.item_desc) - end - v[ id_prefix.."item_desc" ] = data.item_desc - end - if(what_type == "npc_wants" or what_type == "player_offers_item") then - data.item_quest_id = meta:get_string("yl_speak_up:quest_id") - end - -- set special ID (optional) - if(data.item_quest_id - and data.item_quest_id ~= "" - and data.item_quest_id ~= "- no item set -") then - if(what_type == "npc_gives") then - -- which player got this quest item? - meta:set_string("yl_speak_up:quest_item_for", pname) - -- include the NPC id so that we know which NPC gave it - meta:set_string("yl_speak_up:quest_item_from", tostring(n_id)) - -- extend quest_id by NPC id so that it becomes more uniq - meta:set_string("yl_speak_up:quest_id", - tostring(n_id).." "..tostring(data.item_quest_id)) - end - v[ id_prefix.."item_quest_id" ] = data.item_quest_id - end - if( v["a_item_quest_id"] and not(v[ "a_item_desc"]) and what_type == "npc_gives") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;You can't set a special quest ID without ".. - "also changing\nthe description. The player would be ".. - "unable to tell\nthe quest item and normal items ".. - "apartapart.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - if(data.item_group and data.item_group ~= "" - and data.item_group ~= "- no, just this one item -") then - v["p_item_group"] = data.item_group - end - v["p_item_stack_size"] = data.item_stack_size - v["p_match_stack_size"] = data.match_stack_size - local player_inv = player:get_inventory() - if(not(player_inv:room_for_item("main", stack))) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;You have no room in your inventory for ".. - "the example\nitem. Please make room so that it can be".. - "given back to you!]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - player_inv:add_item("main", stack) - trade_inv:remove_item(trade_inv_list, stack) - -- just send a message that the save was successful and give the player time to - -- take his items back - show_save_msg = "size[9,2.5]".. - "label[0.2,0.5;The information was saved successfully.\n".. - "The item has been returned to your inventory.]".. - "button[1.5,2.0;2,0.9;back_from_saving;Back]" - - -- "The player has to manually enter a password or passphrase or some other text.", -- 6 - elseif(what_type == "text_input" and id_prefix == "a_") then - if(not(data.quest_question)) then - data.quest_question = "Your answer:" - end - v[ "a_question" ] = data.quest_question - -- the player setting this up needs to provide the correct answer - if(not(data.quest_answer)) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;Error: Please provide the correct answer!\n".. - "The answer the player gives is checked against this.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - v[ "a_value" ] = data.quest_answer - if(not(data.action_failure_dialog)) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;Error: Please provide a target dialog if ".. - "the player gives the wrong answer.]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - yl_speak_up.edit_mode_set_a_on_failure(data, pname, v) - - elseif(what_type == "deal_with_offered_item" and id_prefix == "r_") then - if(not(data.select_deal_with_offered_item) or data.select_deal_with_offered_item < 2) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2.5]".. - "label[0.2,0.5;Error: Please select what the NPC shall do!]".. - "button[1.5,2.0;2,0.9;back_from_error_msg;Back]"}) - return - end - v[ "r_value" ] = yl_speak_up.dropdown_values_deal_with_offered_item[data.select_deal_with_offered_item] - - -- "Call custom functions that are supposed to be overridden by the server.", -- - -- precondition: 9; action: 7; effect: 13 - elseif((id_prefix == "a_" and what_type == "custom") - or (id_prefix == "p_" and what_type == "custom") - or (id_prefix == "r_" and what_type == "custom")) then - v[ id_prefix.."value" ] = data.custom_param - if(id_prefix == "a_") then - v[ "a_on_failure" ] = data.action_failure_dialog - end - - -- "the type of the entity of the NPC", - -- precondition: (last entry) - elseif(what_type == "entity_type" and id_prefix == "p_") then - -- Note: We might check for minetest.registered_entities[data.entity_type] - but - -- that doesn't really help much - so we skip that. - v[ "p_value" ] = data.entity_type - - -- "The preconditions of another dialog option are fulfilled/not fulfilled.", -- 10 - -- precondition: 10 - elseif(what_type == "other" and id_prefix == "p_") then - if(data.other_o_id and data.other_o_id ~= "-select-") then - v[ "p_value" ] = data.other_o_id - end - if(data.fulfilled and data.fulfilled ~= "-select-") then - v[ "p_fulfilled" ] = data.fulfilled - end - - elseif(what_type == "true") then - v[ "p_value" ] = true -- doesn't matter here - just *some* value - elseif(what_type == "false") then - v[ "p_value" ] = true -- doesn't matter here - just *some* value - end - - v[ "alternate_text" ] = data.alternate_text - - -- only save if something was actually selected - if(v[ id_prefix.."value"]) then - if(not(dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ])) then - dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] = {} - end - -- store the change in the dialog - dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ][ x_id ] = v - -- clear up data - yl_speak_up.speak_to[pname][ id_prefix.."id" ] = nil - yl_speak_up.speak_to[pname][ tmp_data_cache ] = nil - -- record this as a change, but do not save do disk yet - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..tostring(d_id)..": "..element_desc.." "..tostring(x_id).. - " added/changed for option "..tostring(o_id)..".") - if(show_save_msg) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = show_save_msg}) - return - end - -- TODO: when trying to save: save to disk as well? - -- show the new/changed precondition - yl_speak_up.show_fs(player, formspec_input_to, x_id) - return - else - -- make sure the player is informed that saving failed - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: There is no \""..tostring(id_prefix).. - "value\" set.\n".. - "\nCould not save.]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end -end - - --- These two functions --- * yl_speak_up.handle_input_fs_edit_option_related and --- * yl_speak_up.build_fs_edit_option_related --- are very similar for preconditions and effects. Therefore they're called here --- with a lot of parameters. fs_edit_preconditions.lua and fs_edit_effects.lua --- contain only wrappers. - -yl_speak_up.handle_input_fs_edit_option_related = function(player, formname, fields, - id_prefix, element_list_name, max_entries_allowed, - element_desc, tmp_data_cache, - text_ask_for_punching, - values_what, values_operator, values_block, values_trade, values_inv, - check_what, check_operator, check_block, check_trade, check_inv, - get_sorted_player_var_list_function, - formspec_input_to - ) - if(not(player)) then - return - end - local pname = player:get_player_name() - -- what are we talking about? - local n_id = yl_speak_up.speak_to[pname].n_id - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - local x_id = yl_speak_up.speak_to[pname][ id_prefix.."id"] - - -- this only works in edit mode - if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then - return - end - - if(fields.back_from_cannot_be_edited - or fields.back_from_show_var_usage) then - yl_speak_up.show_fs(player, formspec_input_to, x_id) - return - end - - -- clear editing cache tmp_data_cache for all other types - if(id_prefix ~= "p_") then - yl_speak_up.speak_to[pname][ "tmp_prereq" ] = nil - end - if(id_prefix ~= "a_") then - yl_speak_up.speak_to[pname][ "tmp_action" ] = nil - end - if(id_prefix ~= "r_") then - yl_speak_up.speak_to[pname][ "tmp_effect" ] = nil - end - - -- delete precondition, action or effect - if(fields.delete_element) then - yl_speak_up.delete_element_p_or_a_or_e( player, pname, n_id, d_id, o_id, x_id, id_prefix, - element_list_name, element_desc, formspec_input_to) - return - end - - if(fields.select_block_pos) then - minetest.chat_send_player(pname, text_ask_for_punching) - -- this formspec expects the block punch: - yl_speak_up.speak_to[pname].expect_block_punch = formspec_input_to - return - end - - -- field inputs: those do not trigger a sending of the formspec on their own - - local was_changed = false - -- are we talking about an inventory? - -- (inventory only applies to preconditions; not effects) - local data = yl_speak_up.speak_to[pname][ tmp_data_cache ] - local what_type = "" - if(data and data.what and values_what[ data.what ]) then - what_type = values_what[ data.what ] - end - - if(((fields.inv_stack_name and fields.inv_stack_name ~= "") - or (fields.store_item_name and fields.store_item_name ~= "")) - and data and data.what - and ((id_prefix == "p_" - and (what_type == "player_inv" or what_type == "npc_inv" or what_type == "block_inv")) - -- "give item (created out of thin air) to player (requires yl_speak_up.npc_privs_priv priv)", -- 9 - -- "take item from player and destroy it (requires yl_speak_up.npc_privs_priv priv)", -- 10 - or (id_prefix == "r_" - and (what_type == "give_item" or what_type == "take_item" - or what_type == "put_into_block_inv" or what_type == "take_from_block_inv")))) then - local wanted = "" - local wanted_name = "" - if(not(fields.store_item_name)) then - local parts = fields.inv_stack_name:split(" ") - local size = 1 - if(parts and #parts > 1) then - size = tonumber(parts[2]) - if(not(size) or size < 1) then - size = 1 - end - end - wanted = parts[1].." "..tostring(size) - wanted_name = parts[1] - else - local trade_inv = minetest.get_inventory({type="detached", - name="yl_speak_up_player_"..pname}) - if(not(trade_inv) or trade_inv:is_empty("npc_wants", 1)) then - -- show error message - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.0;Please put an item(stack) into the slot ".. - "next to the\n\"Store\" button first!]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - local stack = trade_inv:get_stack("npc_wants", 1) - wanted = stack:get_name().." "..stack:get_count() - wanted_name = stack:get_name() - end - -- does the item exist? - if(minetest.registered_items[ wanted_name ]) then - data.inv_stack_name = wanted - fields.inv_stack_name = wanted - else - -- show error message - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[8,2]".. - "label[0.2,0.5;Error: \"".. - minetest.formspec_escape(wanted).. - "\" is not a valid item(stack).]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - - elseif(fields.select_deal_with_offered_item and fields.select_deal_with_offered_item ~= "") then - data.select_deal_with_offered_item = table.indexof( - yl_speak_up.dropdown_list_deal_with_offered_item, - fields.select_deal_with_offered_item) - - elseif(fields.select_accept_group and fields.select_accept_group ~= "" - and data and data.what and what_type == "player_offered_item" and id_prefix == "p_") then - data.item_group = fields.select_accept_group - - elseif(fields.select_match_stack_size and fields.select_match_stack_size ~= "" - and data and data.what and what_type == "player_offered_item" and id_prefix == "p_") then - data.match_stack_size = fields.select_match_stack_size:split(" ")[1] - - -- comparison value for a variable (same for both preconditions and effects) - -- (also used for checking return values of functions and property values) - elseif(fields.var_cmp_value - and data and data.what - and (what_type == "state" or what_type == "property" or what_type == "evaluate")) then - data.var_cmp_value = fields.var_cmp_value - was_changed = true - - -- text for a chat message - elseif(fields.chat_msg_text - and data and data.what and what_type == "chat_all" and id_prefix == "r_") then - data.chat_msg_text = fields.chat_msg_text - was_changed = true - - elseif(fields.custom_param - and fields.custom_param ~= "- Insert a text that is passed on to your function here -" - and fields.custom_param ~= "" - and data and data.what - and ((id_prefix == "a_" and what_type == "custom") - or (id_prefix == "p_" and what_type == "custom") - or (id_prefix == "r_" and what_type == "custom"))) then - data.custom_param = fields.custom_param - was_changed = true - - elseif(fields.action_item_quest_id - and fields.action_item_quest_id ~= "" - and fields.action_item_quest_id ~= "- none set -" - and data and data.what and what_type == "npc_gives" and id_prefix == "a_") then - data.item_quest_id = fields.action_item_quest_id - was_changed = true - end - -- action_item_quest_id and action_item_desc can be set at the same time - if(fields.action_item_desc - and fields.action_item_desc ~= "" - and fields.action_item_desc ~= "- no item set -" - and data and data.what and what_type == "npc_gives" and id_prefix == "a_") then - -- TODO: check if it diffrent from the default one of the stack - data.item_desc = fields.action_item_desc - was_changed = true - end - if(fields.quest_question - and fields.quest_question ~= "" - and data and data.what and what_type == "text_input" and id_prefix == "a_") then - data.quest_question = fields.quest_question - was_changed = true - end - -- quest question and answer can be given with the same press of the save button - if(fields.quest_answer - and fields.quest_answer ~= "- Insert the correct answer here -" - and fields.quest_answer ~= "" - and data and data.what and what_type == "text_input" and id_prefix == "a_") then - data.quest_answer = fields.quest_answer - was_changed = true - end - - -- "move the player to a given position (requires yl_speak_up.npc_privs_priv priv)", -- 11 - if(fields.move_to_x or fields.move_to_y or fields.move_to_z) then - local dimension = {"x","y","z"} - for i, dim in ipairs(dimension) do - local text = fields["move_to_"..dim] - if(text and text ~= "") then - local val = tonumber(text) - if(not(val) or val < -32000 or val > 32000) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[9,2]".. - "label[0.2,0.5;Error: The coordinate values have ".. - "be in the range of -32000..32000.]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - else - data[ "move_to_"..dim ] = val - end - end - end - end - -- lua code - if(fields.lua_code) then - data.lua_code = fields.lua_code - end - -- select the type of the entity for "the type of the entity of the NPC" - if(fields.entity_type) then - data.entity_type = fields.entity_type - end - -- if the type of operator is changed: store any new values that may need storing - if(what_type == "evaluate" - and (fields.set_param0 or fields.set_param1 or fields.set_param2 or fields.set_param3 - or fields.set_param4 or fields.set_param5 or fields.set_param6 or fields.set_param7 - or fields.set_param8 or fields.set_param9)) then - for i = 1, 9 do - local pn = "param"..tostring(i) - if(fields["set_"..pn]) then - if(data[pn] ~= fields["set_"..pn]) then - data[pn] = fields["set_"..pn] - was_changed = true - end - end - end - end - - - -- the save button was pressed - if(fields.save_element and data and data.what and values_what[ data.what ]) then - local v = yl_speak_up.save_element_p_or_a_or_e( - player, pname, n_id, d_id, o_id, x_id, id_prefix, tmp_data_cache, - element_list_name, element_desc, max_entries_allowed, - values_what, values_operator, values_block, values_trade, values_inv, - formspec_input_to, data, fields) - return - end - - - -- selections in a dropdown menu (they trigger sending the formspec) - - -- select a general direction/type first - -- but *not* when enter was pressed (enter sends them all) - if(fields.select_what and not(fields.key_enter) and not(fields.store_item_name)) then - local nr = table.indexof(check_what, fields.select_what) - yl_speak_up.speak_to[pname][ tmp_data_cache ] = { what = nr } - end - -- select a subtype for the "a trade" selection - if(fields.select_trade) then - local nr = table.indexof(check_trade, fields.select_trade) - yl_speak_up.speak_to[pname][ tmp_data_cache ].trade = nr - end - -- select a subtype for the inventory selection (player or NPC) - if(fields.select_inv) then - local nr = table.indexof(check_inv, fields.select_inv) - yl_speak_up.speak_to[pname][ tmp_data_cache ].inv = nr - end - -- select data regarding a block - if(fields.select_block) then - local nr = table.indexof(check_block, fields.select_block) - yl_speak_up.speak_to[pname][ tmp_data_cache ].block = nr - end - -- select data regarding the inventory list of a block - if(fields.inv_list_name and fields.inv_list_name ~= "") then - local tmp = yl_speak_up.get_node_inv_lists( - yl_speak_up.speak_to[pname][ tmp_data_cache ].block_pos, - fields.inv_list_name) - -- if that inventory list really exists in that block: all ok - if(tmp and tmp.index ~= "" and tmp.index ~= "1") then - yl_speak_up.speak_to[pname][ tmp_data_cache ].inv_list_name = fields.inv_list_name - end - end - -- select data regarding a variable - if(fields.select_variable) then - -- get the list of available variables (with the same elements - -- and the same sort order as when the dropdown was displayed) - local var_list = get_sorted_player_var_list_function(pname) - yl_speak_up.strip_pname_from_varlist(var_list, pname) - local nr = table.indexof(var_list, fields.select_variable) - if(nr) then - yl_speak_up.speak_to[pname][ tmp_data_cache ].variable = nr - yl_speak_up.speak_to[pname][ tmp_data_cache ].variable_name = var_list[ nr ] - end - end - -- select data regarding an operator - if(fields.select_operator) then - local nr = table.indexof(check_operator, fields.select_operator) - yl_speak_up.speak_to[pname][ tmp_data_cache ].operator = nr - end - -- "the value of a property of the NPC (for generic NPC)" - if(fields.property and fields.property ~= "") then - yl_speak_up.speak_to[pname][ tmp_data_cache ].property = fields.property - end - -- "something that has to be calculated or evaluated (=call a function)" - if(fields.select_function_name and fields.select_function_name ~= "") then - for k, v in pairs(yl_speak_up["custom_functions_"..id_prefix]) do - if(v["description"] == fields.select_function_name) then - yl_speak_up.speak_to[pname][ tmp_data_cache ].function_name = k - end - end - end - -- "something that has to be calculated or evaluated (=call a function)" - if(fields.evaluate and fields.evaluate ~= "") then - yl_speak_up.speak_to[pname][ tmp_data_cache ].evaluate = fields.evaluate - end - for i = 1,9 do - local s = "param"..tostring(i) - if(fields[s] and fields[s] ~= "") then - yl_speak_up.speak_to[pname][ tmp_data_cache ][s] = fields[s] - end - end - -- another dialog option is true or false - -- Note: "-select-" can be choosen here as well - if(fields.select_other_o_id and fields.select_other_o_id ~= "") then - yl_speak_up.speak_to[pname][ tmp_data_cache ].other_o_id = fields.select_other_o_id - end - -- Note: "-select-" can be choosen here as well - if(fields.select_fulfilled and fields.select_fulfilled ~= "") then - yl_speak_up.speak_to[pname][ tmp_data_cache ].fulfilled = fields.select_fulfilled - end - if(fields.select_on_failure) then - -- in this case we really want the name of the target dialog - local dialog = yl_speak_up.speak_to[pname].dialog - yl_speak_up.speak_to[pname][ tmp_data_cache ].on_failure = - yl_speak_up.d_name_to_d_id(dialog, fields.select_on_failure) - end - if(fields.select_on_action_failure - and data and data.what and id_prefix == "a_") then - local dialog = yl_speak_up.speak_to[pname].dialog - yl_speak_up.speak_to[pname][ tmp_data_cache ].action_failure_dialog = - yl_speak_up.d_name_to_d_id(dialog, fields.select_on_action_failure) - end - - -- new variables have to be added (and deleted) somewhere after all - if(fields.manage_variables) then - -- remember which formspec we are comming from - yl_speak_up.speak_to[pname][ "working_at" ] = formspec_input_to - if(data.variable) then - yl_speak_up.speak_to[pname].tmp_index_variable = data.variable - 1 - end - yl_speak_up.show_fs(player, "manage_variables") - return - end - - -- handle editing and changing of alternate texts for actions - if( fields.button_edit_action_on_failure_text_change - or fields.button_edit_effect_on_failure_text_change - or fields.turn_alternate_text_into_new_dialog - or fields.save_dialog_modification) then - yl_speak_up.handle_edit_actions_alternate_text( - player, pname, n_id, d_id, o_id, x_id, id_prefix, - formspec_input_to, data, fields, tmp_data_cache) - if(not(fields.save_dialog_modification) - and not(fields.turn_alternate_text_into_new_dialog)) then - return - end - was_changed = true - -- we are back from that submenu - elseif(fields.back_from_edit_dialog_modification) then - was_changed = true - end - - -- show var usage - starting from clicking on a precondition or effect in the - -- edit options menu and viewing the list containing that selected element - if( fields.show_var_usage and x_id) then - local dialog = yl_speak_up.speak_to[pname].dialog - local element = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ][ x_id ] - if(element and element[ id_prefix.."variable"]) then - local effect_name = "(Ef)fect" - if(id_prefix == "p_") then - effect_name = "pre(C)ondition" - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.fs_get_list_of_usage_of_variable( - element[ id_prefix.."variable"], pname, true, - "back_from_show_var_usage", - "Back to select "..effect_name.." "..tostring(x_id).. - " of option "..tostring(o_id).. - " of dialog "..tostring(d_id), - -- internal variable? - (data and data.variable and data.variable < 3)) - }) - return - end - -- show var usuage - but this time from the edit dialog for that precondition or effect - elseif(fields.show_var_usage_edit_element and x_id) then - local dialog = yl_speak_up.speak_to[pname].dialog - local element = nil - -- x_id may be "new" and this may be the first element in element_list_name - if(dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ]) then - element = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ][ x_id ] - end - if(not(element) or data.variable_name) then - element = {} - element[ id_prefix.."variable"] = data.variable_name - end - if(element and element[ id_prefix.."variable"]) then - local effect_name = "(Ef)fect" - if(id_prefix == "p_") then - effect_name = "pre(C)ondition" - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = yl_speak_up.fs_get_list_of_usage_of_variable( - element[ id_prefix.."variable"], pname, true, - "back_from_error_msg", - "Back to select "..effect_name.." "..tostring(x_id).. - " of option "..tostring(o_id).. - " of dialog "..tostring(d_id), - -- internal variable? - (data and data.variable and data.variable < 3)) - }) - return - end - -- allow to delete unused variables - elseif(fields.delete_unused_variable) then - -- try to delete the variable (button comes from the show usage of variable formspec) - local text = yl_speak_up.del_quest_variable(pname, data.variable_name, nil) - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:"..formspec_input_to, - formspec = "size[10,2]".. - "label[0.2,0.0;Trying to delete variable \"".. - minetest.formspec_escape(tostring(data.variable_name)).. - "\":\n"..text.."]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - - -- the player wants to change/edit a precondition or effect - if(not(fields.back) - and (fields.change_element or fields.select_what or fields.select_trade - or fields.select_inv or fields.select_block - or fields.inv_list_name - or fields.select_deal_with_offered_item - or fields.select_accept_group - or fields.select_match_stack_size - or fields.select_variable or fields.select_operator - or fields.select_on_failure - or fields.select_on_action_failure - or fields.back_from_error_msg - or fields.store_item_name - or fields.select_other_o_id - or fields.select_fulfilled - or fields.select_function_name - or fields.entity_type - or was_changed - or fields.key_enter - or fields.quit - -- return was pressed - or fields.key_enter_field)) then - yl_speak_up.show_fs(player, formspec_input_to) - return - end - - -- go back to the edit option dialog - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, caller= formspec_input_to}) -end - - -yl_speak_up.build_fs_edit_option_related = function(player, table_click_result, - id_prefix, element_list_name, max_entries_allowed, - element_desc, tmp_data_cache, - what_do_you_want_txt, - values_what, values_operator, values_block, values_trade, values_inv, - check_what, check_operator, check_block, check_trade, check_inv, - get_sorted_player_var_list_function, - show_element_function, - table_of_name, - text_variable, text_select_operator, text_select_value, - text_block_position) - if(not(player)) then - return "" - end - local pname = player:get_player_name() - -- what are we talking about? - local n_id = yl_speak_up.speak_to[pname].n_id - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - local x_id = yl_speak_up.speak_to[pname][ id_prefix.."id" ] - - -- this only works in edit mode - if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then - return "size[1,1]label[0,0;You cannot edit this NPC.]" - end - - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(dialog) or not(dialog.n_dialogs) - or not(dialog.n_dialogs[d_id]) - or not(dialog.n_dialogs[d_id].d_options) - or not(dialog.n_dialogs[d_id].d_options[o_id])) then - return "size[4,1]label[0,0;Dialog option does not exist.]" - end - - local elements = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] - if(not(elements)) then - elements = {} - end - - -- did we arrive here through clicking on an element in the dialog edit options menu? - if(table_click_result or elements[ table_click_result ]) then - if(not(elements[ table_click_result ])) then - -- which element has the player selected? - local sorted_key_list = yl_speak_up.sort_keys(elements) - local selected = minetest.explode_table_event(table_click_result) - -- use "new" if nothing fits - x_id = "new" - if((selected.type == "CHG" or selected.type == "DLC") - and selected.row <= #sorted_key_list) then - x_id = sorted_key_list[ selected.row ] - end - - if( x_id == "new" and #sorted_key_list >= max_entries_allowed) then - return "size[9,1.5]".. - "label[0.2,0.0;There are only up to ".. - minetest.formspec_escape(yl_speak_up.max_result_effects).. - " "..element_desc.."s allowed per dialog option.]".. - "button[2.0,0.8;1.0,0.9;back;Back]" - end - else - -- allow to directly specify a x_id to show - x_id = table_click_result - end - - local show_var_usage = "" - if(x_id - - and elements[ x_id ] - and elements[ x_id ][ id_prefix.."type"] - and elements[ x_id ][ id_prefix.."type"] == "state" - and elements[ x_id ][ id_prefix.."variable"]) then - show_var_usage = "button[12.0,1.8;6.5,0.9;show_var_usage;".. - "Show where this variable is used]" - end - -- store which element we are talking about - yl_speak_up.speak_to[pname][ id_prefix.."id" ] = x_id - -- nothing selected yet - yl_speak_up.speak_to[pname][ tmp_data_cache ] = nil - -- display the selected element - if(x_id ~= "new") then - return "size[20,3]".. - "bgcolor[#00000000;false]".. - "label[0.2,0.5;Selected "..element_desc..":]".. - "tablecolumns[text;color,span=1;text;text]".. - "table[0.2,0.8;19.6,0.7;"..table_of_name..";".. - minetest.formspec_escape(elements[ x_id ][ id_prefix.."id"]).. - ",#FFFF00,".. - minetest.formspec_escape(elements[ x_id ][ id_prefix.."type"]).. - ",".. - minetest.formspec_escape( - show_element_function(elements[ x_id ], pname))..";0]".. - "button[2.0,1.8;1.5,0.9;delete_element;Delete]".. - "button[4.0,1.8;1.5,0.9;change_element;Change]".. - "button[6.0,1.8;5.5,0.9;back;Back to edit dialog option \"".. - tostring(o_id).."\"]".. - show_var_usage - end - end - - local data = yl_speak_up.speak_to[pname][ tmp_data_cache ] - - if(not(data) or not(data.what)) then - data = { what = 1} - end - -- fallback - if(not(x_id)) then - x_id = "new" - end - - local e = nil - -- does the element exist already? if so: use the existing values as presets for data - -- (so that the element can be edited) - -- does kind of the opposite than the saving of values starting in line 323 of this file - if(x_id ~= "new" and data.what == 1 and elements[ x_id ]) then - e = elements[ x_id ] - if( id_prefix == "r_" and e[ "r_type" ] == "dialog") then - -- dialog effects cannot be edited this way - return "size[9,2]".. - "label[0.2,0.5;Effects of the type \"dialog\" cannot be edited this way.\n".. - "Use the edit options or dialog menu to change the target dialog.]".. - "button[1.5,1.5;2,0.9;back_from_cannot_be_edited;Back]" - end - if( id_prefix == "p_" and e[ "p_type" ] == "item") then - -- the staff-based item precondition can be translated to an editable - -- inventory precondition which is equal - e[ "p_type" ] = "player_inv" - e[ "p_itemstack" ] = e[ "p_value"] - e[ "p_value" ] = "inv_contains" - end - - data.what = table.indexof(values_what, e[ id_prefix.."type" ]) - if(data.what == -1) then - data.what = 1 - - -- npc_gives/npc_wants (action) - -- (two seperate functions, but can be handled here together) - elseif(data.what and id_prefix == "a_" and (data.what == 4 or data.what == 5)) then - data.action_failure_dialog = e[ "a_on_failure" ] - -- data.item_string is used to show a background image - data.item_string = e[ "a_value"] -- stack name and count (as string) - data.item_desc = e[ "a_item_desc" ] - data.item_quest_id = e[ "a_item_quest_id" ] - - -- player_offered_item precondition - elseif(data.what and id_prefix == "p_" and (data.what == 8)) then - -- data.item_string is used to show a background image - data.item_string = e[ "p_value"] -- stack name and count (as string) - data.item_desc = e[ "p_item_desc" ] - data.item_quest_id = e[ "p_item_quest_id" ] - data.item_group = e[ "p_item_group" ] - data.item_stack_size = e["p_item_stack_size"] - data.match_stack_size = e["p_match_stack_size"] - end - - if(e[ "alternate_text"]) then - data.alternate_text = e[ "alternate_text" ] - end - -- write that data back - yl_speak_up.speak_to[pname][ tmp_data_cache ] = data - end - - local save_button = "button[5.0,12.2;1,0.7;save_element;Save]" - local formspec = - "size[20,13]".. - "label[5,0.5;Edit "..element_desc.." \""..minetest.formspec_escape(x_id).. - "\" of option \""..minetest.formspec_escape(tostring(o_id)).. - "\" of dialog \""..minetest.formspec_escape(tostring(d_id)).."\"]".. - "label[0.2,1.5;"..what_do_you_want_txt.."]".. - "label[0.2,2.0;Something regarding...]".. - "dropdown[4.0,1.8;14.0,0.6;select_what;".. - table.concat(check_what, ",")..";".. - tostring(data.what)..";]".. - "button[3.0,12.2;1,0.7;back;Abort]" - - if(id_prefix ~= "a_") then - formspec = formspec.. - "label[1,10.5;If you are unsure if your setup of pre(C)onditions and (Ef)fects ".. - "works as intended,\ntype \"/npc_talk debug "..tostring(n_id).."\" ".. - "in chat in order to enter debug mode. You can leave it with ".. - "\"/npc_talk debug off\".]" - end - - - if(data.what) then - yl_speak_up.speak_to[pname][ tmp_data_cache ] = data - end - local what_type = "" - if(data and data.what and values_what[ data.what ]) then - what_type = values_what[ data.what ] - end - -- "an internal state (i.e. of a quest)", -- 2 - -- (state is the second offered option in both preconditions and effects list) - if(data.what and what_type == "state" and id_prefix ~= "a_") then - return yl_speak_up.get_sub_fs_edit_option_p_and_e_state( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_variable, text_select_value, text_select_operator, - values_operator, check_operator, get_sorted_player_var_list_function ) - - -- "the value of a property of the NPC (for generic NPC)" - elseif(data.what and what_type == "property" and id_prefix ~= "a_") then - return yl_speak_up.get_sub_fs_edit_option_p_and_e_property( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_select_operator, values_operator, check_operator) - - -- "something that has to be calculated or evaluated (=call a function)" - elseif(data.what and what_type == "evaluate") then - return yl_speak_up.get_sub_fs_edit_option_p_and_e_evaluate( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_select_operator, values_operator, check_operator) - - -- "a block somewhere", -- 3 - -- (block is the third offered option in both preconditions and effects list) - elseif(data.what and what_type == "block" and id_prefix ~= "a_") then - return yl_speak_up.get_sub_fs_edit_option_p_and_e_block( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_block_position, values_block, check_block) - - -- "a trade", -- 4 - -- (trade - only for preconditions; effects have something else here) - elseif(data.what and id_prefix == "p_" and what_type == "trade") then - return yl_speak_up.get_sub_fs_edit_option_precondition_trade( - pname, dialog, formspec, data, id_prefix, save_button, e, - values_trade, check_trade) - - -- "the type of the entity of the NPC", - -- (entity_type - only for preconditions) - elseif(data.what and id_prefix == "p_" and what_type == "entity_type") then - return yl_speak_up.get_sub_fs_edit_option_precondition_entity_type( - pname, dialog, formspec, data, id_prefix, save_button, e, - values_trade, check_trade) - - -- "the inventory of the player", -- 5 - -- "the inventory of the NPC", -- 6 - -- "the inventory of a block somewhere", -- 7 - -- "put item from the NPC's inventory into a chest etc.", -- 4 (effect) - -- "take item from a chest etc. and put it into the NPC's inventory", -- 5 (effect) - -- (inventory - only for preconditions; effects have something else here) - elseif((data.what and id_prefix == "p_" - and (what_type == "player_inv" or what_type == "npc_inv" or what_type == "block_inv")) - or (data.what and id_prefix == "r_" - and (what_type == "put_into_block_inv" or what_type == "take_from_block_inv"))) then - -- the inventory of a block needs more input options (in particular block selection) - data.what_type = what_type - return yl_speak_up.get_sub_fs_edit_option_precondition_inv( - pname, dialog, formspec, data, id_prefix, save_button, e, - values_inv, check_inv, values_block) - - elseif(data.what and id_prefix == "r_" and what_type == "deal_with_offered_item") then - return yl_speak_up.get_sub_fs_edit_option_effect_deal_with_offered_item( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "give item (created out of thin air) to player (requires yl_speak_up.npc_privs_priv priv)", -- 9 - -- "take item from player and destroy it (requires yl_speak_up.npc_privs_priv priv)", -- 10 - elseif(data.what and id_prefix == "r_" and (what_type == "give_item" or what_type=="take_item")) then - return yl_speak_up.get_sub_fs_edit_option_effect_give_item_or_take_item( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "move the player to a given position (requires yl_speak_up.npc_privs_priv priv)", -- 11 - elseif(data.what and id_prefix == "r_" and what_type == "move") then - return yl_speak_up.get_sub_fs_edit_option_effect_move( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "execute Lua code (requires npc_master priv)", -- precondition: 8; effect: 12 - elseif((data.what and id_prefix == "p_" and what_type == "function") - or (data.what and id_prefix == "r_" and what_type == "function")) then - return yl_speak_up.get_sub_fs_edit_option_p_and_e_function( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "NPC crafts something", -- 6 - -- (craft - only for effects - not for preconditions) - elseif(data.what and id_prefix == "r_" and what_type == "craft") then - return yl_speak_up.get_sub_fs_edit_option_effect_craft( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "go to other dialog if the *previous* effect failed", -- 5 - -- (on_failure - only for effects - not for preconditions) - elseif(data.what and id_prefix == "r_" and what_type == "on_failure") then - return yl_speak_up.get_sub_fs_edit_option_effect_on_failure( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "send a chat message to all players" -- 8 - elseif(data.what and id_prefix == "r_" and what_type == "chat_all") then - return yl_speak_up.get_sub_fs_edit_option_effect_chat_all( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "Normal trade - one item(stack) for another item(stack).", -- 3 - elseif(data.what and id_prefix == "a_" and what_type == "trade") then - return yl_speak_up.get_sub_fs_edit_option_action_trade( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "The NPC gives something to the player (i.e. a quest item).", -- 4 - -- (only for actions) - elseif(data.what and id_prefix == "a_" and what_type == "npc_gives") then - return yl_speak_up.get_sub_fs_edit_option_action_npc_gives( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5 - -- (only for actions) - -- "an item the player offered/gave to the NPC", (as precondition) - elseif(data.what and ((id_prefix == "a_" and what_type == "npc_wants") - or (id_prefix == "p_" and what_type == "player_offered_item"))) then - return yl_speak_up.get_sub_fs_edit_option_action_npc_wants_or_accepts( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "The player has to manually enter a password or passphrase or some other text.", -- 6 - -- (only for actions) - elseif(data.what and id_prefix == "a_" and what_type == "text_input") then - return yl_speak_up.get_sub_fs_edit_option_action_text_input( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "Call custom functions that are supposed to be overridden by the server.", -- 7 - -- precondition: 9; action: 7; effect: 13 - elseif(data.what - and ((id_prefix == "a_" and what_type == "custom") - or (id_prefix == "p_" and what_type == "custom") - or (id_prefix == "r_" and what_type == "custom"))) then - return yl_speak_up.get_sub_fs_edit_option_all_custom( - pname, dialog, formspec, data, id_prefix, save_button, e) - - -- "The preconditions of another dialog option are fulfilled/not fulfilled.", -- 10 - -- precondition: 9 - elseif(data.what and id_prefix == "p_" and what_type == "other") then - return yl_speak_up.get_sub_fs_other_option_preconditions( - pname, dialog, formspec, data, id_prefix, save_button, e) - end - -- create a new precondition, action or effect - return formspec..save_button -end - - ----------------------------------------------------------------------------- --- begin of formspecs for types of preconditions, actions and effects - --- helper function for "state", "property" and "evaluate"; --- shows dropdown for operator and input field for comparison value var_cmp_value -yl_speak_up.get_sub_fs_operator_based_comparison = function(data, id_prefix, save_button, e, - values_operator, check_operator, - what_is_this, text_what_is_this, - text_select_operator, text_select_value) - if(e) then - data.operator = math.max(1,table.indexof(values_operator, e[ id_prefix.."operator" ])) - data.var_cmp_value = e[ id_prefix.."var_cmp_value" ] - end - if(not(data[what_is_this]) or data[what_is_this] == "" or tostring(data[what_is_this]) == -1 - or tostring(data[what_is_this]) == "0") then - -- not enough selected yet for saving - save_button = "" - elseif(not(data.operator) or data.operator == 1) then - data.operator = 1 - save_button = "" - end - local field_for_value = "field[11.7,4.8;7.5,0.6;var_cmp_value;;".. - minetest.formspec_escape(data.var_cmp_value or "- enter value -").."]" - -- do not show value input field for unary operators - -- (unary operators are diffrent for prerequirements and effects) - if(not(data.operator) - or (id_prefix == "p_" and (data.operator == 1 or (data.operator>=8 and data.operator<11))) - -- "unset", "set_to_current_time" - or (id_prefix == "r_" and (data.operator == 3 or data.operator == 4))) then - field_for_value = "label[11.7,5.1;- not used for this operator -]" - end - -- the list of available variables needs to be extended with the ones - -- the player has read access to, and the order has to be constant - -- (because dropdown just returns an index) - return "label[0.2,3.3;"..text_what_is_this.."]".. - "label[0.2,4.3;Name of "..what_is_this..":]".. - "label[7.0,4.3;"..text_select_operator.."]".. - "dropdown[7.0,4.8;4.5,0.6;select_operator;".. - table.concat(check_operator, ",")..";".. - tostring(data.operator)..";]".. - "label[11.7,4.3;"..text_select_value.."]".. - field_for_value.. - save_button -end - - --- "an internal state (i.e. of a quest)", -- 2 --- (state is the second offered option in both preconditions and effects list) -yl_speak_up.get_sub_fs_edit_option_p_and_e_state = function( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_variable, text_select_value, text_select_operator, - values_operator, check_operator, get_sorted_player_var_list_function ) - -- the list of available variables needs to be extended with the ones - -- the player has read access to, and the order has to be constant - -- (because dropdown just returns an index) - local var_list = get_sorted_player_var_list_function(pname) - local var_list_stripped = yl_speak_up.strip_pname_from_varlist(var_list, pname) - if(e) then - data.variable_name = yl_speak_up.strip_pname_from_var(e[ id_prefix.."variable" ], pname) - data.variable = table.indexof(var_list, e[ id_prefix.."variable"]) - end - if(not(data.variable) or data.variable < 1) then - data.variable = 0 - end - return formspec.. - yl_speak_up.get_sub_fs_operator_based_comparison(data, id_prefix, save_button, e, - values_operator, check_operator, "variable", text_variable, - text_select_operator, text_select_value).. - "dropdown[0.2,4.8;6.5,0.6;select_variable;".. - "- please select -"..var_list_stripped..";".. - tostring(data.variable + 1)..";]".. - "button[0.2,6.0;4.0,0.6;manage_variables;Manage variables]".. - "button[4.7,6.0;6.5,0.6;show_var_usage_edit_element;Show where this variable is used]".. - "hypertext[1.2,7.0;16.0,2.5;some_text;".. - "Note: Each variable is player-specific and will be set and ".. - "checked for the player that currently talks to your NPC.\n".. - "Note: You can set a variable to the current time in an effect. ".. - "After that, use a precondition to check if that variable was set \"more ".. - "than x seconds ago\" or \"less than x seconds ago\". This can be ".. - "useful for prevending your NPC from handing out the same quest item again ".. - "too quickly (players are inventive and may use your quest item for their ".. - "own needs).\n]" -end - - --- "the value of a property of the NPC (for generic NPC)" -yl_speak_up.get_sub_fs_edit_option_p_and_e_property = function( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_select_operator, values_operator, check_operator) - if(e) then - data.property = e[ id_prefix.."value"] - end - local operator_list = {} - for i, v in ipairs(check_operator) do - local v2 = values_operator[i] - if( v2 ~= "quest_step_done" and v2 ~= "quest_step_not_done" - and v2 ~= "true_for_param" and v2 ~= "false_for_param") then - table.insert(operator_list, v) - end - end - local text_compare_with = "Compare property with this value:" - if(id_prefix == "r_") then - text_select_operator = "Set property to:" - text_compare_with = "New value:" - end - -- the list of available variables needs to be extended with the ones - return formspec.. - yl_speak_up.get_sub_fs_operator_based_comparison(data, id_prefix, save_button, e, - values_operator, operator_list, "property", - "The NPC shall have the following property:", - text_select_operator, text_compare_with).. - "field[1.0,4.8;5.0,0.6;property;;".. - minetest.formspec_escape(data.property or "- enter name -").."]".. - "hypertext[1.2,7.0;16.0,2.5;some_text;".. - "Note: Properties are useful for NPC that have a generic ".. - "behaviour and may vary their behaviour slightly.\n".. - "Properties starting with \"server\" can only be set or changed by ".. - "players with the \"npc_talk_admin\" privilege.".. - "]" -end - - --- "something that has to be calculated or evaluated (=call a function)" -yl_speak_up.get_sub_fs_edit_option_p_and_e_evaluate = function( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_select_operator, values_operator, check_operator) - local fun_list = {} - for k, v in pairs(yl_speak_up["custom_functions_"..id_prefix]) do - table.insert(fun_list, v["description"] or k) - end - table.sort(fun_list) - local func_selected = 0 - - local func_data = nil - if(e) then - --data.function_name = e[ id_prefix.."value"] - data.function_name = e[ id_prefix.."value"] - for i = 1, 9 do - local s = "param"..tostring(i) - if(e[id_prefix..s]) then - data[s] = e[id_prefix..s] - end - end - end - local add_description = "Nothing selected." - if(data.function_name) then - func_data = yl_speak_up["custom_functions_"..id_prefix][data.function_name] - -- add the fields for param1..param9: - if(func_data) then - local xoff = 0 - for i = 1, 9 do - if(i > 5) then - xoff = 10 - end - local paramn = "param"..tostring(i) - local s = func_data[paramn.."_text"] - if(s) then - formspec = formspec.. - "label["..(0.2 + xoff)..","..(6.05 + ((i-1)%5)*0.8)..";".. - minetest.formspec_escape(s).."]".. - "field["..(4.0 + xoff)..","..(5.8 + ((i-1)%5)*0.8).. - ";5.0,0.6;set_"..paramn..";;".. - minetest.formspec_escape( - data[paramn] or "").."]".. - "tooltip[set_"..paramn..";".. - minetest.formspec_escape( - func_data[paramn.."_desc"] or "?").."]" - end - end - func_selected = table.indexof(fun_list, func_data["description"]) - add_description = func_data["description"] - -- necessary so that the save_button can be shown - data["function"] = func_selected - end - end - local operator_list = {} - for i, v in ipairs(check_operator) do - local v2 = values_operator[i] - if( v2 ~= "quest_step_done" and v2 ~= "quest_step_not_done" - and v2 ~= "true_for_param" and v2 ~= "false_for_param") then - table.insert(operator_list, v) - end - end - local text_operator_and_comparison = "" - local explanation = "" - local dlength = "6.5" - if(id_prefix == "p_") then - text_operator_and_comparison = yl_speak_up.get_sub_fs_operator_based_comparison( - data, id_prefix, save_button, e, - values_operator, operator_list, "function", - "Execute and evaluate the following function:", - "Operator for checking result:", "Compare the return value with this value:") - explanation = - "Note: Functions are called with parameters which are passed on to them. ".. - "The function then calculates a result. This result can be compared to a given ".. - "value. What the function calculates and what it returns depends on its ".. - "implementation." - else - dlength = "15" -- we have more room for the dropdown here - if(not(data["function"]) or data["function"]=="") then - save_button = "" - end - text_operator_and_comparison = - "label[0.2,3.3;Execute the following function:]".. - "label[0.2,4.3;Name of function:]".. - save_button - explanation = - "Note: Functions are called with parameters which are passed on to them. ".. - "Functions used as effects/results ought to change something, i.e. set a ".. - "variable to a new value." - if(id_prefix == "a_") then - explanation = - "Note: Functions are called with parameters which are passed on to ".. - "them. Functions used as actions need to return a valid formspec. This ".. - "formspec is then displayed to the player. The clicks the player does in ".. - "that formspec are sent to another custom function linked to it." - end - end - -- the list of available variables needs to be extended with the ones - return formspec.. - text_operator_and_comparison.. - -- show the description of the function again (the space in the dropdown menu is a bit - -- limited) - "label[7.5,3.3;"..minetest.formspec_escape(add_description).."]".. - "dropdown[0.2,4.8;"..dlength..",0.6;select_function_name;".. - "- please select -,"..table.concat(fun_list, ",")..";".. - tostring(func_selected + 1)..";]".. - "hypertext[1.2,9.6;16.0,2.5;some_text;".. - explanation.. - "]" -end - - --- helper function for: --- yl_speak_up.get_sub_fs_edit_option_p_and_e_block -yl_speak_up.get_block_pos_info = function(pname, data, id_prefix, e, values_block, ignore_protection) - -- are we more intrested in the inventory of the block or in the block itself? - local looking_at_inventory = false - if(data and data.what_type - and (data.what_type == "block_inv" - or data.what_type == "put_into_block_inv" - or data.what_type == "take_from_block_inv")) then - looking_at_inventory = true - end - -- did the player get here through punching a block in the meantime? - local block_pos = yl_speak_up.speak_to[pname].block_punched - yl_speak_up.speak_to[pname].block_punched = nil - if(e and e[id_prefix.."pos"]) then - -- if we are not looking for the inventory of a block: - if(looking_at_inventory) then - data.block = math.max(1,table.indexof(values_block, e[ id_prefix.."value" ])) - end - data.node_data = {} - data.node_data.data = e[ id_prefix.."node" ] - data.node_data.param2 = e[ id_prefix.."param2" ] - data.block_pos = {x=e[ id_prefix.."pos" ].x, - y=e[ id_prefix.."pos" ].y, - z=e[ id_prefix.."pos" ].z} - -- the block below was punched - if(id_prefix == "p_" and data.block == 5) then - data.block_pos.y = data.block_pos.y - 1 - end - end - local block_pos_str = "- none set -" - local node = {name = "- unknown -", param2 = "- unkown -"} - if(not(block_pos) and data and data.block_pos) then - block_pos = data.block_pos - end - local error_is_protected = "" - if(block_pos) then - -- store for later usage - data.block_pos = block_pos - local tmp_pos = {x=block_pos.x, y=block_pos.y, z=block_pos.z} - -- "I can't punch it. The block is as the block *above* the one I punched.", - -- (only valid for preconditions; not for effects - because the player and - -- his NPC need to be able to build there) - if(data.block and id_prefix == "p_" and data.block == 5) then - tmp_pos.y = block_pos.y + 1 - end - -- effects (and, likewise, preconditions): the player at least has to be able to - -- build at that position - check that - if(not(ignore_protection) and minetest.is_protected(tmp_pos, pname)) then - error_is_protected = "label[0.2,7.8;Error: ".. - "The position you punched is protected. It cannot be used by ".. - "your NPC for checks or building. Please select a diffrent block!]" - block_pos = nil - data.block_pos = nil - else - block_pos_str = minetest.pos_to_string(tmp_pos) - node = minetest.get_node_or_nil(tmp_pos) - if(not(node)) then - node = {name = "- unknown -", param2 = "- unkown -"} - end - -- "There shall be air instead of this block.", - -- (only valid for preconditions) - if(data.block and id_prefix == "p_" and data.block == 3) then - node = {name = "air", param2 = 0} - end - -- cache that (in case a sapling grows or someone else changes it) - data.node_data = node - end - end - local show_save_button = true - if(node.name == "- unknown -") then - show_save_button = false - end - -- if we are dealing with the *inventory* of a block, the state of the block is of no intrest here - if(not(looking_at_inventory) and (not(data.block) or data.block == 1)) then - data.block = 1 - -- not enough selected yet for saving - show_save_button = false - end - - return {block_pos = block_pos, block_pos_str = block_pos_str, node = node, - error_is_protected = error_is_protected, - show_save_button = show_save_button} -end - - - --- "a block somewhere", -- 3 --- (block is the third offered option in both preconditions and effects list) -yl_speak_up.get_sub_fs_edit_option_p_and_e_block = function( - pname, dialog, formspec, data, id_prefix, save_button, e, - text_block_position, values_block, check_block) - - local res = yl_speak_up.get_block_pos_info(pname, data, id_prefix, e, values_block, false) - if(not(res.show_save_button)) then - save_button = "" - end - return formspec.. - "label[0.2,3.3;"..text_block_position.."]".. - "dropdown[4.0,3.5;16.0,0.6;select_block;".. - table.concat(check_block, ",")..";".. - tostring(data.block)..";]".. - "label[0.2,4.8;Position of the block:]".. - "label[4.0,4.8;"..minetest.formspec_escape(res.block_pos_str).."]".. - "label[0.2,5.8;Name of block:]".. - "label[4.0,5.8;"..minetest.formspec_escape(res.node.name).."]".. - "label[0.2,6.8;Orientation (param2):]".. - "label[4.0,6.8;"..minetest.formspec_escape(res.node.param2).."]".. - "button_exit[10.0,5.5;4.0,0.7;select_block_pos;Set position of block]".. - "tooltip[select_block_pos;Click on this button to select a block.\n".. - "This menu will close and you will be asked to punch\n".. - "the block at the position you want to check or change.\n".. - "After punching it, you will be returned to this menu.]".. - res.error_is_protected.. - save_button -end - - --- "a trade", -- 4 --- (trade - only for preconditions; effects have something else here) -yl_speak_up.get_sub_fs_edit_option_precondition_trade = function( - pname, dialog, formspec, data, id_prefix, save_button, e, - values_trade, check_trade) - if(e) then - data.trade = math.max(1,table.indexof(values_trade, e[ "p_value" ])) - end - if(not(data.trade) or data.trade == 1) then - data.trade = 1 - -- not enough selected yet for saving - save_button = "" - end - return formspec.. - "label[0.2,3.3;If the action is a trade, the following shall be true:]".. - "dropdown[4.0,3.5;16.0,0.6;select_trade;".. - table.concat(check_trade, ",")..";".. - tostring(data.trade)..";]".. - save_button -end - - --- "the type of the entity of the NPC", --- (entity_type - only for preconditions) -yl_speak_up.get_sub_fs_edit_option_precondition_entity_type = function( - pname, dialog, formspec, data, id_prefix, save_button, e, - values_trade, check_trade) - if(e) then - data.entity_type = e[ "p_value" ] - end - if(not(data.entity_type) or data.entity_type == "") then - -- get the name/type of the current entity - if(yl_speak_up.speak_to[pname].obj) then - local obj = yl_speak_up.speak_to[pname].obj - if(obj) then - local entity = obj:get_luaentity() - if(entity) then - data.entity_type = entity.name - end - end - end - end - return formspec.. - "label[0.2,3.3;The entity (this NPC) is of type:]".. - "field[5.0,3.0;6.0,0.6;entity_type;;"..(data.entity_type or "").."]".. - "label[0.2,4.3;Note: This is only really useful for generic NPCs.]".. - save_button -end - - --- "the inventory of the player", -- 5 --- "the inventory of the NPC", -- 6 --- "the inventory of a block somewhere", -- 7 --- "put item from the NPC's inventory into a chest etc.", -- 4 (effect) --- "take item from a chest etc. and put it into the NPC's inventory", -- 5 (effect) --- (inventory - only for preconditions; effects have something else here) -yl_speak_up.get_sub_fs_edit_option_precondition_inv = function( - pname, dialog, formspec, data, id_prefix, save_button, e, - values_inv, check_inv, values_block) - if(e) then - data.inv = math.max(1,table.indexof(values_inv, e["p_value"])) - data.inv_stack_name = e[ id_prefix.."itemstack" ] - end - if(id_prefix == "p_" and (not(data.inv) or data.inv == 1)) then - data.inv = 1 - -- not enough selected yet for saving - save_button = "" - end - local block_selection = "" - if(data and data.what_type - and (data.what_type == "block_inv" - or data.what_type == "put_into_block_inv" - or data.what_type == "take_from_block_inv")) then - local inv_list_name = "" - if(e) then - -- not really relevant here but needed for getting the position - e[ id_prefix.."value" ] = "node_is_like" - inv_list_name = e[ id_prefix.."inv_list_name"] - end - -- positions of nodes in protected areas are allowed for inventory access - local res = yl_speak_up.get_block_pos_info(pname, data, id_prefix, e, values_block, true) - if(not(res.show_save_button)) then - save_button = "" - end - -- which inventory lists are available? - local tmp = yl_speak_up.get_node_inv_lists(res.block_pos, inv_list_name) - block_selection = "".. - "label[0.2,7.0;Position of the block:]".. - "label[4.0,7.0;"..minetest.formspec_escape(res.block_pos_str).."]".. - "label[0.2,7.5;Name of block:]".. - "label[4.0,7.5;"..minetest.formspec_escape(res.node.name).."]".. - "label[0.2,8.0;Orientation (param2):]".. - "label[4.0,8.0;"..minetest.formspec_escape(res.node.param2).."]".. - "label[0.2,8.5;Inventory list name:]".. - "dropdown[4.0,8.2;3.8,0.6;inv_list_name;".. - table.concat(tmp.inv_lists, ",")..";".. - tostring(tmp.index)..";]".. - "button_exit[0.2,9.0;4.0,0.7;select_block_pos;Set position of block]".. - "tooltip[select_block_pos;Click on this button to select a block.\n".. - "This menu will close and you will be asked to punch\n".. - "the block at the position you want to check or change.\n".. - "After punching it, you will be returned to this menu.]" - end - local intro = "" - -- for preconditions: contain/does not contain item, is empty, .. - if(id_prefix == "p_") then - intro = "label[0.2,3.0;The following shall be true about the inventory:]".. - "dropdown[4.0,3.2;16.0,0.6;select_inv;".. - table.concat(check_inv, ",")..";".. - tostring(data.inv)..";]" - -- for results/effects: - elseif(data.what_type == "put_into_block_inv") then - intro = "label[0.2,3.0;The NPC shall put the following item from his inventory ".. - "into the given block's inventory:]" - elseif(data.what_type == "take_from_block_inv") then - intro = "label[0.2,3.0;The NPC shall take the following item from the given block's ".. - "inventory and put it into his own inventory:]" - end - return formspec.. - intro.. - yl_speak_up.fs_your_inventory_select_item(pname, data).. - block_selection.. - save_button -end - - --- "an item the player offered to the NPC" -yl_speak_up.get_sub_fs_edit_option_effect_deal_with_offered_item = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - data.select_deal_with_offered_item = table.indexof( - yl_speak_up.dropdown_values_deal_with_offered_item, - e[ "r_value" ]) - end - if(not(data) or not(data.select_deal_with_offered_item) - or data.select_deal_with_offered_item < 2) then - save_button = "" - data.select_deal_with_offered_item = 1 - end - return formspec.. - "label[0.2,3.3;The NPC shall:]".. - "dropdown[4.0,3.0;15.0,0.7;select_deal_with_offered_item;".. - table.concat(yl_speak_up.dropdown_list_deal_with_offered_item, ",")..";".. - tostring(data.select_deal_with_offered_item)..";]".. - save_button -end - - --- "give item (created out of thin air) to player (requires yl_speak_up.npc_privs_priv priv)", -- 9 --- "take item from player and destroy it (requires yl_speak_up.npc_privs_priv priv)", -- 10 -yl_speak_up.get_sub_fs_edit_option_effect_give_item_or_take_item = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - data.inv_stack_name = e[ "r_value" ] or "" - end - local text = "The following item shall be created out of thin air and added to the ".. - "player's inventory:" - local priv_name = "effect_give_item" - if(data.what == 10) then - text = "The following item shall be removed from the player's inventory and ".. - "be destroyed:" - priv_name = "effect_take_item" - end - return formspec.. - "label[0.2,3.0;"..text.."]".. - "label[0.2,3.5;Note: You can *save* this effect only if you have the ".. - "\""..tostring(yl_speak_up.npc_privs_priv).."\" priv!]".. - "label[0.2,8.0;".. - "And in order to be able to execute it, this NPC\n".. - "needs the \""..tostring(priv_name).."\" priv.\n\t".. - "Type \"/npc_talk_privs grant "..tostring(yl_speak_up.speak_to[pname].n_id).. - " "..tostring(priv_name).."\"\nin order to grant this.]".. - yl_speak_up.fs_your_inventory_select_item(pname, data).. - save_button -end - - --- "move the player to a given position (requires yl_speak_up.npc_privs_priv priv)", -- 11 -yl_speak_up.get_sub_fs_edit_option_effect_move = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - if(e[ "r_value"] and type(e[ "r_value" ]) == "string") then - local pos = minetest.string_to_pos(e[ "r_value" ]) - if(pos) then - data.move_to_x = pos.x - data.move_to_y = pos.y - data.move_to_z = pos.z - end - end - end - return formspec.. - "label[0.2,3.0;Move the player to this position:]".. - "label[0.2,3.5;Note: You can *save* this effect only if you have the ".. - "\""..tostring(yl_speak_up.npc_privs_priv).."\" priv!\n".. - "And in order to be able to execute it, this NPC needs the \"".. - "effect_move_player\" priv.\n\t".. - "Type \"/npc_talk_privs grant "..tostring(yl_speak_up.speak_to[pname].n_id).. - " effect_move_player\" in order to grant this.]".. - "label[0.2,5.3;X:]".. - "label[3.7,5.3;Y:]".. - "label[7.2,5.3;Z:]".. - "field[0.7,5.0;2.0,0.6;move_to_x;;"..(data.move_to_x or "").."]".. - "field[4.2,5.0;2.0,0.6;move_to_y;;"..(data.move_to_y or "").."]".. - "field[7.7,5.0;2.0,0.6;move_to_z;;"..(data.move_to_z or "").."]".. - save_button -end - - --- "execute Lua code (requires npc_master priv)", -- precondition: 8; effect: 12 -yl_speak_up.get_sub_fs_edit_option_p_and_e_function = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - if(e[ id_prefix.."value"] and e[ id_prefix.."value"] ~= "") then - data.lua_code = e[ id_prefix.."value" ] - end - end - local priv_name = "precon_exec_lua" - if(id_prefix == "_r") then - priv_name = "effect_exec_lua" - end - return formspec.. - "label[0.2,3.0;Execute the following Lua code (ought to return true or false):]".. - "label[0.2,3.5;Note: You can *save* this effect only if you have the ".. - "\"npc_master\" priv!\n".. - "And in order to be able to execute it, this NPC needs the \"".. - tostring(priv_name).."\" priv.\n\t".. - "Type \"/npc_talk_privs grant "..tostring(yl_speak_up.speak_to[pname].n_id).. - " "..tostring(priv_name).."\" in order to grant this.]".. - "textarea[0.2,5.0;20,4.0;lua_code;;".. - minetest.formspec_escape(tostring(data.lua_code)).."]".. - save_button -end - - --- "NPC crafts something", -- 6 --- (craft - only for effects - not for preconditions) -yl_speak_up.get_sub_fs_edit_option_effect_craft = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - -- those items can at least be shown as background images - data.craftresult = e[ "r_value" ] - data.craft_grid = e[ "r_craft_grid"] - end - local bg_img = "" - if(data and data.craftresult and data.craft_grid) then - bg_img = "item_image[5.95,8.70;0.7,0.7;"..tostring(data.craftresult).."]".. - "image[4.6,8.6;1,1;gui_furnace_arrow_bg.png^[transformR270]" - for i, v in ipairs(data.craft_grid) do - if(v and v ~= "") then - bg_img = bg_img.."item_image[".. - tostring(1.15 + ((i-1)%3)*1.25)..",".. - tostring(8.15 + math.floor((i-1)/3)*0.65).. - ";0.7,0.7;"..tostring(v).."]" - end - end - end - return formspec.. - "label[8,2.6;Your invnetory:]".. - "list[current_player;main;8,3;8,4;]".. - "label[1,3.1;Your craft grid:]".. - "list[current_player;craft;1,3.5;3,3;]".. - "list[current_player;craftpreview;5.8,4.75;1,1;]".. - "image[4.6,4.8;1,1;gui_furnace_arrow_bg.png^[transformR270]".. - "label[1,8.0;Use your craft grid to show your NPC what to craft ".. - "and how. Click on \"Save\" to save. Currently stored:]".. - bg_img.. - save_button -end - - --- "go to other dialog if the *previous* effect failed", -- 5 --- (on_failure - only for effects - not for preconditions) -yl_speak_up.get_sub_fs_edit_option_effect_on_failure = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - data.on_failure = e[ "r_value" ] - data.alternate_text = e[ "alternate_text" ] - end - local dialog = yl_speak_up.speak_to[pname].dialog - local sorted_dialog_list = yl_speak_up.get_sorted_dialog_name_list(dialog) - local nr = 1 - if(not(data) or not(data.on_failure) - or not(dialog.n_dialogs) - or not(dialog.n_dialogs[data.on_failure])) then - save_button = "" - else - local t = dialog.n_dialogs[data.on_failure].d_name or data.on_failure - nr = math.max(0, table.indexof(sorted_dialog_list, t)) - end - local on_failure_dialog = "" - if(dialog and dialog.n_dialogs and dialog.n_dialogs[ data.on_failure ]) then - on_failure_dialog = - "label[0.2,5.5;This will switch to dialog \"".. - minetest.formspec_escape(tostring(data.on_failure)).."\"".. - yl_speak_up.show_colored_dialog_text( - dialog, - data, - data.on_failure, - "1.2,5.8;18.0,2.0;d_text", - ", but with the following *modified* text", - ":]", - "button_edit_effect_on_failure_text_change") - end - return formspec.. - "label[0.2,3.3;If the *previous* effect failed,]".. - "label[0.2,3.8;switch to the following dialog:]".. - "dropdown[5.0,3.5;6.5,0.6;select_on_failure;".. - table.concat(sorted_dialog_list, ",")..";".. - tostring(nr)..";]".. - on_failure_dialog.. - save_button -end - - --- "send a chat message to all players" -- 8 -yl_speak_up.get_sub_fs_edit_option_effect_chat_all = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - data.chat_msg_text = e[ "r_value" ] - end - local default_text = "$NPC_NAME$ (owned by $OWNER_NAME$) announces: $PLAYER_NAME$ ".. - "- example; please enter the text -" - return formspec.. - "label[0.2,3.3;Send the following chat message to *all* players:]".. - "label[0.2,4.1;Message:]".. - "field[2.0,3.8;16.0,0.6;chat_msg_text;;".. - minetest.formspec_escape( - data.chat_msg_text - or default_text).."]".. - "label[0.2,5.3;Note: Your chat message needs to contain the following placeholders,".. - " which will be replaced automaticly like in dialog texts:".. - "\n$NPC_NAME$, $PLAYER_NAME$ and $OWNER_NAME$.]".. - save_button -end - - --- "Normal trade - one item(stack) for another item(stack).", -- 3 -yl_speak_up.get_sub_fs_edit_option_action_trade = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - data.trade_id = e[ "a_value" ] - -- use as background images - if(dialog and dialog.trades and dialog.trades[ data.trade_id ]) then - data.pay = dialog.trades[ data.trade_id ].pay[1] - data.buy = dialog.trades[ data.trade_id ].buy[1] - end - data.action_failure_dialog = e[ "a_on_failure" ] - end - local dialog = yl_speak_up.speak_to[pname].dialog - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - if(not(data.trade_id)) then - data.trade_id = tostring(d_id).." "..tostring(o_id) - end - -- show the player which trade is stored - local bg_img = "" - if(data and data.buy and data.pay) then - bg_img = "item_image[1.15,4.35;0.7,0.7;"..tostring(data.pay).."]".. - "item_image[6.15,4.35;0.7,0.7;"..tostring(data.buy).."]" - end - yl_speak_up.speak_to[pname].trade_id = data.trade_id - return formspec.. - "label[8,2.6;Your invnetory:]".. - "list[current_player;main;8,3;8,4;]".. - "label[0.2,3.1;Configure trade with "..minetest.formspec_escape(dialog.n_npc)..":]".. - "label[0.5,3.8;The customer pays:]".. - -- show the second slot of the setup inventory in the detached player's inv - "list[detached:yl_speak_up_player_"..pname..";setup;2,4.2;1,1;]".. - "image[3.5,4.2;1,1;gui_furnace_arrow_bg.png^[transformR270]".. - "label[4.0,3.8;"..minetest.formspec_escape(dialog.n_npc or "?").." sells:]".. - -- show the second slot of said inventory - "list[detached:yl_speak_up_player_"..pname..";setup;5,4.2;1,1;1]".. - bg_img.. - yl_speak_up.set_on_action_failure_dialog(pname, data, - "The player shall trade at least once.").. - save_button -end - - --- "The NPC gives something to the player (i.e. a quest item).", -- 4 --- (only for actions) -yl_speak_up.get_sub_fs_edit_option_action_npc_gives = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - local bg_img = "" - if(e) then - data.item_quest_id = data.item_quest_id or e["item_quest_id"] - data.item_desc = data.item_desc or e["item_desc"] - end - if(data and (data.item_node_name or data.item_string)) then - bg_img = "item_image[1.15,3.65;0.7,0.7;".. - tostring(data.item_node_name or data.item_string).."]" - end - return formspec.. - "label[8,2.6;Your inventory:]".. - "list[current_player;main;8,3;8,4;]".. - "label[1,3.1;"..minetest.formspec_escape(dialog.n_npc or "?").." gives:]".. - "list[detached:yl_speak_up_player_"..pname..";npc_gives;2,3.5;1,1;]".. - "label[3.2,4.0;".. - minetest.formspec_escape( - data.item_node_name - or "- no item set -").."]".. - "label[0.2,5.6;Set a description to turn the item into a special\n".. - "quest item. Set a special ID (short text) so that\n".. - "the player cannot create a fake item. Click on \n".. - "\"Save\" to apply the changes.\n".. - "You can use placeholders like $PLAYER_NAME$ etc.]".. - "label[0.2,8.3;Special ID to set:]".. - "field[3.2,8.0;14.5,0.6;action_item_quest_id;;".. - minetest.formspec_escape( - data.item_quest_id - or "- none set -").."]".. - "tooltip[action_item_quest_id;".. - "Set this to a text that helps *you* to remember what this\n".. - "special quest item is for (i.e. \"quest_deliver_augusts_".. - "letter\").\n".. - "The ID will be extended with the ID of the NPC and the\n".. - "name of the player who got this item from the NPC.]".. - "label[0.2,9.0;Description to set:]".. - "field[3.2,8.7;14.5,0.6;action_item_desc;;".. - minetest.formspec_escape( - data.item_desc - or "- no item set -").."]".. - "tooltip[action_item_desc;".. - "Set this to a text that helps the *player* to remember what\n".. - "this special quest item is for (i.e. \"Letter from August to\n".. - "Frederike\" for a piece of paper).\n".. - "This description is shown in the inventory on mouseover.]".. - bg_img.. - yl_speak_up.set_on_action_failure_dialog(pname, data, - "The player shall take this offered item.").. - save_button -end - - --- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5 --- (only for actions) --- "an item the player offered/gave to the NPC", (as precondition) -yl_speak_up.get_sub_fs_edit_option_action_npc_wants_or_accepts = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - local bg_img = "" - local node_name = "" - if(e) then - data.item_quest_id = data.item_quest_id or e["item_quest_id"] - data.item_desc = data.item_desc or e["item_desc"] - data.item_group = data.item_group or e["item_group"] - data.item_stack_size = data.item_stack_size or e["item_stack_size"] - data.match_stack_size = data.match_stack_size or e["match_stack_size"] - end - if(data and (data.item_node_name or data.item_string)) then - node_name = tostring(data.item_node_name or data.item_string) - bg_img = "item_image[1.15,3.65;0.7,0.7;"..node_name.."]" - end - local info_text = "" - if(id_prefix == "p_") then - local group_list = {minetest.formspec_escape("- no, just this one item -")} - -- get node name without amount - local parts = node_name:split(" ") - local nr = 1 - local count = 1 - local amount = tostring(1) - -- prepare group_list - if(data and parts and minetest.registered_items[ parts[1] ]) then - for k,v in pairs(minetest.registered_items[ parts[1] ].groups) do - table.insert(group_list, k) - count = count + 1 - if(data.item_group and data.item_group == k) then - nr = count - end - end - amount = tostring(parts[2]) - end - local size_list = {"any amount", "exactly "..amount, - "less than "..amount, "more than "..amount, "another amount than "..amount} - local match_size = 1 - for i, list_text in ipairs(size_list) do - if(data.match_stack_size and data.match_stack_size == list_text:split(" ")[ 1 ]) then - match_size = i - end - end - if(data) then - data.item_stack_size = amount - end - info_text = - "label[1,2.6;The player offered:]".. - "label[6.7,3.1;of:]".. - "dropdown[2,2.8;4.5,0.6;select_match_stack_size;".. - table.concat(size_list, ",")..";".. - tostring(match_size or 1)..";]".. - "label[1,4.8;...and also all other items of the group:]".. - "dropdown[2,5.1;5.0,0.6;select_accept_group;".. - table.concat(group_list, ",")..";"..tostring(nr)..";]" - else - info_text = - "label[1,3.1;"..minetest.formspec_escape(dialog.n_npc or "?").." wants:]".. - yl_speak_up.set_on_action_failure_dialog(pname, data, - "The player shall give the NPC this item.") - end - return formspec.. - "label[8,2.6;Your inventory:]".. - "list[current_player;main;8,3;8,4;]".. - "list[detached:yl_speak_up_player_"..pname..";npc_wants;2,3.5;1,1;]".. - "label[3.2,4.0;".. - minetest.formspec_escape( - node_name - or "- no item set -").."]".. - "label[0.2,6.1;If you want a special ID and description, create\n".. - "those via the \"NPC gives something to the player\"\n".. - "menu option first and insert that item here. Don't\n".. - "use other placeholders than $PLAYER_NAME$ for this!]".. - "label[0.2,8.3;Expected special ID:]".. - "label[4.0,8.3;".. - minetest.formspec_escape( - data.item_quest_id - or "- none set -").."]".. - "label[0.2,9.0;Expected description:]".. - "label[4.0,9.0;".. - minetest.formspec_escape( - data.item_desc - or "- none set -").."]".. - bg_img.. - info_text.. - save_button -end - - --- "The player has to manually enter a password or passphrase or some other text.", -- 6 --- (only for actions) -yl_speak_up.get_sub_fs_edit_option_action_text_input = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - data.quest_question = e[ "a_question" ] - data.quest_answer = e[ "a_value" ] - data.action_failure_dialog = e[ "a_on_failure" ] - end - return formspec.. - "label[0.2,3.3;What to ask the player and which answer to expect:]".. - "label[0.2,4.0;Question to show:]".. - "field[4.0,3.8;10.0,0.6;quest_question;;".. - minetest.formspec_escape( - data.quest_question - or "Your answer:").."]".. - "label[0.2,5.0;Expected answer:]".. - "field[4.0,4.8;10.0,0.6;quest_answer;;".. - minetest.formspec_escape( - data.quest_answer - or "- Insert the correct answer here -").."]".. - "tooltip[quest_question;".. - "This is just a short text that will be shown to remind\n".. - "the player what he is asked for. Most of the question\n".. - "ought to be part of the normal dialog of the NPC.]".. - "tooltip[quest_answer;".. - "The correct answer will not be shown to the player.\n".. - "What the player enters will be compared to this\n".. - "correct value.]".. - "tooltip[select_on_action_failure;".. - "If the player gives the wrong answer, you can show him\n".. - "a diffrent target dialog (i.e. with text \"No, that answer\n".. - "was wrong, but please try again!\"). In such a case the\n".. - "effects/results of the current dialog option are *not*\n".. - "executed.]".. - yl_speak_up.set_on_action_failure_dialog(pname, data, - "The player shall enter the correct answer.").. - save_button -end - - --- "Call custom functions that are supposed to be overridden by the server.", -- 7 --- precondition: 9; action: 7; effect: 13 -yl_speak_up.get_sub_fs_edit_option_all_custom = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - if(e) then - data.custom_param = e[ id_prefix.."value" ] - if(id_prefix == "a_") then - data.action_failure_dialog = e[ "a_on_failure" ] - end - end - formspec = formspec.. - "label[0.2,3.3;Note: Calling a custom function will require direct support ".. - "from the server.]".. - "label[0.2,4.0;Parameter for custom function:]".. - "field[6.0,3.7;10.0,0.6;custom_param;;".. - minetest.formspec_escape( - data.custom_param - or "- Insert a text that is passed on to your function here -").."]".. - "tooltip[custom_param;".. - "The custom parameter may help whoever implements the\n".. - "custom function to more easily see what it belongs to.\n".. - "Dialog and option ID are also passed as parameters.]" - if(id_prefix == "a_") then - formspec = formspec.. - "tooltip[select_on_action_failure;".. - "If the player gives the wrong answer, you can show him\n".. - "a diffrent target dialog (i.e. with text \"No, that answer\n".. - "was wrong, but please try again!\"). In such a case the\n".. - "effects/results of the current dialog option are *not*\n".. - "executed.]".. - yl_speak_up.set_on_action_failure_dialog(pname, data, - "The player shall click on the right button.") - else - formspec = formspec.. - "label[0.3,5.0;Note: Your custom function has to return either true ".. - "or false.]" - end - return formspec..save_button -end - - --- "The preconditions of another dialog option are fulfilled/not fulfilled.", -- 10 --- precondition: 10 -yl_speak_up.get_sub_fs_other_option_preconditions = function( - pname, dialog, formspec, data, id_prefix, save_button, e) - local dialog = yl_speak_up.speak_to[pname].dialog - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - -- only o_id with a *lower* o_sort value are suitable (else evaluation would become - -- difficult and loops might be created) - local o_id_list = {} - local options = dialog.n_dialogs[ d_id ].d_options - if(options) then - local this_option = options[ o_id ] - if(not(this_option) or not(this_option.o_sort)) then - this_option = {o_sort = 0} - end - for k, v in pairs(options) do - if(k and v and v.o_sort and v.o_sort < this_option.o_sort) then - table.insert(o_id_list, minetest.formspec_escape(k)) - end - end - end - if(e) then - data.other_o_id = e[ "p_value" ] - data.fulfilled = e[ "p_fulfilled" ] - end - local nr = math.max(0, table.indexof(o_id_list, data.other_o_id)) - nr_fulfilled = 1 - if(data.fulfilled == "true") then - nr_fulfilled = 2 - elseif(data.fulfilled == "false") then - nr_fulfilled = 3 - end - if(nr == 0 or nr_fulfilled == 1) then - save_button = "" - end - return formspec.. - "label[0.2,3.3;Note: You can only select dialog options with a *lower* o_sort value ".. - "for this evaluation.]".. - "label[0.2,4.0;The preconditions of dialog option:]".. - "dropdown[6.0,3.7;3.0,0.6;select_other_o_id;-select-,".. - table.concat(o_id_list, ",")..";".. - tostring(nr + 1)..";]".. - "label[9.2,4.0;..shall be:]".. - "dropdown[11,3.7;2.0,0.6;select_fulfilled;-select-,true,false;".. - tostring(nr_fulfilled).."]".. - "tooltip[select_other_o_id;".. - "Sometimes you may need the same preconditions for more than\n".. - "one dialog option - or you may need one dialog option to be\n".. - "available exactly when another one is *not* available.\n".. - "This is what you can do here.]".. - "tooltip[select_fulfilled;".. - "If you select \"true\" here, then this precondition will be\n".. - "fulfilled when all the preconditions of the dialog option you\n".. - "selected here are true as well.\n".. - "If you select \"false\", this precondition will only be\n".. - "fulfilled if the other dialog option you selected here\n".. - "is not true.]".. - save_button -end - - --- end of formspecs for types of preconditions, actions and effects ----------------------------------------------------------------------------- - --- helper function -yl_speak_up.set_on_action_failure_dialog = function(pname, data, instruction) - local dialog = yl_speak_up.speak_to[pname].dialog - local nr = 1 - - local sorted_dialog_list = yl_speak_up.get_sorted_dialog_name_list(dialog) - if(data and data.action_failure_dialog - and dialog.n_dialogs - and dialog.n_dialogs[data.action_failure_dialog]) then - local t = dialog.n_dialogs[data.action_failure_dialog].d_name or data.action_failure_dialog - nr = math.max(0, table.indexof(sorted_dialog_list, t)) + 1 - end - local start_at = "9.9;" - if(nr and nr > 1) then - start_at = "9.7;" - end - local on_failure_dialog = - "label[0.2,"..start_at..tostring(instruction).." If he doesn't, go to dialog:]".. - "dropdown[11,9.6;8.0,0.6;select_on_action_failure;".. - "- current one -,".. - table.concat(sorted_dialog_list, ",")..";"..tostring(nr)..";]" - if(nr and nr > 1) then - return on_failure_dialog.. - yl_speak_up.show_colored_dialog_text( - dialog, - data, - sorted_dialog_list[ nr - 1], - "1.2,10.2;18.0,1.8;d_text", - "label[0.2,10.1;...and show the following *modified* text:]", - "", - "button_edit_action_on_failure_text_change") - end - return on_failure_dialog -end - - -yl_speak_up.edit_mode_set_a_on_failure = function(data, pname, v) - if(pname and data and data.action_failure_dialog) then - v[ "a_on_failure" ] = yl_speak_up.d_name_to_d_id( - yl_speak_up.speak_to[pname].dialog, - data.action_failure_dialog) - else - v[ "a_on_failure" ] = "" - end -end diff --git a/editor/chat_commands_in_edit_mode.lua b/editor/chat_commands_in_edit_mode.lua deleted file mode 100644 index 686a4d5..0000000 --- a/editor/chat_commands_in_edit_mode.lua +++ /dev/null @@ -1,28 +0,0 @@ - --- Implementation of chat commands that were registered in register_once --- (here: only add those additional things needed for edit mode) - -local old_command_npc_talk = yl_speak_up.command_npc_talk -yl_speak_up.command_npc_talk = function(pname, param) - if(not(pname)) then - return - end - -- activates edit mode when talking to an NPC; but only if the player can edit that NPC - if(param and param == "force_edit") then - -- implemented in functions.lua: - return yl_speak_up.command_npc_talk_force_edit(pname, rest) - end - -- not perfect - but at least some help - if(param - and (param == "help force_edit" - or param == "? force_edit" - or param == "force_edit help")) then - minetest.chat_send_player(pname, - "Toggles force edit mode. This is helpful if you cut yourself out ".. - "of editing an NPC by breaking it. From now on all NPC you will talk to ".. - "will already be in edit mode (provided you are allowed to edit them).".. - "\nIssuing the command again ends force edit mode.") - return - end - return old_command_npc_talk(pname, param) -end diff --git a/editor/command_force_edit_mode.lua b/editor/command_force_edit_mode.lua deleted file mode 100644 index b79fb7a..0000000 --- a/editor/command_force_edit_mode.lua +++ /dev/null @@ -1,24 +0,0 @@ - - --- allow to enter force edit mode (useful when an NPC was broken) -yl_speak_up.force_edit_mode = {} --- command to enter force edit mode -yl_speak_up.command_npc_talk_force_edit = function(pname, param) - if(not(pname)) then - return - end - if(yl_speak_up.force_edit_mode[pname]) then - yl_speak_up.force_edit_mode[pname] = nil - minetest.chat_send_player(pname, - "Ending force edit mode for NPC. From now on talks ".. - "will no longer start in edit mode.") - else - yl_speak_up.force_edit_mode[pname] = true - minetest.chat_send_player(pname, - "STARTING force edit mode for NPC. From now on talks ".. - "with NPC will always start in edit mode provided ".. - "you are allowed to edit this NPC.\n".. - "In order to end force edit mode, give the command ".. - "/npc_talk_force_edit a second time.") - end -end diff --git a/editor/edit_mode.lua b/editor/edit_mode.lua deleted file mode 100644 index c0e5306..0000000 --- a/editor/edit_mode.lua +++ /dev/null @@ -1,151 +0,0 @@ - --- if player has npc_talk_owner priv AND is owner of this particular npc: --- chat option: "I am your owner. I have new orders for you. --- -> enters edit mode --- when edit_mode has been enabled, the following chat options are added to the options: --- chat option: "Add new answer/option to this dialog." --- -> adds a new aswer/option --- chat option: "That was all. I'm finished with giving you new orders. Remember them!" --- -> ends edit mode --- (happens in fs/fs_talkdialog_in_edit_mode.lua) - - --- store if the player is editing a particular NPC; format: yl_speak_up.edit_mode[pname] = npc_id -yl_speak_up.edit_mode = {} - --- changes applied in edit_mode are applied immediately - but not immediately stored to disk --- (this gives the players a chance to back off in case of unwanted changes) -yl_speak_up.npc_was_changed = {} - - --- is the player in edit mode? -yl_speak_up.in_edit_mode = function(pname) - return pname - and yl_speak_up.edit_mode[pname] - and (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id) -end - - --- reset edit_mode when stopping to talk to an NPC -local old_reset_vars_for_player = yl_speak_up.reset_vars_for_player -yl_speak_up.reset_vars_for_player = function(pname, reset_fs_version) - yl_speak_up.edit_mode[pname] = nil - old_reset_vars_for_player(pname, reset_fs_version) -end - - --- make sure generic dialogs are never included in edit_mode (because in edit mode we want to --- edit this particular NPC without generic parts) -local old_load_dialog = yl_speak_up.load_dialog -yl_speak_up.load_dialog = function(n_id, player) -- returns the saved dialog - if(player and yl_speak_up.in_edit_mode(player:get_player_name())) then - return old_load_dialog(n_id, false) - end - return old_load_dialog(n_id, player) -end - - --- in edit mode the dialog may be saved. visits to a particular dialog are of no intrest here -local old_count_visits_to_dialog = yl_speak_up.count_visits_to_dialog -yl_speak_up.count_visits_to_dialog = function(pname) - if(yl_speak_up.in_edit_mode(pname)) then - return - end - return old_count_visits_to_dialog(pname) -end - - -local modname = minetest.get_current_modname() -if(not(modname)) then - modname = "yl_speak_up" -end - --- TODO: adjust to new mod name and paths -local modpath = minetest.get_modpath(modname)..DIR_DELIM.."editor"..DIR_DELIM - --- this is a way to provide additional help if a mod adds further commands (like the editor) -yl_speak_up.add_to_command_help_text = yl_speak_up.add_to_command_help_text.. - "\nAdditional commands provided by "..tostring(modname)..":\n".. - " force_edit forces edit mode for any NPC you talk to\n" - - - -- overrides of functions fo fs/fs_talkdialog.lua when in edit_mode (or for entering/leaving it) - dofile(modpath .. "fs/fs_talkdialog_edit_mode.lua") - - -- edit preconditions (can be reached through edit options dialog) - dofile(modpath .. "fs/fs_edit_preconditions.lua") - -- edit actions (can be reached through edit options dialog) - dofile(modpath .. "fs/fs_edit_actions.lua") - -- edit effects (can be reached through edit options dialog) - dofile(modpath .. "fs/fs_edit_effects.lua") - -- edit options dialog (detailed configuration of options in edit mode) - dofile(modpath .. "fs/fs_edit_options_dialog.lua") - - -- the player wants to change something regarding the dialog - dofile(modpath .. "edit_mode_apply_changes.lua") - - - - -- handle page changes and asking for saving when in edit mode: - dofile(modpath .. "show_fs_in_edit_mode.lua") - -- ask if the player wants to save, discard or go back in edit mode - dofile(modpath .. "fs/fs_save_or_discard_or_back.lua") - -- the player wants to change something regarding the dialog - dofile(modpath .. "edit_mode_apply_changes.lua") - - -- assign a quest step to a dialog option/answer - dofile(modpath .. "fs/fs_assign_quest_step.lua") - - -- in edit_mode we need a more complex reaction to inventory changes - dofile(modpath .. "exec_actions_action_inv_changed.lua") - -- in edit_mode: effects are not executed - dofile(modpath .. "exec_all_relevant_effects.lua") - -- some helper functions for formatting text for a formspec talbe - dofile(modpath .. "print_as_table.lua") - -- create i.e. a dropdown list of player names - dofile(modpath .. "api/formspec_helpers.lua") - -- handle alternate text for dialogs - dofile(modpath .. "api/api_alternate_text.lua") - -- helpful for debugging the content of the created dialog structure - dofile(modpath .. "fs/fs_show_what_points_to_this_dialog.lua") - -- common functions for editing preconditions and effects - dofile(modpath .. "api/fs_edit_general.lua") - -- edit preconditions (can be reached through edit options dialog) - dofile(modpath .. "fs/fs_edit_preconditions.lua") - -- edit actions (can be reached through edit options dialog) - dofile(modpath .. "fs/fs_edit_actions.lua") - -- edit effects (can be reached through edit options dialog) - dofile(modpath .. "fs/fs_edit_effects.lua") - -- edit options dialog (detailed configuration of options in edit mode) - dofile(modpath .. "fs/fs_edit_options_dialog.lua") - dofile(modpath .. "fs/fs_initial_config_in_edit_mode.lua") - dofile(modpath .. "trade_in_edit_mode.lua") - dofile(modpath .. "fs/fs_add_trade_simple_in_edit_mode.lua") - -- handle back button diffrently when editing a trade as an action: - dofile(modpath .. "fs/fs_do_trade_simple_in_edit_mode.lua") - -- as the name says: list which npc acesses a variable how and in which context - dofile(modpath .. "fs/fs_get_list_of_usage_of_variable.lua") - -- show which values are stored for which player in a quest variable - dofile(modpath .. "fs/fs_show_all_var_values.lua") - -- manage quest variables: add, delete, manage access rights etc. - dofile(modpath .. "fs/fs_manage_variables.lua") - -- GUI for adding/editing quests - dofile(modpath .. "fs/fs_manage_quests.lua") - -- GUI for adding/editing quest steps for the quests - dofile(modpath .. "api/api_quest_steps.lua") - dofile(modpath .. "fs/fs_manage_quest_steps.lua") - -- used by the above - dofile(modpath .. "fs/fs_add_quest_steps.lua") - -- setting skin, wielded item etc. - dofile(modpath .. "fs/fs_fashion.lua") - dofile(modpath .. "fs/fs_fashion_extended.lua") - -- properties for NPC without specific dialogs that want to make use of - dofile(modpath .. "fs/fs_properties.lua") - -- /npc_talk force_edit (when talking to an NPC in the normal way fails): - dofile(modpath .. "command_force_edit_mode.lua") - -- add the force_edit option to the chat commands - dofile(modpath .. "chat_commands_in_edit_mode.lua") - -- creating and maintaining quests - dofile(modpath .. "fs/fs_quest_gui.lua") - -- take notes regarding what the NPC is for - dofile(modpath .. "fs/fs_notes.lua") diff --git a/editor/edit_mode_apply_changes.lua b/editor/edit_mode_apply_changes.lua deleted file mode 100644 index 25efaa6..0000000 --- a/editor/edit_mode_apply_changes.lua +++ /dev/null @@ -1,570 +0,0 @@ - - --- helper function for yl_speak_up.edit_mode_apply_changes; --- makes sure the new dialog (and a result/effect "dialog" for each option) exist -yl_speak_up.prepare_new_dialog_for_option = function(dialog, pname, n_id, d_id, o_id,target_dialog,o_results) - -- this may also point to a new dialog - if(target_dialog == yl_speak_up.text_new_dialog_id) then - -- create a new dialog and show it as new target dialog - but do not display - -- 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 - for kr, vr in pairs(o_results) do - if( vr.r_type == "dialog" ) then - result = vr - -- no problem - the right dialog is set already - if(result.r_value and result.r_value == target_dialog) then - return target_dialog - else - -- no need to search any further - break - end - 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 ".. - 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 - result.r_value = target_dialog - return target_dialog - end - -- create a new result (first the id, then the actual result) - local future_r_id = yl_speak_up.add_new_result(dialog, d_id, o_id) - -- actually store the new result - dialog.n_dialogs[d_id].d_options[o_id].o_results[future_r_id] = { - r_id = future_r_id, - r_type = "dialog", - r_value = target_dialog} - return target_dialog -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); --- the function checks if the player has changed any parameters --- Parameters: --- pname player name --- fields the fields returned from the formspec --- Returns: --- result table with information about what was added --- (for now, only result.show_next_option is of intrest in the option edit menu) -yl_speak_up.edit_mode_apply_changes = function(pname, fields) - local n_id = yl_speak_up.edit_mode[pname] - if(not(n_id) or not(yl_speak_up.speak_to[pname])) then - return - end - local d_id = yl_speak_up.speak_to[pname].d_id - local dialog = yl_speak_up.speak_to[pname].dialog - - -- check if the player is allowed to edit this NPC - if(not(yl_speak_up.may_edit_npc(minetest.get_player_by_name(pname), n_id))) then - return - end - - -- this way we can store the actual changes and present them to the player for saving - if(not(yl_speak_up.npc_was_changed[ n_id ])) then - yl_speak_up.npc_was_changed[ n_id ] = {} - end - - - -- nothing to do if that dialog does not exist - if(not(d_id) or not(dialog.n_dialogs) or not(dialog.n_dialogs[ d_id ])) then - return - end - - -- 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) - -- mute/unmute gets logged in the function and does not need extra log entries - local obj = yl_speak_up.speak_to[pname].obj - if(fields.mute_npc and obj) then - yl_speak_up.set_muted(pname, obj, true) - elseif(fields.un_mute_npc and obj) then - yl_speak_up.set_muted(pname, obj, false) - end - - -- changes to d_dynamic are *not* changed (the content of that dialog has to be provided - -- dynamicly by a function): - if(d_id == "d_dynamic") then - return - end - - -- new options etc. may be added; store these IDs so that we can switch to the right target - local result = {} - - -- make this the first dialog shown when starting a conversation - if(fields.make_first_option) then - -- check which dialog(s) previously had the highest priority and change thsoe - for k, v in pairs(dialog.n_dialogs) do - if(v and v.d_sort and (v.d_sort=="0" or v.d_sort==0)) then - -- try to derive a sensible future sort priority from the key: - -- here we make use of the d_ pattern; but even if that fails to yield - -- a number, the sort function will later be able to deal with it anyway - local new_priority = string.sub(k, 3) - dialog.n_dialogs[ k ].d_sort = new_priority - end - end - -- actually make this the chat with the highest priority - dialog.n_dialogs[ d_id ].d_sort = "0" - -- this is not immediately saved, even though the changes to the previous dialog with - -- the highest priority cannot be automaticly undone (but as long as it is not saved, - -- it really does not matter; and when saving, the player has to take some care) - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Turned into new start dialog.") - end - - -- if it is *a* start dialog: buttons like give item to npc/trade/etc. will be shown - if(fields.turn_into_a_start_dialog) then - if(dialog.n_dialogs[ d_id ].is_a_start_dialog) then - -- no need to waste space... - dialog.n_dialogs[ d_id ].is_a_start_dialog = nil - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Is no longer *a* start dialog (regarding buttons).") - else - dialog.n_dialogs[ d_id ].is_a_start_dialog = true - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Turned into *a* start dialog (regarding buttons).") - end - end - - -- detect changes to d_text: text of the dialog (what the npc is saying) - -- (only happens in dialog edit menu) - if(fields.d_text and dialog.n_dialogs[ d_id ].d_text ~= fields.d_text) then - -- store that there have been changes to this npc - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": d_text (what the NPC says) was changed from \"".. - tostring( dialog.n_dialogs[ d_id ].d_text).. - "\" to \""..tostring(fields.d_text).."\".") - -- actually change the text - but do not save to disk yet - 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).."." - elseif(yl_speak_up.is_special_dialog(fields.d_name)) then - err_msg = "Sorry. That is a special dialog ID. You cannot use it as ".. - "a manually set name." - elseif(string.sub(fields.d_name, 1, 2) == "d_") then - err_msg = "Sorry. Names starting with \"d_\" are not allowed. They ".. - "may later be needed for new dialogs." - 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) - if(not(future_o_id)) then - -- this is already checked earlier on and the button only shown if - -- options can be added; so this can reamin a chat message - minetest.chat_send_player(pname, "Sorry. Only ".. - tostring(yl_speak_up.max_number_of_options_per_dialog).. - " options/answers are allowed per dialog.") - fields.add_option = nil - else - -- add_new_option has added a dialog result for us already - no need to do that again - - -- if this is selected in the options edit menu, we want to move straight on to the new option - result["show_next_option"] = future_o_id - end - end - - -- delete an option directly from the main fs_talkdialog - if(dialog.n_dialogs[d_id].d_options) then - for o_id, o_v in pairs(dialog.n_dialogs[d_id].d_options) do - if(o_id and fields["delete_option_"..o_id]) then - fields["del_option"] = true - fields.o_id = o_id - -- ..or move an option up by one in the list - elseif(o_id and fields["option_move_up_"..o_id]) then - fields["option_move_up"] = true - fields.o_id = o_id - -- ..or move an option down by one in the list - elseif(o_id and fields["option_move_down_"..o_id]) then - fields["option_move_down"] = true - fields.o_id = o_id - end - end - end - - if(fields[ "del_option"] and fields.o_id and dialog.n_dialogs[d_id].d_options[fields.o_id]) then - local o_id = fields.o_id - -- which dialog to show instead of the deleted one? - local next_o_id = o_id - local sorted_list = yl_speak_up.get_sorted_options(dialog.n_dialogs[d_id].d_options, "o_sort") - for i, o in ipairs(sorted_list) do - if(o == o_id and sorted_list[ i+1 ]) then - next_o_id = sorted_list[ i+1 ] - elseif(o == o_id and sorted_list[ i-1 ]) then - next_o_id = sorted_list[ i-1 ] - end - end - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(o_id).." deleted.") - -- actually delete the dialog - dialog.n_dialogs[d_id].d_options[o_id] = nil - -- the current dialog is deleted; we need to show another one - result["show_next_option"] = next_o_id - -- after deleting the entry, all previous/further changes to it are kind of unintresting - return result - end - - -- move an option up by one - local d_options = dialog.n_dialogs[d_id].d_options - if(fields[ "option_move_up"] and fields.o_id and d_options[fields.o_id]) then - local sorted_o_list = yl_speak_up.get_sorted_options(d_options, "o_sort") - local idx = table.indexof(sorted_o_list, fields.o_id) - if(idx > 1) then - -- swap the two positions - local tmp = dialog.n_dialogs[d_id].d_options[fields.o_id].o_sort - dialog.n_dialogs[d_id].d_options[fields.o_id].o_sort = - dialog.n_dialogs[d_id].d_options[sorted_o_list[idx - 1]].o_sort - dialog.n_dialogs[d_id].d_options[sorted_o_list[idx - 1]].o_sort = tmp - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(fields.o_id).." was moved up by one.") - end - -- ..or move the option down by one - elseif(fields[ "option_move_down"] and fields.o_id and d_options[fields.o_id]) then - local sorted_o_list = yl_speak_up.get_sorted_options(d_options, "o_sort") - local idx = table.indexof(sorted_o_list, fields.o_id) - if(idx > 0 and idx < #sorted_o_list) then - local tmp = dialog.n_dialogs[d_id].d_options[fields.o_id].o_sort - dialog.n_dialogs[d_id].d_options[fields.o_id].o_sort = - dialog.n_dialogs[d_id].d_options[sorted_o_list[idx + 1]].o_sort - dialog.n_dialogs[d_id].d_options[sorted_o_list[idx + 1]].o_sort = tmp - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(fields.o_id).." was moved down by one.") - end - end - - -- ignore entries to o_sort if they are not a number - if(fields[ "edit_option_o_sort"] - and tonumber(fields[ "edit_option_o_sort"]) - and fields.o_id and dialog.n_dialogs[d_id].d_options[fields.o_id]) then - local o_id = fields.o_id - local new_nr = tonumber(fields[ "edit_option_o_sort"]) - local old_nr = tonumber(dialog.n_dialogs[d_id].d_options[o_id].o_sort) - -- if the nr is -1 (do not show) then we are done already: nothing to do - if(old_nr == new_nr) then - -- -1: do not list as option/answer (but still store and keep it) - elseif(new_nr == -1 and old_nr ~= -1) then - dialog.n_dialogs[d_id].d_options[o_id].o_sort = "-1" - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(o_id).." was set to -1 (do not list).") - else - -- get the old sorted list - local sorted_list = yl_speak_up.get_sorted_options(dialog.n_dialogs[d_id].d_options, "o_sort") - -- negative numbers are not shown - local entries_shown_list = {} - for i, o in ipairs(sorted_list) do - local n = tonumber(dialog.n_dialogs[d_id].d_options[o].o_sort) - if(n and n > 0 and o ~= o_id) then - table.insert(entries_shown_list, o) - end - end - -- insert the entry at the new position and let lua do the job - table.insert(entries_shown_list, new_nr, o_id) - -- take the indices from that new list as new sort values and store them; - -- this has the side effect that duplicate entries get sorted out as well - for i, o in ipairs(entries_shown_list) do - dialog.n_dialogs[d_id].d_options[o].o_sort = tostring(i) - end - -- store that there was a cahnge - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(o_id).." was moved to position ".. - tostring(new_nr)..".") - end - end - - -- changes to options are not possible if there are none - if(dialog.n_dialogs[ d_id ].d_options) then - - -- detect changes to text_option_: text for option - for k, v in pairs(dialog.n_dialogs[ d_id ].d_options) do - if( fields[ "text_option_"..k ] - and fields[ "text_option_"..k ] ~= v.o_text_when_prerequisites_met ) then - -- store that there have been changes to this npc - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The text for option "..tostring(k).. - " was changed from \""..tostring(v.o_text_when_prerequisites_met).. - "\" to \""..tostring(fields[ "text_option_"..k]).."\".") - -- actually change the text of the option - dialog.n_dialogs[ d_id ].d_options[ k ].o_text_when_prerequisites_met = fields[ "text_option_"..k ] - end - end - - -- detect changes to d_id_: target dialog for option - for k, v in pairs(dialog.n_dialogs[ d_id ].d_options) do - if(fields[ "d_id_"..k ]) then - local new_target_dialog = yl_speak_up.prepare_new_dialog_for_option( - dialog, pname, n_id, d_id, k, fields[ "d_id_"..k ], v.o_results) - if(new_target_dialog ~= fields[ "d_id_"..k ] - and not( dialog.n_dialogs[new_target_dialog] - and dialog.n_dialogs[new_target_dialog].d_name - and dialog.n_dialogs[new_target_dialog].d_name == fields["d_id_"..k]) - ) then - fields[ "d_id_"..k ] = new_target_dialog - -- in options edit menu: show this update - result["show_next_option"] = k - end - end - end - end - - -- add a new dialog; either via "+" button or "New dialog" in dialog dropdown menu - -- this has to be done after all the other changes because those (text changes etc.) still - -- apply to the *old* dialog - if(fields.show_new_dialog - or(fields["d_id"] and fields["d_id"] == yl_speak_up.text_new_dialog_id)) then - -- create the new dialog and make sure it gets shown - local d_id = yl_speak_up.add_new_dialog(dialog, pname, nil) - -- actually show the new dialog - fields["d_id"] = d_id - fields["show_new_dialog"] = nil - end - - -- delete one empty dialog - if(fields.delete_this_empty_dialog) then - local anz_options = 0 - -- we need to show a new dialog after this one was deleted - local new_dialog = d_id - local sorted_list = yl_speak_up.get_sorted_options(dialog.n_dialogs, "d_sort") - for i, k in ipairs(sorted_list) do - -- count the options of this dialog - if(k == d_id) then - if(dialog.n_dialogs[d_id].d_options) then - for o, w in pairs(dialog.n_dialogs[d_id].d_options) do - anz_options = anz_options + 1 - end - end - if(sorted_list[i+1]) then - new_dialog = sorted_list[i+1] - elseif(sorted_list[i-1]) then - new_dialog = sorted_list[i-1] - end - end - end - -- there needs to be one dialog left after deleting this one, - -- (as there is always d_dynamic we need to leave *two* dialogs) - if(#sorted_list > 2 - -- this dialog isn't allowed to hold any more options/answers - and anz_options == 0 - -- we really found a new dialog to show - and new_dialog ~= d_id - -- and the text needs to be empty - and dialog.n_dialogs[ d_id ].d_text == "") then - -- actually delete this dialog - dialog.n_dialogs[ d_id ] = nil - -- ..and store it to disk - yl_speak_up.delete_dialog(n_id, d_id) - yl_speak_up.log_change(pname, n_id, - "Deleted dialog "..tostring(d_id)..".") - -- switch to another dialog (this one was deleted after all) - fields["d_id"] = new_dialog - fields["show_new_dialog"] = nil - else - -- deleting is only possible from the talk menu, and there the delete - -- button is only shown if the dialog can be deleted; so this can remain - -- a chat message - minetest.chat_send_player(pname, "Sorry. This dialog cannot be deleted (yet). ".. - "It is either the only dialog left or has a non-empty text or has at ".. - "least on remaining option/answer.") - end - end - - -- not in options edit menu? - local o_id = fields.o_id - if(not(o_id)) then - return result - end - - local d_option = dialog.n_dialogs[ d_id ].d_options[ o_id ] - -- change alternate text when preconditions are not met - -- (only happens in options edit menu) - if(fields.option_text_not_met and d_option - and d_option.o_text_when_prerequisites_not_met ~= fields.option_text_not_met) then - -- add change to changelog - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The alternate text for option "..tostring(o_id).. - " was changed from \"".. - tostring(d_option.o_text_when_prerequisites_not_met).."\" to \"".. - tostring(fields.option_text_not_met).."\".") - -- actually change the text of the option - d_option.o_text_when_prerequisites_not_met = fields.option_text_not_met - end - - -- toggle visit often/only *once* - if(d_option and fields.option_visits and fields.option_visits ~= "") then - local old_visit_mode = "often" - if(d_option.o_visit_only_once and d_option.o_visit_only_once == 1) then - old_visit_mode = "*once*" - end - if(fields.option_visits ~= old_visit_mode) then - if(fields.option_visits == "often") then - d_option.o_visit_only_once = 0 - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(o_id).. - " can now be visited often/unlimited (default).") - elseif(fields.option_visits == "*once*") then - d_option.o_visit_only_once = 1 - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(o_id).. - " can now be visited only *once* per talk.") - end - end - end - - -- toggle autoselection/autoclick of an option - if(d_option and fields.option_autoanswer and fields.option_autoanswer ~= "") then - local old_answer_mode = "by clicking on it" - if(dialog.n_dialogs[ d_id ].o_random) then - old_answer_mode = "randomly" - elseif(d_option.o_autoanswer and d_option.o_autoanswer == 1) then - old_answer_mode = "automaticly" - end - if(fields.option_autoanswer ~= old_answer_mode) then - local new_answer_mode = "" - if(fields.option_autoanswer == "by clicking on it") then - d_option.o_autoanswer = nil - -- the dialog is no longer random - dialog.n_dialogs[ d_id ].o_random = nil - new_answer_mode = fields.option_autoanswer - elseif(fields.option_autoanswer == "automaticly") then - d_option.o_autoanswer = 1 - -- the dialog is no longer random - dialog.n_dialogs[ d_id ].o_random = nil - new_answer_mode = fields.option_autoanswer - elseif(fields.option_autoanswer == "randomly") then - d_option.o_autoanswer = nil - -- the entire dialog needs to be set to randomly - not just this option - dialog.n_dialogs[ d_id ].o_random = 1 - new_answer_mode = fields.option_autoanswer - end - if(new_answer_mode ~= "" and new_answer_mode ~= old_answer_mode) then - local random_was_changed = "" - if(new_answer_mode == "randomly" or old_answer_mode == "randomly") then - random_was_changed = " Note that changes to/from \"randomly\" ".. - "affect the entire dialog!" - end - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": The modus for option "..tostring(o_id).. - " was changed from \""..old_answer_mode.."\" to \"".. - new_answer_mode.."\"."..random_was_changed) - end - end - end - - -- handle hide/grey out/show alternate answer - -- (only happens in options edit menu) - if(fields.hide_or_grey_or_alternate_answer and d_option) then - if(fields.hide_or_grey_or_alternate_answer == "..hide this answer." - and d_option.o_hide_when_prerequisites_not_met ~= "true") then - d_option.o_hide_when_prerequisites_not_met = "true" - d_option.o_grey_when_prerequisites_not_met = "false" - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": If precondition for option "..tostring(o_id).. - " is not met, hide option/answer.") - -- make sure we show this options update next - result["show_next_option"] = o_id - elseif(fields.hide_or_grey_or_alternate_answer == "..grey out the following answer:" - and d_option.o_grey_when_prerequisites_not_met ~= "true") then - d_option.o_hide_when_prerequisites_not_met = "false" - d_option.o_grey_when_prerequisites_not_met = "true" - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": If precondition for option "..tostring(o_id).. - " is not met, grey out option/answer.") - result["show_next_option"] = o_id - elseif(fields.hide_or_grey_or_alternate_answer == "..display the following alternate answer:" - and (d_option.o_hide_when_prerequisites_not_met ~= "false" - or d_option.o_grey_when_prerequisites_not_met) ~= "false") then - d_option.o_hide_when_prerequisites_not_met = "false" - d_option.o_grey_when_prerequisites_not_met = "false" - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": If precondition for option "..tostring(o_id).. - " is not met, show alternate option/answer.") - result["show_next_option"] = o_id - end - end - - -- how many times can the player fail to execute the action successfully? - if(fields[ "timer_max_attempts_on_failure"]) then - local field_name = "timer_max_attempts_on_failure" - local timer_name = "timer_on_failure_"..tostring(d_id).."_"..tostring(o_id) - if(not(tonumber(fields[ field_name ]))) then - fields[ field_name ] = 0 - end - -- make sure the variable exists - if(yl_speak_up.add_time_based_variable(timer_name)) then - yl_speak_up.set_variable_metadata(timer_name, nil, "parameter", "max_attempts", - fields[ field_name ]) - end - end - -- ..and how long has the player to wait in order to try again? - if(fields[ "timer_max_seconds_on_failure"]) then - local field_name = "timer_max_seconds_on_failure" - local timer_name = "timer_on_failure_"..tostring(d_id).."_"..tostring(o_id) - if(not(tonumber(fields[ field_name ]))) then - fields[ field_name ] = 0 - end - -- make sure the variable exists - if(yl_speak_up.add_time_based_variable(timer_name)) then - yl_speak_up.set_variable_metadata(timer_name, nil, "parameter", "duration", - fields[ field_name ]) - end - end - if(fields[ "timer_max_seconds_on_success"]) then - local field_name = "timer_max_seconds_on_success" - local timer_name = "timer_on_success_"..tostring(d_id).."_"..tostring(o_id) - if(not(tonumber(fields[ field_name ]))) then - fields[ field_name ] = 0 - end - -- make sure the variable exists - if(yl_speak_up.add_time_based_variable(timer_name)) then - yl_speak_up.set_variable_metadata(timer_name, nil, "parameter", "duration", - fields[ field_name ]) - end - end - -- currently only contains result["show_new_option"] (which is needed for options edit menu) - return result -end --- end of yl_speak_up.edit_mode_apply_changes diff --git a/editor/exec_actions_action_inv_changed.lua b/editor/exec_actions_action_inv_changed.lua deleted file mode 100644 index d16f056..0000000 --- a/editor/exec_actions_action_inv_changed.lua +++ /dev/null @@ -1,62 +0,0 @@ - -local old_action_inv_changed = yl_speak_up.action_inv_changed --- monitor changes to the npc_gives and npc_wants slots (in particular when editing actions) --- how: can be "put" or "take" -yl_speak_up.action_inv_changed = function(inv, listname, index, stack, player, how) - if(not(player)) then - return - end - local pname = player:get_player_name() - if(not(pname) or not(yl_speak_up.speak_to[pname])) then - return - end - local n_id = yl_speak_up.speak_to[pname].n_id - -- if not in edit mode: the player may just be normally interacting with the NPC; - -- nothing to do for us here (wait for the player to click on "save") - if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then - return old_action_inv_changed(inv, listname, index, stack, player, how) - end - -- is the player in the process of editing an action of the npc_gives/npc_wants type? - local target_fs = "edit_actions" - local data = yl_speak_up.speak_to[pname][ "tmp_action" ] - if(not(data) or (data.what ~= 4 and data.what ~= 5)) then - -- we are editing an action - if(data) then - return - end - -- it might be a precondition - data = yl_speak_up.speak_to[pname][ "tmp_prereq" ] - if(not(data) or (data.what ~= 8)) then - return - end - target_fs = "edit_preconditions" - end - -- "The NPC gives something to the player (i.e. a quest item).", -- 4 - -- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5 - if(how == "put") then - data.item_node_name = stack:get_name().." "..stack:get_count() - local meta = stack:get_meta() - if(meta and meta:get_string("description")) then - -- try to reconstruct $PLAYER_NAME$ (may not always work) - local item_was_for = meta:get_string("yl_speak_up:quest_item_for") - local new_desc = meta:get_string("description") - if(item_was_for and item_was_for ~= "") then - new_desc = string.gsub(new_desc, item_was_for, "$PLAYER_NAME$") - end - data.item_desc = new_desc - end - if(meta and meta:get_string("yl_speak_up:quest_id")) then - data.item_quest_id = meta:get_string("yl_speak_up:quest_id") - end - elseif(how == "take" and data.what == 4) then - data.item_desc = "- no item set -" - data.item_node_name = "" - elseif(how == "take" and data.what == 5) then - data.item_desc = "- no item set -" - data.item_node_name = "" - end - -- show the updated formspec to the player - yl_speak_up.show_fs(player, target_fs, nil) - -- no need to check anything more here; the real checks need to be done - -- when the player presses the save/store/execute button -end diff --git a/editor/exec_all_relevant_effects.lua b/editor/exec_all_relevant_effects.lua deleted file mode 100644 index be67eef..0000000 --- a/editor/exec_all_relevant_effects.lua +++ /dev/null @@ -1,9 +0,0 @@ - -local old_execute_all_relevant_effects = yl_speak_up.execute_all_relevant_effects -yl_speak_up.execute_all_relevant_effects = function(player, effects, o_id, action_was_successful, d_option, - dry_run_no_exec) -- dry_run_no_exec for edit_mode - -- if in edit mode: do a dry run - do *not* execute the effects - local edit_mode = (player and yl_speak_up.in_edit_mode(player:get_player_name())) - -- we pass this as an additional parameter so that it doesn't have to be re-evaluated for each effect - return old_execute_all_relevant_effects(player, effects, o_id, action_was_successful, d_option, edit_mode) -end diff --git a/editor/fs/fs_add_quest_steps.lua b/editor/fs/fs_add_quest_steps.lua deleted file mode 100644 index ba88747..0000000 --- a/editor/fs/fs_add_quest_steps.lua +++ /dev/null @@ -1,763 +0,0 @@ --- helper function to make unintresting zeros in tables less visible -local grey_if_zero = function(fs, n) - if(n and n == 0) then - table.insert(fs, "#444444") - else - table.insert(fs, "#FFFFFF") - end - table.insert(fs, minetest.formspec_escape(n)) -end - - --- small helper function -local show_error_fs = function(player, text) - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:add_quest_steps", - formspec = yl_speak_up.build_fs_quest_edit_error(text, "back_from_error_msg")}) -end - - --- find out in how many quest steps this NPC or location is used; --- ID can either be n_ or a location p_(x,y,z) -yl_speak_up.count_used_in_quest_steps = function(id, step_data) - local used = 0 - for s, d in pairs(step_data or {}) do - for loc_id, loc in pairs(d.where or {}) do - if(loc and loc.n_id and loc.n_id == id) then - used = used + 1 - end - end - end - return used -end - - --- This order imposed here on the quest steps is the one in which the --- quest steps have to be solved - as far as we can tell (the quest --- may be in the process of beeing created and not logicly complete yet). -yl_speak_up.get_sorted_quest_step_list_by_prev_step = function(pname, q_id) - if(not(q_id) or not(yl_speak_up.quests[q_id]) or not(yl_speak_up.quests[q_id].step_data)) then - return {} - end - - -- for now: sort alphabeticly - local step_data = yl_speak_up.quests[q_id].step_data - local liste = {} - for k, v in pairs(step_data) do - table.insert(liste, k) - end - table.sort(liste) - return liste -end - ---[[ still belongs to the above function - -- add back links (or rather: forward links to quest steps that get enabled) - local connected = table.copy(step_data) - for k, v in pairs(connected) do - -- will store the inverse data - connected[k].inv_one_step_required = {} - connected[k].inv_all_steps_require = {} - end - for k, v in pairs(connected) do - if(k and v and v.one_step_required) then - for i, s in ipairs(v.one_step_required) do - table.insert(connected[s].inv_one_step_required, k) - end - end - if(k and v and v.all_steps_required) then - for i, s in ipairs(v.all_steps_required) do - table.insert(connected[s].inv_all_steps_required, k) - end - end - end - -- get those quest steps that are not connected and not used yet - local liste = {} - for k, v in pairs(connected) do - if(k and v - and #v.one_step_required == 0 and #v.all_steps_required == 0 - and #v.inv_one_step_required == 0 and #v.inv_all_steps_required == 0) then - table.insert(liste, k) - end - end - -- sort alphabeticly - table.sort(liste) - -- remove those entries from our connection table (they're not connected anyway); - -- we have already added them to the beginning of the list - for i, v in ipairs(liste) do - connected[v] = nil - end - - - return liste -end ---]] - - --- helper function: find out if a quest step is required by other quest steps -yl_speak_up.quest_step_get_required_for_steps = function(step_data) - local required_for_steps = {} - for s, d in pairs(step_data) do - required_for_steps[s] = {} - end - for s, d in pairs(step_data) do - if(s and d and d.one_step_required and type(d.one_step_required) == "table") then - for i, s2 in ipairs(d.one_step_required) do - table.insert(required_for_steps[s2], s) - end - end - if(s and d and d.all_steps_required and type(d.all_steps_required) == "table") then - for i, s2 in ipairs(d.all_steps_required) do - table.insert(required_for_steps[s2], s) - end - end - end - return required_for_steps -end - - -yl_speak_up.input_fs_add_quest_steps = function(player, formname, fields) - if(not(fields) or not(player)) then - return - end - local res = yl_speak_up.player_is_working_on_quest(player) - if(res.error_msg) then - return show_error_fs(player, res.error_msg) - end - local pname = res.pname - local q_id = res.q_id - local current_step = res.current_step - local step_data = res.step_data - local quest = res.quest - - if(fields.back_from_error_msg) then - yl_speak_up.show_fs(player, "add_quest_steps") - return - end - local mode = yl_speak_up.speak_to[pname].quest_step_mode - if(fields.back) then - -- go back to quest overview - if(mode and (mode == "manage_quest_npcs" or mode == "manage_quest_locations")) then - return yl_speak_up.show_fs(player, "manage_quests") - end - return yl_speak_up.show_fs(player, "manage_quest_steps", current_step) - end - - -- has a quest step be selected? - local work_step = nil - if(fields.add_element and fields.add_element_name) then - if( mode and mode == "manage_quest_npcs") then - -- manually entered an NPC ID - local npc_id = fields.add_element_name or "" - -- just check if it is *potentially* an NPC ID; that way NPC the quest - -- creator has no write access to can be added - if(string.sub(npc_id, 1, 2) ~= "n_" - or not(tonumber(string.sub(npc_id, 3)))) then - return show_error_fs(player, "This is not an NPC ID. They have the form n_.") - end - -- only npcs that are not yet added (and we store IDs without n_ prefix) - local id = tonumber(string.sub(npc_id, 3)) - if(id and table.indexof(res.quest.npcs or {}, id) == -1) then - table.insert(yl_speak_up.quests[q_id].npcs, id) - yl_speak_up.save_quest(q_id) - end - return yl_speak_up.show_fs(player, "add_quest_steps") - elseif(mode and mode == "manage_quest_locations") then - -- manually entered a quest location - local location_id = fields.add_element_name or "" - local d = yl_speak_up.player_vars["$NPC_META_DATA$"][location_id] - local error_msg = "" - -- the owner is not checked; that way, locations can be added where the - -- quest onwer does not (yet) have write access - if(string.sub(location_id, 1, 1) ~= "p") then - error_msg = "This is not a location ID." - elseif(not(d)) then - error_msg = "Location not found." - end - if(error_msg ~= "") then - return show_error_fs(player, error_msg) - end - -- only locations that are not yet added - if(table.indexof(res.quest.locations or {}, location_id) == -1) then - table.insert(yl_speak_up.quests[q_id].locations, location_id) - yl_speak_up.save_quest(q_id) - end - return yl_speak_up.show_fs(player, "add_quest_steps") - end - - -- create a new quest step - local new_step = fields.add_element_name:trim() - -- a new one shall be created - local msg = yl_speak_up.quest_step_add_quest_step(pname, q_id, new_step) - if(msg ~= "OK") then - return show_error_fs(player, msg) - end - -- this will also be set if the quest step exists already; this is fine so far - work_step = new_step - - elseif(fields.add_from_available - and yl_speak_up.speak_to[pname].list_available) then - -- selected a quest step from the list of available steps offered - local liste = yl_speak_up.speak_to[pname].list_available - local selected = minetest.explode_table_event(fields.add_from_available) - if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then - work_step = liste[selected.row - 1] - end - - elseif(fields.add_to_npc_list - and yl_speak_up.speak_to[pname].list_available) then - -- selected an NPC from the list of available NPC offered - local liste = yl_speak_up.speak_to[pname].list_available - local selected = minetest.explode_table_event(fields.add_to_npc_list) - if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then - local npc_id = liste[selected.row - 1] - if(table.indexof(res.quest.npcs or {}, npc_id) == -1) then - table.insert(yl_speak_up.quests[q_id].npcs, npc_id) - yl_speak_up.save_quest(q_id) - end - end - return yl_speak_up.show_fs(player, "add_quest_steps") - - elseif(fields.add_to_location_list - and yl_speak_up.speak_to[pname].list_available) then - -- selected a location from the list of available locations offered - local liste = yl_speak_up.speak_to[pname].list_available - local selected = minetest.explode_table_event(fields.add_to_location_list) - if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then - local location_id = liste[selected.row - 1] - if(table.indexof(res.quest.locations or {}, location_id) == -1) then - table.insert(yl_speak_up.quests[q_id].locations, location_id) - yl_speak_up.save_quest(q_id) - end - end - return yl_speak_up.show_fs(player, "add_quest_steps") - - elseif(fields.delete_from_one_step_required and current_step and step_data[current_step]) then - -- remove a quest step from the list (from one step required) - local selected = minetest.explode_table_event(fields.delete_from_one_step_required) - local liste = (step_data[current_step].one_step_required or {}) - if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then - table.remove(yl_speak_up.quests[q_id].step_data[current_step].one_step_required, selected.row-1) - end - yl_speak_up.save_quest(q_id) - return yl_speak_up.show_fs(player, "add_quest_steps") - - elseif(fields.delete_from_all_steps_required and current_step and step_data[current_step]) then - -- remove a quest step from the lists (from all steps required) - local selected = minetest.explode_table_event(fields.delete_from_all_steps_required) - local liste = (step_data[current_step].all_steps_required or {}) - if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then - table.remove(yl_speak_up.quests[q_id].step_data[current_step].all_steps_required, selected.row-1) - end - yl_speak_up.save_quest(q_id) - return yl_speak_up.show_fs(player, "add_quest_steps") - - elseif(fields.delete_from_npc_list) then - -- remove an NPC from the list of contributors - local selected = minetest.explode_table_event(fields.delete_from_npc_list) - local liste = (res.quest.npcs or {}) - if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then - -- *can* it be removed, or is it needed somewhere? - local full_id = "n_"..tostring(liste[selected.row - 1]) - if(yl_speak_up.count_used_in_quest_steps(full_id, step_data) > 0) then - return show_error_fs(player, "This NPC is needed for setting a quest step.") - end - table.remove(yl_speak_up.quests[q_id].npcs, selected.row - 1) - end - yl_speak_up.save_quest(q_id) - return yl_speak_up.show_fs(player, "add_quest_steps") - - elseif(fields.delete_from_location_list) then - -- remove a location from the list of contributors - local selected = minetest.explode_table_event(fields.delete_from_location_list) - local liste = (res.quest.locations or {}) - if(selected and selected.row and selected.row > 1 and selected.row <= #liste + 1) then - -- *can* it be removed, or is it needed somewhere? - local full_id = liste[selected.row - 1] - if(yl_speak_up.count_used_in_quest_steps(full_id, step_data) > 0) then - return show_error_fs(player, "This location is needed for setting a quest step.") - end - table.remove(yl_speak_up.quests[q_id].locations, selected.row - 1) - end - yl_speak_up.save_quest(q_id) - return yl_speak_up.show_fs(player, "add_quest_steps") - end - - if(not(work_step)) then - return -- TODO - elseif(mode == "embedded_select") then - yl_speak_up.speak_to[pname].quest_step = work_step - return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) - elseif(mode == "assign_quest_step") then - -- TODO: what if there's already a step assigned? - -- actually add the step - local n_id = yl_speak_up.speak_to[pname].n_id - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - -- this saves the quest data as well if needed - local msg = yl_speak_up.quest_step_add_where(pname, q_id, work_step, - {n_id = n_id, d_id = d_id, o_id = o_id}) - if(msg ~= "OK") then - return show_error_fs(player, msg) - end - if(not(n_id)) then - return show_error_fs(player, "NPC or location not found.") - end - -- store the new connection in the NPC file itself (do not load generic dialogs) - local dialog = yl_speak_up.load_dialog(n_id, false) - if(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id)) then - -- ok - the tables exist, so we can store the connection - dialog.n_dialogs[d_id].d_options[o_id].quest_id = quest.var_name - dialog.n_dialogs[d_id].d_options[o_id].quest_step = work_step - -- write it back to disc - yl_speak_up.save_dialog(n_id, dialog) - else - return show_error_fs(player, "Failed to save this quest step for this NPC.") - end - -- the player is working on the NPC - thus, the NPC may be in a modified stage - -- that hasn't been written to disc yet, and we need to adjust this stage as well - dialog = yl_speak_up.speak_to[pname].dialog - if(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id)) then - -- ok - the tables exist, so we can store the connection - dialog.n_dialogs[d_id].d_options[o_id].quest_id = quest.var_name - dialog.n_dialogs[d_id].d_options[o_id].quest_step = work_step - yl_speak_up.speak_to[pname].dialog = dialog - else - return show_error_fs(player, "Failed to update NPC.") - end - -- show the newly created or selected step - yl_speak_up.speak_to[pname].quest_step = work_step - -- log the change - yl_speak_up.log_change(pname, n_id, - "Dialog "..tostring(d_id)..": Option "..tostring(o_id).. - " will now set quest step \"".. - tostring(dialog.n_dialogs[d_id].d_options[o_id].quest_step).. - "\" of quest \"".. - tostring(dialog.n_dialogs[d_id].d_options[o_id].quest_id).."\".") - return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) - elseif(not(current_step) or not(step_data[current_step])) then - return yl_speak_up.show_fs(player, "manage_quests") - end - - local required_for_steps = yl_speak_up.quest_step_get_required_for_steps(step_data) - - -- make sure we have a sane data structure - for i, s in ipairs({current_step, work_step}) do - if(s and yl_speak_up.quests[q_id].step_data[s]) then - if(not(yl_speak_up.quests[q_id].step_data[s].one_step_required)) then - yl_speak_up.quests[q_id].step_data[s].one_step_required = {} - end - if(not(yl_speak_up.quests[q_id].step_data[s].all_steps_required)) then - yl_speak_up.quests[q_id].step_data[s].all_steps_required = {} - end - end - end - -- actually do the work - if(mode == "add_to_one_needed") then - table.insert(yl_speak_up.quests[q_id].step_data[current_step].one_step_required, work_step) - elseif(mode == "add_to_all_needed") then - table.insert(yl_speak_up.quests[q_id].step_data[current_step].all_steps_required, work_step) - elseif(mode == "insert_after_prev_step") then - -- the work_step requires what the current step used to require - if(#step_data[current_step].one_step_required == 1) then - -- a clear insert is possible - yl_speak_up.quests[q_id].step_data[work_step].one_step_required = { - step_data[current_step].one_step_required[1]} - yl_speak_up.quests[q_id].step_data[current_step].one_step_required[1] = work_step - else - -- no useful information on what the new work_step ought to depend on; - -- we just insert the new step at the first place - table.insert(yl_speak_up.quests[q_id].step_data[current_step].one_step_required, - 1, work_step) - end - return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) - elseif(mode == "insert_before_next_step") then - -- the work_step requires the current_step - table.insert(yl_speak_up.quests[q_id].step_data[work_step].one_step_required, 1, current_step) - -- the current step has exactly one successor? then we adjust that one - if(#required_for_steps[current_step] == 1) then - local next_step = required_for_steps[current_step][1] - local i = table.indexof(step_data[next_step].one_step_required, current_step) - local a = table.indexof(step_data[next_step].all_steps_required, current_step) - if(i > -1) then - -- is it in one_step_required? -> replace current_step with work_step - yl_speak_up.quests[q_id].step_data[next_step].one_step_required[i] = work_step - elseif(a > -1) then - -- or in all_steps_required? -> replace current_step with work_step - yl_speak_up.quests[q_id].step_data[next_step].all_steps_required[i] =work_step - end - end - return yl_speak_up.show_fs(player, "manage_quest_steps", work_step) - end - yl_speak_up.save_quest(q_id) - return yl_speak_up.show_fs(player, "add_quest_steps") -end - - --- small helper function for yl_speak_up.get_fs_add_quest_steps; --- lists all the quest steps found in liste in the order they occour there -yl_speak_up.quest_step_list_show_table = function(formspec, table_specs, liste, data, required_for_steps) - table.insert(formspec, "tablecolumns[".. - "color;text,align=right;".. -- #d.one_step_required - "color;text,align=right;".. -- #d.all_steps_required - "color;text,align=right;".. -- #required_for_steps (quest steps that need this one) - "color;text,align=right;".. -- #where (locations/NPC that *set* this quest step) - "color;text,align=left".. -- name of quest step - "]table[") - table.insert(formspec, table_specs) - table.insert(formspec,"#FFFFFF,(O),#FFFFFF,(A),#FFFFFF,(U),#FFFFFF,(L),#FFFFFF,Name of step:,") - local tmp = {} - for i, s in ipairs(liste or {}) do - local d = data[s] - if(not(d.one_step_required) or type(d.one_step_required) ~= "table") then - d.one_step_required = {} - end - grey_if_zero(tmp, #d.one_step_required) - if(not(d.all_steps_required) or type(d.all_steps_required) ~= "table") then - d.all_steps_required = {} - end - grey_if_zero(tmp, #d.all_steps_required) - if(not(required_for_steps[s])) then - required_for_steps[s] = {} - end - grey_if_zero(tmp, #required_for_steps[s]) - - if(not(d.where) or type(d.where) ~= "table") then - d.where = {} - end - local anz_where = 0 - for k, v in pairs(d.where) do - anz_where = anz_where + 1 - end - grey_if_zero(tmp, anz_where) - - table.insert(tmp, "#AAFFAA") - table.insert(tmp, minetest.formspec_escape(s)) - end - table.insert(formspec, table.concat(tmp, ",")) - table.insert(formspec, ";]") -end - - --- returns list of NPCs that pname can edit and that are not yet part of quest_npc_list -yl_speak_up.quest_get_npc_candidate_list = function(pname, quest_npc_liste) - -- build a list of candidates - local npc_list = {} - for k, v in pairs(yl_speak_up.npc_list) do - -- only NPC that are not already added - if(table.indexof(quest_npc_liste or {}, k) == -1 - -- and only those that the player can edit - and (v.owner == pname or (v.may_edit and v.may_edit[pname]))) then - table.insert(npc_list, k) - end - end - table.sort(npc_list) - return npc_list -end - - --- lists npc that are either already added or could be added --- can also handle locations -yl_speak_up.quest_npc_show_table = function(formspec, table_specs, liste, step_data, is_location_list) - table.insert(formspec, "tablecolumns[".. - "color;text,align=right;".. -- used in this many quest steps - "color;text,align=left;".. -- n_id (number, for NPC) or p_(-185,3,-146) (for locations) - "color;text,align=left;".. -- owner - "color;text,align=left".. -- name of NPC - "]table[") - table.insert(formspec, table_specs) - if(is_location_list) then - table.insert(formspec,"#FFFFFF,Used:,#FFFFFF,PositionID:,#FFFFFF,Name") - else - table.insert(formspec,"#FFFFFF,Used:,#FFFFFF,n_id:,#FFFFFF,Name") - end - table.insert(formspec, minetest.formspec_escape(",")) - table.insert(formspec, " description:,#FFFFFF,Owner:,") - local tmp = {} - for i, n_id in ipairs(liste or {}) do - local full_id = n_id - if(not(is_location_list)) then - full_id = "n_"..tostring(n_id) - end - grey_if_zero(tmp, yl_speak_up.count_used_in_quest_steps(full_id, step_data)) - -- the n_id of the NPC - table.insert(tmp, "#AAFFAA") - if(is_location_list) then - -- this already encodes the position but contains , and () - table.insert(tmp, minetest.formspec_escape(n_id)) - else - table.insert(tmp, "n_"..minetest.formspec_escape(n_id)) - end - -- get information from the NPC list (see fs_npc_list.lua) - local owner = "- ? -" - local name = "- ? -" - if(yl_speak_up.npc_list[n_id]) then - local npc = yl_speak_up.npc_list[n_id] - owner = npc.owner - name = (npc.name or name) - if(npc.desc and npc.desc ~= "") then - name = name..', '..(npc.desc or "") - end - end - -- name and description of the NPC - table.insert(tmp, "#AAFFAA") - table.insert(tmp, minetest.formspec_escape(name)) - -- owner of the NPC - table.insert(tmp, "#AAFFAA") - table.insert(tmp, minetest.formspec_escape(owner)) - end - table.insert(formspec, table.concat(tmp, ",")) - table.insert(formspec, ";]") -end - - --- returns list of locations that pname can edit and that are not yet part of quest_location_list -yl_speak_up.quest_get_location_candidate_list = function(pname, quest_location_liste) - -- build a list of candidates of locations - local location_list = {} - for n_id, v in pairs(yl_speak_up.player_vars["$NPC_META_DATA$"] or {}) do - -- TODO: better detection would be helpful - if(string.sub(n_id, 1, 1) == "p" - -- only locations that are not yet added - and table.indexof(quest_location_liste or {}, n_id) == -1 - -- and only those that the player can edit - and (v.owner == pname or (v.may_edit and v.may_edit[pname]))) then - table.insert(location_list, n_id) - end - end - table.sort(location_list) - return location_list -end - - --- param is unused -yl_speak_up.get_fs_add_quest_steps = function(player, param) - local res = yl_speak_up.player_is_working_on_quest(player) - if(res.error_msg) then - return yl_speak_up.build_fs_quest_edit_error(res.error_msg, "back") - end - local pname = res.pname - local step_data = res.step_data or {} - - - -- find out if a quest step is required by other quest steps - local required_for_steps = yl_speak_up.quest_step_get_required_for_steps(step_data) - - local current_step = nil - local this_step_data = nil - if(pname and yl_speak_up.speak_to[pname] and yl_speak_up.speak_to[pname].quest_step) then - current_step = yl_speak_up.speak_to[pname].quest_step - this_step_data = step_data[current_step] - end - local mode = "" - if(param) then - mode = param - yl_speak_up.speak_to[pname].quest_step_mode = param - elseif(pname and yl_speak_up.speak_to[pname] and yl_speak_up.speak_to[pname].quest_step_mode) then - mode = yl_speak_up.speak_to[pname].quest_step_mode - end - - local add_what = "Add a new quest step named:" - if(mode == "manage_quest_npcs") then - add_what = "Add the NPC with n_:" - elseif(mode == "manage_quest_locations") then - add_what = "Add a location by entering its ID directly:" - end - - local formspec = {} - if(mode and mode == "embedded_select") then - table.insert(formspec, "size[30,12]container[6,0;18.5,12]") - current_step = nil - else - table.insert(formspec, "size[18.5,17.3]") - end - - -- add back button - table.insert(formspec, "button[8,0;2,0.7;back;Back]") - -- show which quest we're working at - table.insert(formspec, "label[0.2,1.0;Quest ID:]") - table.insert(formspec, "label[3.0,1.0;") - table.insert(formspec, minetest.formspec_escape(res.q_id)) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,1.5;Quest name:]") - table.insert(formspec, "label[3.0,1.5;") - table.insert(formspec, minetest.formspec_escape(res.quest.name or "- unknown -")) - table.insert(formspec, "]") - - -- add new quest step - table.insert(formspec, "label[0.2,2.2;") - table.insert(formspec, add_what) - table.insert(formspec, "]") - table.insert(formspec, "button[16.1,2.4;1.2,0.7;add_element;Add]") - table.insert(formspec, "field[1.0,2.4;15,0.7;add_element_name;;]") - - local y_pos = 3.3 - if(current_step and mode == "insert_after_prev_step") then - local prev_step = "-" - if(this_step_data and this_step_data.one_step_required and #this_step_data.one_step_required > 0) then - prev_step = this_step_data.one_step_required[1] - end - table.insert(formspec, "label[0.2,3.3;between the previous step:]") - table.insert(formspec, "label[1.0,3.7;") - table.insert(formspec, minetest.colorize("#AAFFAA", minetest.formspec_escape(prev_step))) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,4.1;and the currently selected step:]") - table.insert(formspec, "label[1.0,4.5;") - table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) - table.insert(formspec, "]") - y_pos = 5.3 - elseif(current_step and mode == "insert_before_next_step") then - local next_step = "-" - if(current_step and required_for_steps[current_step] and #required_for_steps[current_step] > 0) then - next_step = required_for_steps[current_step][1] - end - table.insert(formspec, "label[0.2,3.3;between the currently selected step:]") - table.insert(formspec, "label[1.0,3.7;") - table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,4.1;and the next step:]") - table.insert(formspec, "label[1.0,4.5;") - table.insert(formspec, minetest.colorize("#AAFFAA", minetest.formspec_escape(next_step))) - table.insert(formspec, "]") - y_pos = 5.3 - elseif(current_step and mode == "add_to_one_needed") then - table.insert(formspec, "label[0.2,3.3;as a requirement to the currently selected step:]") - table.insert(formspec, "label[1.0,3.7;") - table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,4.1;so that ".. - minetest.colorize("#9999FF", "at least one").. - " of these requirements is fulfilled:]") - yl_speak_up.quest_step_list_show_table(formspec, - "0.2,4.3;17.0,3.0;delete_from_one_step_required;", - step_data[current_step].one_step_required, - step_data, required_for_steps) - table.insert(formspec, "label[0.2,7.5;(Click on an entry to delete it from the list above.)]") - y_pos = 8.3 - elseif(current_step and mode == "add_to_all_needed") then - table.insert(formspec, "label[0.2,3.3;as a requirement to the currently selected step:]") - table.insert(formspec, "label[1.0,3.7;") - table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(current_step))) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,4.1;so that ".. - minetest.colorize("#9999FF", "all").. - " of these requirements are fulfilled:]") - yl_speak_up.quest_step_list_show_table(formspec, - "0.2,4.3;17.0,3.0;delete_from_all_steps_required;", - step_data[current_step].all_steps_required, - step_data, required_for_steps) - table.insert(formspec, "label[0.2,7.5;(Click on an entry to delete it from the list above.)]") - y_pos = 8.3 - -- add a quest step to an NPC or location - elseif(mode == "assign_quest_step") then - table.insert(formspec, "container[0,3.3;17,4]") - -- what are we talking about? - local n_id = yl_speak_up.speak_to[pname].n_id - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - -- describe where in the dialog of the NPC or location this quest step shall be set - yl_speak_up.quest_step_show_where_set(pname, formspec, "which will be set by ", n_id, d_id, o_id, nil, nil) - table.insert(formspec, "container_end[]") - y_pos = 7.8 - - -- which NPC may contribute to the quest? - elseif(mode == "manage_quest_npcs") then - table.insert(formspec, "container[0,3.3;18,6]") - table.insert(formspec, "label[0.2,0;so that the NPC ".. - minetest.colorize("#9999FF", "may contribute").. - " to the quest like these NPC:]") - yl_speak_up.quest_npc_show_table(formspec, - "0.2,0.2;17.0,3.0;delete_from_npc_list;", - res.quest.npcs or {}, - step_data, false) - table.insert(formspec, "label[0.2,3.4;(Click on an entry to delete it from the list above.)]") - local available_npcs = yl_speak_up.quest_get_npc_candidate_list(pname, res.quest.npcs or {}) - yl_speak_up.speak_to[pname].list_available = available_npcs - table.insert(formspec, "label[0.2,4.4;or select an NPC from the list below:]") - yl_speak_up.quest_npc_show_table(formspec, - "0.2,4.6;17.0,6.0;add_to_npc_list;", - available_npcs or {}, step_data, false) - table.insert(formspec, "label[0.2,10.8;Used: Shows in how many quest steps this NPC is used.]") - table.insert(formspec, "container_end[]") - return table.concat(formspec, "") - -- which locations may contribute to the quest? - elseif(mode == "manage_quest_locations") then - table.insert(formspec, "container[0,3.3;18,6]") - table.insert(formspec, "label[0.2,0;so that the location ".. - minetest.colorize("#9999FF", "may contribute").. - " to the quest like these locations:]") - yl_speak_up.quest_npc_show_table(formspec, - "0.2,0.2;17.0,3.0;delete_from_location_list;", - res.quest.locations or {}, - step_data, true) - table.insert(formspec, "label[0.2,3.4;(Click on an entry to delete it from the list above.)]") - local available_locations = yl_speak_up.quest_get_location_candidate_list(pname, res.quest.locations or {}) - yl_speak_up.speak_to[pname].list_available = available_locations - table.insert(formspec, "label[0.2,4.4;or select a location from the list below:]") - yl_speak_up.quest_npc_show_table(formspec, - "0.2,4.6;17.0,6.0;add_to_location_list;", - available_locations or {}, step_data, true) - table.insert(formspec, "label[0.2,10.8;Used: Shows in how many quest steps this location is used.]") - table.insert(formspec, "container_end[]") - return table.concat(formspec, "") - end - - -- some quest steps may not be available/may not make sense - local not_available = {} - if(current_step and step_data[current_step] and (not(mode) or mode ~= "assign_quest_step")) then - -- steps that are already required - for i, s in ipairs(step_data[current_step].one_step_required or {}) do - not_available[s] = true - end - for i, s in ipairs(step_data[current_step].all_steps_required or {}) do - not_available[s] = true - end - -- steps that directly require this quest step here - for i, s in ipairs(required_for_steps[current_step] or {}) do - not_available[s] = true - end - end - if(current_step and (not(mode) or mode ~= "assign_quest_step")) then - not_available[current_step] = true - end - -- build a list of candidates - local available_steps = {} - for k, v in pairs(step_data) do - if(not(not_available[k])) then - table.insert(available_steps, k) - end - end - table.sort(available_steps) - yl_speak_up.speak_to[pname].list_available = available_steps - - table.insert(formspec, "container[0,") - table.insert(formspec, tostring(y_pos)) - table.insert(formspec, ";30,20]") - - table.insert(formspec, "label[0.2,0;or select an existing quest step from the list below") - if(mode and mode == "embedded_select") then - table.insert(formspec, minetest.colorize("#9999FF", " to display the step")..":]") - else - table.insert(formspec, ":]") - end - yl_speak_up.quest_step_list_show_table(formspec, - "0.2,0.2;17,6.0;add_from_available;", - available_steps, - step_data, required_for_steps) - table.insert(formspec, "label[0.2,6.5;Legend: The numbers show the amount of quest steps...\n".. - "\t(O) from which (o)ne needs to be achieved for this quest step\n".. - "\t(A) that (a)ll need to be achieved for this quest step\n".. - "\t(U) that require/(u)se this quest step in some form\n".. - "\t(L) Number of locations (npc/places) that ".. - minetest.colorize("#9999FF", "set").." this quest step]") - table.insert(formspec, "container_end[]") - - return table.concat(formspec, "") -end - -yl_speak_up.register_fs("add_quest_steps", - yl_speak_up.input_fs_add_quest_steps, - -- param is unused here - yl_speak_up.get_fs_add_quest_steps, - -- no special formspec version required - nil -) diff --git a/editor/fs/fs_add_trade_simple_in_edit_mode.lua b/editor/fs/fs_add_trade_simple_in_edit_mode.lua deleted file mode 100644 index 1e22d0d..0000000 --- a/editor/fs/fs_add_trade_simple_in_edit_mode.lua +++ /dev/null @@ -1,31 +0,0 @@ --- override fs/fs_add_trade_simple.lua: --- (this is kept here as it is trade related and does not change the formspec as such) - -local old_input_add_trade_simple = yl_speak_up.input_add_trade_simple -yl_speak_up.input_add_trade_simple = function(player, formname, fields, input_to) - if(not(player)) then - return 0 - end - local pname = player:get_player_name() - - input_to = "add_trade_simple" - -- are we editing an action of the type trade? - if( yl_speak_up.speak_to[pname][ "tmp_action" ] - and yl_speak_up.speak_to[pname][ "tmp_action" ].what == 3 - and yl_speak_up.in_edit_mode(pname) - and yl_speak_up.edit_mode[pname] == n_id) then - input_to = "edit_actions" - end - - return old_input_add_trade_simple(player, formname, fields, input_to) -end - - -yl_speak_up.register_fs("add_trade_simple", - -- the input function is a new one now - yl_speak_up.input_add_trade_simple, - -- the get_fs function stays the same - yl_speak_up.get_fs_add_trade_simple_wrapper, - -- force formspec version 1 (not changed): - 1 -) diff --git a/editor/fs/fs_assign_quest_step.lua b/editor/fs/fs_assign_quest_step.lua deleted file mode 100644 index ebf06cb..0000000 --- a/editor/fs/fs_assign_quest_step.lua +++ /dev/null @@ -1,343 +0,0 @@ --- assign a quest step to a dialog option/answe --- This is the formspec where this is handled. - --- small helper function -local show_error_fs = function(player, text) - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:assign_quest_step", - formspec = yl_speak_up.build_fs_quest_edit_error(text, "back_from_error_msg")}) -end - - --- small helper function -yl_speak_up.get_choose_until_step_list = function(pname, q_id, quest_step) - local choose_until_step = { - " - the player restarts the quest -", - " - this quest step -", - " - the quest step immediately following this one -" - } - local cdata = yl_speak_up.quests[q_id].step_data[quest_step] - for step_name, d in pairs(yl_speak_up.quests[q_id].step_data or {}) do - if(step_name ~= quest_step - and cdata - -- exclude steps that quest_step depends on - and table.indexof(cdata.one_step_required or {}, step_name) == -1 - and table.indexof(cdata.all_steps_required or {}, step_name) == -1) then - table.insert(choose_until_step, minetest.formspec_escape(step_name)) - end - end - return choose_until_step -end - - -yl_speak_up.input_fs_assign_quest_step = function(player, formname, fields) - if(not(player)) then - return "" - end - local pname = player:get_player_name() - -- what are we talking about? - local n_id = yl_speak_up.speak_to[pname].n_id - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - - if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then - return - end - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id))) then - return - end - - -- go back to edit options field - if((fields and fields.quit) - or (fields and fields.back and fields.back ~= "")) then - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id}) - return - elseif(fields and fields.back_from_error_msg) then - yl_speak_up.show_fs(player, "assign_quest_step", nil) - return - -- show manage quests formspec - elseif(fields and fields.manage_quests) then - -- store information so that the back button can work - yl_speak_up.speak_to[pname][ "working_at" ] = "assign_quest_step" - yl_speak_up.show_fs(player, "manage_quests", nil) - return - elseif(fields and fields.show_quest) then - local q_id = yl_speak_up.speak_to[pname].q_id - local quest_var_name = nil - if(q_id and yl_speak_up.quests[q_id]) then - quest_var_name = yl_speak_up.strip_pname_from_var(yl_speak_up.quests[q_id].var_name, pname) - end - yl_speak_up.show_fs(player, "manage_quests", quest_var_name) - return - elseif(fields and fields.select_quest_id and fields.select_quest_id ~= "") then - local parts = string.split(fields.select_quest_id, " ") - if(parts and parts[1] and yl_speak_up.quests[parts[1]]) then - -- TODO: check if the player has access rights to that quest - -- TODO: check if the NPC has been added to that quest - yl_speak_up.speak_to[pname].q_id = parts[1] - yl_speak_up.show_fs(player, "add_quest_steps", "assign_quest_step") - return - end - elseif(fields and fields.show_step) then - yl_speak_up.show_fs(player, "manage_quest_steps", yl_speak_up.speak_to[pname].quest_step) - return - elseif(fields and fields.change_show_until) then - yl_speak_up.show_fs(player, "assign_quest_step", "change_show_until") - return - elseif(fields and fields.store_show_until and fields.select_show_until) then - local res = yl_speak_up.player_is_working_on_quest(player) - if(res.error_msg) then - return yl_speak_up.build_fs_quest_edit_error(res.error_msg, "back") - end - local choose_until_step = yl_speak_up.get_choose_until_step_list( - res.pname, res.q_id, yl_speak_up.speak_to[pname].quest_step) - local index = table.indexof(choose_until_step, fields.select_show_until or "") - if(index ~= -1) then - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id))) then - return - end - table.insert(yl_speak_up.npc_was_changed[ n_id ], - tostring(d_id).." "..tostring(o_id).. - " quest step will be offered until player reached step \"".. - tostring(fields.select_show_until).."\".") - if(fields.select_show_until == " - the player restarts the quest -") then - fields.select_show_until = nil - elseif(fields.select_show_until == " - this quest step -") then - fields.select_show_until = yl_speak_up.speak_to[pname].quest_step - elseif(fields.select_show_until == " - the quest step immediately following this one -") then - fields.select_show_until = " next_step" - end - dialog.n_dialogs[d_id].d_options[o_id].quest_show_until = fields.select_show_until - end - yl_speak_up.show_fs(player, "assign_quest_step") - return - elseif(fields.delete_assignment and fields.delete_assignment ~= "") then - local n_id = yl_speak_up.speak_to[pname].n_id - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - -- load the dialog (which may be diffrent from what the player is working on) - local stored_dialog = yl_speak_up.load_dialog(n_id, false) - -- check if the dialog exists - if(not(yl_speak_up.check_if_dialog_has_option(stored_dialog, d_id, o_id))) then - return show_error_fs(player, "Dialog or option not found.") - end - local quest_step_name = dialog.n_dialogs[d_id].d_options[o_id].quest_step - local var_name = dialog.n_dialogs[d_id].d_options[o_id].quest_id - local q_id = yl_speak_up.get_quest_id_by_var_name(var_name, pname) - -- we will ignore the return value so that this connection can be deleted even if - -- something went wrong (quest deleted, no write access to quest etc.) - local msg = yl_speak_up.quest_step_del_where(pname, q_id, quest_step_name, - {n_id = n_id, d_id = d_id, o_id = o_id}) - if(not(n_id)) then - return show_error_fs(player, "NPC or location not found.") - end - -- log the change - yl_speak_up.log_change(pname, n_id, - "Dialog "..tostring(d_id)..": Option "..tostring(o_id).. - " no longer sets quest step \"".. - tostring(dialog.n_dialogs[d_id].d_options[o_id].quest_step).. - "\" of quest \"".. - tostring(dialog.n_dialogs[d_id].d_options[o_id].quest_id).."\".") - -- we have updated the quest step data - we need to update the NPC as well - local dialog = yl_speak_up.load_dialog(n_id, false) - if(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id)) then - -- ok - the tables exist, so we can delete the connection - -- (if it doesn't exist there's no need to change the stored NPC) - dialog.n_dialogs[d_id].d_options[o_id].quest_id = nil - dialog.n_dialogs[d_id].d_options[o_id].quest_step = nil - -- write it back to disc - yl_speak_up.save_dialog(n_id, dialog) - end - -- the player is working on the NPC - thus, the NPC may be in a modified stage - -- that hasn't been written to disc yet, and we need to adjust this stage as well - dialog = yl_speak_up.speak_to[pname].dialog - -- delete the connection - dialog.n_dialogs[d_id].d_options[o_id].quest_id = nil - dialog.n_dialogs[d_id].d_options[o_id].quest_step = nil - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id}) - return - elseif(not(fields) or not(fields.save)) then - return - end - -- actually store the data - local error_msg = "" - -- check if the quest exists - local quest_list = yl_speak_up.get_sorted_quest_list(pname) - local idx = table.indexof(quest_list, fields.quest_id or "") - if(not(fields.quest_id) or fields.quest_id == "" or idx < 1) then - error_msg = "Quest not found." - elseif(not(fields.quest_step) - or string.len(fields.quest_step) < 1 - or string.len(fields.quest_step) > 80) then - error_msg = "The name of the quest step has to be between\n".. - "1 and 80 characters long." - end - if(error_msg ~= "") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:assign_quest_step", - formspec = "size[9,2]".. - "label[0.2,0.5;Error: "..minetest.formspec_escape(error_msg).."]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - -- we identify quests by their var_name - not by their q_id - -- (makes it easier to transfer quests from one server to another later) - dialog.n_dialogs[d_id].d_options[o_id].quest_id = yl_speak_up.add_pname_to_var(fields.quest_id, pname) - dialog.n_dialogs[d_id].d_options[o_id].quest_step = fields.quest_step - if(not(yl_speak_up.npc_was_changed[ n_id ])) then - yl_speak_up.npc_was_changed[ n_id ] = {} - end - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..d_id..": Option "..tostring(o_id).. - " has been set as quest step \"".. - tostring(fields.quest_step).."\" for quest \""..tostring(fields.quest_id).."\".") - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id}) -end - - -yl_speak_up.get_fs_assign_quest_step = function(player, param) - if(not(player)) then - return "" - end - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - -- this only works in edit mode - if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then - return "size[1,1]label[0,0;You cannot edit this NPC.]" - end - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o_id))) then - return "size[4,1]label[0,0;Dialog option does not exist.]" - end - local d_option = dialog.n_dialogs[d_id].d_options[o_id] - local quest_id = d_option.quest_id or "" - local quest_step = d_option.quest_step or "" - local quest_show_until = d_option.quest_show_until or " - the player restarts the quest -" - if(quest_show_until == quest_step) then - quest_show_until = " - this quest step -" - -- players cannot create quest steps with leading blanks - elseif(quest_show_until == " next_step") then - quest_show_until = " - the quest step immediately following this one -" - end - - -- has a quest been selected? - local q_id = yl_speak_up.get_quest_id_by_var_name(quest_id, pname) - if(not(q_id)) then - local npc_id = tonumber(string.sub(n_id, 3)) - local quest_list = {} - for id, d in pairs(yl_speak_up.quests) do - if(table.indexof(d.npcs or {}, npc_id) ~= -1) then - table.insert(quest_list, minetest.formspec_escape( - tostring(id).." "..tostring(d.name))) - end - end - if(#quest_list < 1) then - return "size[14,4]".. - "label[4.0,0.5;Using this option/answer shall be a quest step.]".. - "label[0.2,1.4;".. - "This NPC "..tostring(n_id).." has not been added to a quest yet.\n".. - "Please add him to the NPC list of one of your quests first!\n".. - "Search the \"Edit\" button for \"NPC that (may) participate:\" ".. - "while viewing the desired quest.]".. - "button[0.2,3.0;3.6,0.8;manage_quests;Manage Quests]".. - "button[9.5,3.0;4.0,0.8;back;Back to edit option "..tostring(o_id).."]" - end - local selected = 1 - --- local quest_list = yl_speak_up.get_sorted_quest_list(pname) --- for i, v in ipairs(quest_list) do --- quest_list[i] = minetest.formspec_escape(v) --- if(quest_id and v == quest_id) then --- selected = i --- end --- end - return "size[14,4]".. - "label[4.0,0.5;Using this option/answer shall be a quest step.]".. - "label[0.2,1.4;Select a quest:]".. - "dropdown[4.0,1.0;9.5,0.8;select_quest_id;".. - table.concat(quest_list, ',')..";".. - tostring(selected)..",]".. - "label[0.2,2.1;If you want to use a quest not mentionned here or a new one, ".. - "click on \"Manage Quests\"\n".. - "and search the \"Edit\" button for \"NPC that (may) participate:\".]".. - "button[0.2,3.0;3.6,0.8;manage_quests;Manage Quests]".. - "button[9.5,3.0;4.0,0.8;back;Back to edit option "..tostring(o_id).."]" - end - - -- this is the currently relevant quest - yl_speak_up.speak_to[pname].q_id = q_id - yl_speak_up.speak_to[pname].quest_step = quest_step - local choose_until_step = {} - local show_until = "" - if(param and param == "change_show_until") then - local choose_until_step = yl_speak_up.get_choose_until_step_list(pname, q_id, quest_step) - local index = table.indexof(choose_until_step, quest_show_until or "") - if(index == -1) then - index = 1 - end - show_until = "dropdown[3.0,5.1;10,0.5;select_show_until;".. - table.concat(choose_until_step, ",")..";"..tostring(index)..";]".. - "button[13.5,4.8;4.3,0.8;store_show_until;Store]" - else - show_until = "label[3.0,5.4;"..minetest.colorize("#AAFFAA", - minetest.formspec_escape(quest_show_until)).."]".. - "button[13.5,4.8;4.3,0.8;change_show_until;Edit]" - end - local formspec = { - "size[18,7]".. - "label[3.0,0.5;Using this option/answer shall be a quest step.]".. - "label[0.2,1.4;Quest ID:]".. - "label[0.2,1.9;Quest name:]".. - "label[0.2,3.4;quest step:]".. - "button[13.5,3.1;4.3,0.8;show_step;Show this quest step]".. - "label[0.2,3.9;".. - "This quest step will be set for the player after the effects of ".. - "the dialog option are executed.]".. - - "label[0.2,4.9;".. - "This dialog option will be shown until the player has reached the ".. - "following quest step:]".. - "button[0.2,0.2;2.0,0.8;delete_assignment;Delete]".. - "tooltip[delete_assignment;".. - "Delete the assignment of this quest step to this dialog option.\n".. - "Neither the quest step nor the dialog option will be deleted.\n".. - "Just their connection. Afterwards, you can assign a new or\n".. - "diffrent quest step to the dialog option.]".. - "button[13.5,6.0;4.3,0.8;manage_quests;Manage quests]" - } - table.insert(formspec, "label[3.0,1.4;") - table.insert(formspec, minetest.formspec_escape(q_id)) - table.insert(formspec, "]") - table.insert(formspec, "label[3.0,1.9;") - table.insert(formspec, minetest.formspec_escape(yl_speak_up.quests[q_id].name or "- ? -")) - table.insert(formspec, "]") - table.insert(formspec, "button[13.5,1.0;4.3,0.8;show_quest;Show this quest ") - table.insert(formspec, tostring(q_id)) - table.insert(formspec, "]") - table.insert(formspec, "label[0.2,2.9;This option here (") - table.insert(formspec, tostring(o_id)) - table.insert(formspec, ") will be available once the player has reached all required ".. "quest steps for the following]") - table.insert(formspec, "label[3.0,3.4;") - table.insert(formspec, minetest.colorize("#FFFF00", minetest.formspec_escape(quest_step))) - table.insert(formspec, "]") - table.insert(formspec, "button[6.0,6.0;6.0,0.8;back;Back to edit option ") - table.insert(formspec, tostring(o_id)) - table.insert(formspec, "]") - table.insert(formspec, show_until) - return table.concat(formspec, " ") -end - - -yl_speak_up.register_fs("assign_quest_step", - yl_speak_up.input_fs_assign_quest_step, - yl_speak_up.get_fs_assign_quest_step, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_do_trade_simple_in_edit_mode.lua b/editor/fs/fs_do_trade_simple_in_edit_mode.lua deleted file mode 100644 index a5aa73e..0000000 --- a/editor/fs/fs_do_trade_simple_in_edit_mode.lua +++ /dev/null @@ -1,54 +0,0 @@ --- spimple trading: one item(stack) for another item(stack) --- (in edit_mode it's a bit diffrent) - - --- if in edit mode: go back to the edit_options dialog -local old_input_do_trade_simple = yl_speak_up.input_do_trade_simple -yl_speak_up.input_do_trade_simple = function(player, formname, fields) - if(not(player)) then - return 0 - end - local pname = player:get_player_name() - - -- which trade are we talking about? - local trade = yl_speak_up.trade[pname] - - - local n_id = yl_speak_up.speak_to[pname].n_id - -- if in edit mode: go back to the edit options dialog - if(fields.back_to_edit_options - and n_id and yl_speak_up.in_edit_mode(pname)) then - local dialog = yl_speak_up.speak_to[pname].dialog - local tr = dialog.trades[ trade.trade_id ] - if(tr) then - -- done trading - yl_speak_up.speak_to[pname].target_d_id = nil - yl_speak_up.speak_to[pname].trade_id = nil - -- go to the edit options dialog - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = tr.d_id, o_id = tr.o_id}) - return - end - end - - - -- can the player edit this trade? - if(fields.edit_trade_simple - and n_id and yl_speak_up.in_edit_mode(pname)) then - -- force edit mode for this trade - trade.edit_trade = true - yl_speak_up.trade[pname] = trade - end - - return old_input_do_trade_simple(player, formname, fields) -end - - -yl_speak_up.register_fs("do_trade_simple", - -- new version implemented here: - yl_speak_up.input_do_trade_simple, - -- this is just the old function: - yl_speak_up.get_fs_do_trade_simple_wrapper, - -- force formspec version 1: - 1 -) diff --git a/editor/fs/fs_edit_actions.lua b/editor/fs/fs_edit_actions.lua deleted file mode 100644 index 1b94fb1..0000000 --- a/editor/fs/fs_edit_actions.lua +++ /dev/null @@ -1,133 +0,0 @@ --- This file contains what is necessary to add/edit an action. --- --- Which diffrent types of actions are available? --- -> The following fields are part of an action: --- a_id the ID/key of the action --- a_type selected from values_what --- a_value used to store the subtype of a_type --- --- no action (none): nothing to do. --- --- a trade ("trade"): --- a_buy what the NPC sells (itemstack) --- a_pay what the NPC wants as payment (itemstack) --- --- giving and taking of items ("npc_gives" and "npc_wants"): --- a_on_failure if the action fails, go to this dialog --- a_value itemstack of the given/wanted item in string form --- a_item_desc the description the NPC shall set for that itemstack --- (so that the player can distinguish it from other --- itemstacks with the same items) --- a_item_quest_id Special ID to make sure that it is really the *right* --- item and not just something the player faked with an --- engraving table or something similar --- --- the player has to enter text ("text_input"): --- a_value the expected answer the player has to enter --- a_question the question the NPC shall ask the player (so that the --- player can know which answer is expected here) --- --- Show something custom (has to be provided by the server). (=call a function) ("evaluate"): --- a_value the name of the function that is to be called --- a_param1 the first paramter (optional; depends on function) --- .. --- a_param9 the 9th parameter (optional; depends on function) --- --- a general, more complex formspec-basted puzzle ("puzzle"): not supported --- (custom may be more helpful) --- --- --- Note: Trades are not stored as actions - they are stored in --- dialog.trades[ trade_id ] with == " " --- - --- some helper lists for creating the formspecs and evaulating --- the player's answers: - --- general direction of what could make up an action -local check_what = { - "- please select -", - "No action (default).", -- 2 - "Normal trade - one item(stack) for another item(stack).", -- 3 - "The NPC gives something to the player (i.e. a quest item).", -- 4 - "The player is expected to give something to the NPC (i.e. a quest item).", -- 5 - "The player has to manually enter a password or passphrase or some other text.", -- 6 - "Show something custom (has to be provided by the server).", - -- "The player has to move virtual items in a virtual inventory to the right position.", -- 8 -} - --- how to store these as a_type in the action: -local values_what = {"", "none", "trade", "npc_gives", "npc_wants", "text_input", "evaluate", "puzzle"} - - --- returns a human-readable text as description of the action --- (as shown in the edit options dialog and in the edit effect formspec) -yl_speak_up.show_action = function(a) - if(not(a.a_type) or a.a_type == "" or a.a_type == "none") then - return "(nothing): Nothing to do. No action." - elseif(a.a_type == "trade") then - return "NPC sells \""..table.concat(a.a_buy, ";").."\" for \"".. - table.concat(a.a_pay, ";").."\"." - elseif(a.a_type == "npc_gives") then - return "The NPC gives \""..tostring(a.a_item_desc or "- default description -").. - "\" (\""..tostring(a.a_value or "- ? -").."\") ".. - "with ID \""..tostring(a.a_item_quest_id or "- no special ID -").."\"." - elseif(a.a_type == "npc_wants") then - return "The NPC wants \""..tostring(a.a_item_desc or "- default description -").. - "\" (\""..tostring(a.a_value or "- ? -").."\") ".. - "with ID \""..tostring(a.a_item_quest_id or "- no special ID -").."\"." - elseif(a.a_type == "text_input") then - return "Q: \""..tostring(a.a_question).."\" A:\""..tostring(a.a_value).."\"." - elseif(a.a_type == "evaluate") then - local str = "" - for i = 1, 9 do - str = str..tostring(a["a_param"..tostring(i)]) - if(i < 9) then - str = str.."," - end - end - return "FUNCTION["..tostring(a.a_value).."]("..str..")" --- puzzle is unused; better do that via custom --- elseif(a.a_type == "puzzle") then --- return "puzzle:" - end - -- fallback - return tostring(a.a_value) -end - --- these are only wrapper functions for those in fs_edit_general.lua - -yl_speak_up.input_edit_actions = function(player, formname, fields) - return yl_speak_up.handle_input_fs_edit_option_related(player, formname, fields, - "a_", "actions", yl_speak_up.max_actions, - "(A)ctions", "tmp_action", - nil, -- unused - no block operations - values_what, {}, {}, {}, {}, - check_what, {}, {}, {}, {}, - nil, -- no variables - "edit_actions" - ) -end - -yl_speak_up.get_fs_edit_actions = function(player, table_click_result) - return yl_speak_up.build_fs_edit_option_related(player, table_click_result, - "a_", "actions", yl_speak_up.max_actions, - "(A)ctions", "tmp_action", - "What do you want to happen in this (A)ction?", - values_what, {}, {}, {}, {}, - check_what, {}, {}, {}, {}, - nil, -- no variables - yl_speak_up.show_action, - "table_of_elements", - nil, nil, nil, -- no variable handling here - nil -- nothing block-related to do here - ) -end - - -yl_speak_up.register_fs("edit_actions", - yl_speak_up.input_edit_actions, - yl_speak_up.get_fs_edit_actions, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_edit_effects.lua b/editor/fs/fs_edit_effects.lua deleted file mode 100644 index d9bb8dd..0000000 --- a/editor/fs/fs_edit_effects.lua +++ /dev/null @@ -1,352 +0,0 @@ --- This file contains what is necessary to add/edit an effect. --- --- Which diffrent types of effects are available? --- -> The following fields are part of an effect/result: --- r_id the ID/key of the effect/result --- r_type selected from values_what; the staffs allow to use other --- types like "function" or "give_item" etc. - but that is not --- supported here (cannot be edited or created; only be shown) --- r_value used to store the subtype of r_type --- --- a state/variable ("state"): --- r_variable name of a variable the player has *write* access to; --- dropdown list with allowed options --- r_operator selected from values_operator --- r_var_cmp_value can be set freely by the player (the variable will be --- set to this value) --- --- the value of a property of the NPC (for generic NPC) ("property"): --- r_value name of the property that is to be changed --- r_operator how shall the property be changed? --- r_var_cmp_value the new value (or increment/decrement) for this property --- --- something that has to be calculated or evaluated (=call a function) ("evaluate"): --- r_value the name of the function that is to be called --- r_param1 the first paramter (optional; depends on function) --- .. --- r_param9 the 9th parameter (optional; depends on function) --- --- a block in the world ("block"): --- r_pos a position in the world; determined by asking the player --- to punch the block --- r_node (follows from r_pos) --- r_param2 (follows from r_pos) --- --- place an item into the inventory of a block (i.e. a chest; "put_into_block_inv"): --- r_pos the position of the target block --- r_inv_list_name the inventory list where the item shall be moved to (often "main") --- r_itemstack the itemstack that is to be moved --- --- take item out of the inventory of a block (i.e. a chest; "take_from_block_inv"); --- same as "put_into_block_inv" --- --- accept items the player has given to the NPC ("deal_with_offered_item"): --- r_value subtype; one of yl_speak_up.dropdown_values_deal_with_offered_item --- --- a craft receipe ("craft"): --- r_value the expected craft result --- r_craft_grid array containing the stacks in the 9 craft grid fields in string form --- --- on_failure ("on_failure"): --- r_value alternate target dialog if the previous *effect* failed --- --- chat_all ("chat_all"): --- r_value chat message sent to all players --- --- --- give item to player ("give_item"): requires yl_speak_up.npc_privs_priv priv --- r_value the itemstack that shall be added to the player's inventory --- --- take item from player's inventory ("take_item"): requires yl_speak_up.npc_privs_priv priv --- r_value the itemstack that will be removed from the player's inventory --- --- move the player to a position ("move"): requires yl_speak_up.npc_privs_priv priv --- r_value the position where the player shall be moved to --- --- execute lua code ("function"): requires npc_master priv --- r_value the lua code that shall be executed --- --- Unlike in preconditions, trade (the trade action already happened) and --- inventory actions are not supported as effects. --- - --- some helper lists for creating the formspecs and evaulating --- the player's answers: - --- general direction of what could make up an effect -local check_what = { - "- please select -", - "an internal state (i.e. of a quest)", -- 2 - "the value of a property of the NPC (for generic NPC)", -- property - "something that has to be calculated or evaluated (=call a function)", -- evaluate - "a block somewhere", -- 3 - "put item from the NPC's inventory into a chest etc.", -- 4 - "take item from a chest etc. and put it into the NPC's inventory", - -- 5 - "an item the player offered to the NPC", - "NPC crafts something", -- 6 - "go to other dialog if the previous effect failed", -- 7 - "send a chat message to all players", -- 8 - "give item (created out of thin air) to player (requires ".. - tostring(yl_speak_up.npc_privs_priv).." priv)", -- 9 - "take item from player and destroy it (requires ".. - tostring(yl_speak_up.npc_privs_priv).." priv)", -- 10 - "move the player to a given position (requires ".. - tostring(yl_speak_up.npc_privs_priv).." priv)", -- 11 - "execute Lua code (requires npc_master priv)", -- 12 -} - --- how to store these as r_type in the precondition: -local values_what = {"", "state", - "property", "evaluate", "block", - -- interact with the inventory of blocks on the map - "put_into_block_inv", "take_from_block_inv", - -- the player gave an item to the NPC; now deal with it somehow - "deal_with_offered_item", - -- crafting, handling failure, send chat message to all - "craft", "on_failure", "chat_all", - -- the following require the yl_speak_up.npc_privs_priv priv: - "give_item", "take_item", "move", - -- the following require the npc_master priv: - "function", - } - --- unlike in the preconditions, the "I cannot punch it" option is --- not offered here - because the player (and later the NPC) needs --- to be able to build at this position -local check_block = { - "- please select -", -- 1 - "If there is air: Place a block so that it looks like now.", -- 2 - "If there is a block: Dig it.", -- 3 - "Punch the block.", -- 4 - "Right-click the block.", -- 5 -} - --- how to store these as p_value (the actual node data gets stored as p_node, p_param2 and p_pos): -local values_block = {"", "place", "dig", "punch", "right-click"} - --- comparison operators for variables -local check_operator = { - "- please select -", -- 1 - "new value:", -- 2 - "discard/unset/forget", -- 3 - "current time", -- 4 - "quest step completed:", -- 5 - minetest.formspec_escape("max(current, new_value)"), -- 6 - minetest.formspec_escape("min(current, new_value)"), -- 7 - "increment by:", -- 8 - "decrement by:", -- 9 -} - --- how to store these as r_value (the actual variable is stored in r_variable, and the value in r_new_value): -local values_operator = {"", "set_to", "unset", "set_to_current_time", - "quest_step", "maximum", "minimum", "increment", "decrement"} - - --- get the list of variables the player has *write* access to -yl_speak_up.get_sorted_player_var_list_write_access = function(pname) - local var_list = {} - -- some values - like hour of day or HP of the player - can be read in - -- a precondition but not be modified - -- get the list of variables the player can *write* - local tmp = yl_speak_up.get_quest_variables_with_write_access(pname) - -- sort that list (the dropdown formspec element returns just an index) - table.sort(tmp) - for i, v in ipairs(tmp) do - table.insert(var_list, v) - end - return var_list -end - - --- helper function for yl_speak_up.show_effect --- used by "state" and "property" -yl_speak_up.show_effect_with_operator = function(r, var_name) - if(not(r.r_operator)) then - return "Error: Operator not defined." - elseif(r.r_operator == "set_to") then - return "set "..var_name.." to value \"".. - tostring(r.r_var_cmp_value).."\"" - elseif(r.r_operator == "unset") then - return "discard "..var_name.." (unset)" - elseif(r.r_operator == "set_to_current_time") then - return "set "..var_name.." to the current time" - elseif(r.r_operator == "quest_step") then - return "store that the player has completed quest step \"".. - tostring(r.r_var_cmp_value).."\"" - elseif(r.r_operator == "maximum") then - return "set "..var_name.." to value \"".. - tostring(r.r_var_cmp_value).."\" if its current value is larger than that" - elseif(r.r_operator == "minimum") then - return "set "..var_name.." to value \"".. - tostring(r.r_var_cmp_value).."\" if its current value is lower than that" - elseif(r.r_operator == "increment") then - return "increment the value of "..var_name.." by \"".. - tostring(r.r_var_cmp_value).."\"" - elseif(r.r_operator == "decrement") then - return "decrement the value of "..var_name.." by \"".. - tostring(r.r_var_cmp_value).."\"" - else - return "ERROR: Wrong operator \""..tostring(r.r_operator).."\" for "..var_name - end -end - - --- returns a human-readable text as description of the effects --- (as shown in the edit options dialog and in the edit effect formspec) -yl_speak_up.show_effect = function(r, pname) - if(not(r.r_type) or r.r_type == "") then - return "(nothing): Nothing to do. No effect." - elseif(r.r_type == "give_item") then - return "give_item: Add \""..tostring(r.r_value).."\" to the player's inventory." - elseif(r.r_type == "take_item") then - return "take_item: Take \""..tostring(r.r_value).."\" from the player's inventory." - elseif(r.r_type == "move") then - return "move: Move the player to "..tostring(r.r_value).."." - elseif(r.r_type == "function") then - return "function: execute \""..tostring(r.r_value).."\"." - elseif(r.r_type == "trade") then - return "trade: obsolete (now defined as an action)" - elseif(r.r_type == "dialog") then - return "Switch to dialog \""..tostring(r.r_value).."\"." - elseif(r.r_type == "state") then - local var_name = "VARIABLE[ - ? - ]" - if(r.r_variable) then - var_name = "VARIABLE[ "..tostring( - yl_speak_up.strip_pname_from_var(r.r_variable, pname)).." ]" - end - return yl_speak_up.show_effect_with_operator(r, var_name) - -- the value of a property of the NPC (for generic NPC) ("property"): - elseif(r.r_type == "property") then - local var_name = "PROPERTY[ "..tostring(r.r_value or "- ? -").." ]" - return yl_speak_up.show_effect_with_operator(r, var_name) - -- something that has to be calculated or evaluated (=call a function) ("evaluate"): - elseif(r.r_type == "evaluate") then - local str = "" - for i = 1, 9 do - str = str..tostring(r["r_param"..tostring(i)]) - if(i < 9) then - str = str.."," - end - end - return "FUNCTION["..tostring(r.r_value).."]("..str..")" - elseif(r.r_type == "block") then - if(not(r.r_pos) or type(r.r_pos) ~= "table" - or not(r.r_pos.x) or not(r.r_pos.y) or not(r.r_pos.z)) then - return "ERROR: r.r_pos is "..minetest.serialize(r.r_pos) - -- we don't check here yet which node is actually there - that will be done upon execution - elseif(yl_speak_up.check_blacklisted(r.r_value, r.r_node, r.r_node)) then - return "ERROR: Blocks of type \""..tostring(r.r_node).."\" do not allow ".. - "interaction of type \""..tostring(r.r_value).."\" for NPC." - elseif(r.r_value == "place") then - return "Place \""..tostring(r.r_node).."\" with param2: "..tostring(r.r_param2).. - " at "..minetest.pos_to_string(r.r_pos).."." - elseif(r.r_value == "dig") then - return "Dig the block at "..minetest.pos_to_string(r.r_pos).."." - elseif(r.r_value == "punch") then - return "Punch the block at "..minetest.pos_to_string(r.r_pos).."." - elseif(r.r_value == "right-click") then - return "Right-click the block at "..minetest.pos_to_string(r.r_pos).."." - else - return "ERROR: Don't know what to do with the block at ".. - minetest.pos_to_string(r.r_pos)..": \""..tostring(r.r_value).."\"?" - end - elseif(r.r_type == "craft") then - -- this is only shown in the edit options menu and when editing an effect; - -- we can afford a bit of calculation here (it's not a precondtion...) - if(not(r.r_value) or not(r.r_craft_grid)) then - return "ERROR: Crafting not configured correctly." - end - local craft_str = "Craft \""..tostring(r.r_value).."\" from ".. - table.concat(r.r_craft_grid, ", ").."." - -- check here if the craft receipe is broken - local input = {} - input.items = {} - for i, v in ipairs(r.r_craft_grid) do - input.items[ i ] = ItemStack(v or "") - end - input.method = "normal" -- normal crafting; no cooking or fuel or the like - input.width = 3 - local output, decremented_input = minetest.get_craft_result(input) - if(output.item:is_empty()) then - return "Error: Recipe changed! No output for "..craft_str - end - -- the craft receipe may have changed in the meantime and yield a diffrent result - local expected_stack = ItemStack(r.r_value) - if(output.item:get_name() ~= expected_stack:get_name() - or output.item:get_count() ~= expected_stack:get_count()) then - return "Error: Amount of output changed! "..craft_str - end - return craft_str - elseif(r.r_type == "on_failure") then - return "If the *previous* effect failed, go to dialog \""..tostring(r.r_value).. "\"." - elseif(r.r_type == "chat_all") then - return "Send chat message: \""..tostring(r.r_value).."\"" - elseif(r.r_type == "put_into_block_inv") then - if(not(r.r_pos) or type(r.r_pos) ~= "table" - or not(r.r_pos.x) or not(r.r_pos.y) or not(r.r_pos.z)) then - return "ERROR: r.r_pos is "..minetest.serialize(r.r_pos) - end - return "Put item \""..tostring(r.r_itemstack).."\" from NPC inv into block at ".. - minetest.pos_to_string(r.r_pos).. - " in inventory list \""..tostring(r.r_inv_list_name).."\"." - elseif(r.r_type == "take_from_block_inv") then - if(not(r.r_pos) or type(r.r_pos) ~= "table" - or not(r.r_pos.x) or not(r.r_pos.y) or not(r.r_pos.z)) then - return "ERROR: r.r_pos is "..minetest.serialize(r.r_pos) - end - return "Take item \""..tostring(r.r_itemstack).."\" from block at ".. - minetest.pos_to_string(r.r_pos).. - " out of inventory list \""..tostring(r.r_inv_list_name).. - "\" and put it into the NPC's inventory." - elseif(r.r_type == "deal_with_offered_item") then - local nr = 1 - if(r.r_value) then - nr = math.max(1, table.indexof(yl_speak_up.dropdown_values_deal_with_offered_item, - r.r_value)) - return yl_speak_up.dropdown_list_deal_with_offered_item[ nr ] - end - return "ERROR: Missing subtype r.r_value: \""..tostring(r.r_value).."\"" - end - -- fallback - return tostring(r.r_value) -end - --- these are only wrapper functions for those in fs_edit_general.lua - -yl_speak_up.input_edit_effects = function(player, formname, fields) - return yl_speak_up.handle_input_fs_edit_option_related(player, formname, fields, - "r_", "o_results", yl_speak_up.max_result_effects, - "(Ef)fect", "tmp_result", - "Please punch the block you want to manipulate in your effect!", - values_what, values_operator, values_block, {}, {}, - check_what, check_operator, check_block, {}, {}, - -- player variables with write access - yl_speak_up.get_sorted_player_var_list_write_access, - "edit_effects" - ) -end - -yl_speak_up.get_fs_edit_effects = function(player, table_click_result) - return yl_speak_up.build_fs_edit_option_related(player, table_click_result, - "r_", "o_results", yl_speak_up.max_result_effects, - "(Ef)fect", "tmp_result", - "What do you want to change with this effect?", - values_what, values_operator, values_block, {}, {}, - check_what, check_operator, check_block, {}, {}, - -- player variables with write access - yl_speak_up.get_sorted_player_var_list_write_access, - yl_speak_up.show_effect, - "table_of_elements", - "Change the value of the following variable:", "Set variable to:", "New value:", - "The NPC shall do something to the block at the following position:" - ) -end - - -yl_speak_up.register_fs("edit_effects", - yl_speak_up.input_edit_effects, - yl_speak_up.get_fs_edit_effects, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_edit_options_dialog.lua b/editor/fs/fs_edit_options_dialog.lua deleted file mode 100644 index 16eaa38..0000000 --- a/editor/fs/fs_edit_options_dialog.lua +++ /dev/null @@ -1,853 +0,0 @@ - --- helper function; used by --- * yl_speak_up.get_fs_edit_option_dialog and --- * yl_speak_up.get_fs_edit_trade_limit -yl_speak_up.get_list_of_effects_and_target_dialog_and_effect = function(dialog, results, pname, target_dialog, target_effect) - local list_of_effects = "" - local count_effects = 0 - 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 or v.r_value == "d_end" or v.r_value == "d_got_item") then - list_of_effects = list_of_effects.. - minetest.formspec_escape(v.r_id)..",#999999,".. - minetest.formspec_escape(v.r_type)..",".. - minetest.formspec_escape( - yl_speak_up.show_effect(v, pname)).."," - -- there may be more than one in the data structure - target_dialog = v.r_value - target_effect = v - 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( - yl_speak_up.show_effect(v, pname)).."," - end - count_effects = count_effects + 1 - end - end - if(count_effects < yl_speak_up.max_result_effects) then - list_of_effects = list_of_effects..",#00FF00,add,Add a new (Ef)fect" - else - list_of_effects = list_of_effects..",#AAAAAA,-,".. - "Maximum amount of allowed (Ef)fects per option reached!" - end - return {list = list_of_effects, target_dialog = target_dialog, target_effect = target_effect} -end - - --- 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)) 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 - local o_id = yl_speak_up.speak_to[pname].o_id - - local dialog = yl_speak_up.speak_to[pname].dialog - local n_dialog = dialog.n_dialogs[d_id] - if(not(n_dialog) or not(n_dialog.d_options)) then - return - end - local d_option = n_dialog.d_options[o_id] - if(not(d_option)) then - return - end - - if(fields.assign_quest_step and fields.assign_quest_step ~= "") then - yl_speak_up.show_fs(player, "assign_quest_step", - {n_id = n_id, d_id = d_id, o_id = o_id}) - return - end - - if(fields.switch_tab and fields.switch_tab == "2") then - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, - caller="show_if_action_failed"}) - return - elseif(fields.switch_tab and fields.switch_tab == "1") then - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, - caller="show_if_action_succeeded"}) - return - elseif(fields.switch_tab and fields.switch_tab == "3") then - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, - caller="show_tab_limit_guessing"}) - return - elseif(fields.switch_tab and fields.switch_tab == "4") then - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, - caller="show_tab_limit_repeating"}) - return - end - - -- this menu is specific to an option for a dialog; if no dialog is selected, we really - -- can't know what to do - if(not(o_id) and d_id) then - yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id}) - elseif(not(d_id)) then - return - end - - -- backwards compatibility to when this was a hidden field - fields.o_id = o_id - -- 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 - - if(fields.save_option) then - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, caller="save_option"}) - return - end - - -- want to edit the text that is shown when switching to the next dialog? - if(fields.button_edit_action_failed_dialog - or fields.button_edit_action_success_dialog - or fields.save_dialog_modification - or fields.button_edit_limit_action_failed_repeat - or fields.button_edit_limit_action_success_repeat - or fields.turn_alternate_text_into_new_dialog) then - if( yl_speak_up.handle_edit_actions_alternate_text( - -- x_id, id_prefix, target_element and tmp_data_cache are nil here - player, pname, n_id, d_id, o_id, nil, nil, - "edit_option_dialog", nil, fields, nil)) then - -- the function above showed a formspec already - return - else - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, - caller="back_from_edit_dialog_modifications"}) - return - end - - elseif(fields.back_from_edit_dialog_modification) then - -- no longer working on an alternate text - yl_speak_up.speak_to[pname].edit_alternate_text_for = nil - yl_speak_up.show_fs(player, "edit_option_dialog", - {n_id = n_id, d_id = d_id, o_id = o_id, caller="back_from_edit_dialog_modifications"}) - 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 - - -- the player wants to see the previous option/answer - if(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 - - -- the player clicked on a precondition - elseif(fields.table_of_preconditions) then - yl_speak_up.show_fs(player, "edit_preconditions", fields.table_of_preconditions) - return - - -- the player clicked on an action - elseif(fields.table_of_actions) then - yl_speak_up.show_fs(player, "edit_actions", fields.table_of_actions) - return - - -- the player clicked on an effect - elseif(fields.table_of_effects) then - yl_speak_up.show_fs(player, "edit_effects", fields.table_of_effects) - return - 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, caller) - -- 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] - - -- 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(n_dialog) or not(n_dialog.d_options) or not(n_dialog.d_options[o_id])) 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 - local d_option = n_dialog.d_options[o_id] - - -- if it is a quest step, then show that; else allow creating a quest step - local quest_step_text = "button[15.4,0.1;6.0,0.9;assign_quest_step;Turn this into a quest step]" - if( d_option.quest_id and d_option.quest_id ~= "" - and d_option.quest_step and d_option.quest_step ~= "") then - local q_id = "" - local quest_name = "["..tostring(d_option.quest_id).."] - unknown quest -" - for q_id, data in pairs(yl_speak_up.quests) do - if(data and data.var_name == d_option.quest_id) then - quest_name = "["..tostring(q_id)..": ".. - tostring(yl_speak_up.strip_pname_from_var(data.var_name, pname)).. - "] ".. - tostring(data.name) - end - end - quest_step_text = table.concat({"box[4.9,0.0;14.0,1.1;#BB77BB]", - "label[0.2,0.3;This is quest step:]", - "label[5.0,0.3;", - minetest.colorize("#00FFFF", - minetest.formspec_escape(d_option.quest_step)), - "]", - "label[0.2,0.8;of the quest:]", - "label[5.0,0.8;", - minetest.colorize("#CCCCFF", - minetest.formspec_escape(quest_name)), - "]", - "button[19.4,0.1;2.0,0.9;assign_quest_step;Change]" - }, "") - 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 - - local answer_mode = 0 - -- shall this option be choosen automaticly? - if(d_option.o_autoanswer and d_option.o_autoanswer == 1) then - answer_mode = 1 - -- or randomly? - elseif(n_dialog.o_random) then - answer_mode = 2 - end - - -- show an option only once - local visit_only_once = 0 - if(d_option.o_visit_only_once and d_option.o_visit_only_once == 1) then - visit_only_once = 1 - end - - local answer_text = - -- answer of the player (the actual option) - "container[0.0,8.3]".. - "label[0.2,0.0;..the player may answer with this text".. - minetest.formspec_escape(" [dialog option \""..tostring(o_id).."\"]:").."]".. - "dropdown[13.3,-0.4;2.5,0.7;option_visits;".. - "often,*once*;"..tostring(visit_only_once + 1)..";]".. - "tooltip[option_visits;\"often\" allows to select this option whenever the\n".. - "\tpreconditions are fulfilled.\n".. - "\"*once*\" greys out the option after it has been selected\n".. - "\tone time successfully.\n".. - "Useful for visually marking options as read for the player.\n".. - "Talking to the NPC anew resets this option and it can be selected again.]".. - "dropdown[16.0,-0.4;5.3,0.7;option_autoanswer;".. - "by clicking on it,automaticly,randomly;"..tostring(answer_mode+1)..";]" - -- (automaticly *by fulfilling the prerequirements*) - if(d_id == "d_got_item" or d_id == "d_trade") then - answer_mode = 1 - d_option.o_autoanswer = 1 - answer_text = - "container[0.0,8.3]".. - "label[0.2,0.0;..this option will be selected automaticly.]" - end - if(answer_mode == 0 and (d_id ~= "d_got_item" and d_id ~= "d_trade")) then - answer_text = table.concat({answer_text, - "label[1.2,0.8;A:]", - "field[1.7,0.3;19.6,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,1.7;..but if at least one pre(C)ondition is not fulfilled, then...]", - "dropdown[12.0,1.3;9.3,0.7;hide_or_grey_or_alternate_answer;", - "..hide this answer.,", - "..grey out the following answer:,", - "..display the following alternate answer:;", - alternate_answer_option, - ";]", - -- alternate answer - "label[1.2,2.5;A:]", - "field[1.7,2.0;19.6,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.]", - "container_end[]" - }, "") - elseif(answer_mode == 1) then - answer_text = answer_text.. - "label[1.2,0.8;This option will not be shown but will be selected automaticly if all ".. - "prerequirements are fullfilled.]".. - "label[1.2,1.4;The remaining options of this dialog will in this case not be evaluated.]".. - "label[1.2,2.0;The NPC will proceed as if this option was choosen manually.]".. - "label[1.2,2.6;" - if(d_id == "d_got_item") then - answer_text = answer_text.. - "Note: This is used here to process items that the player gave to the NPC." - elseif(d_id == "d_trade") then - answer_text = answer_text.. - "Note: This is useful for refilling stock by crafting new things when ".. - "necessary, or for getting\nsupplies from a storage, or for storing ".. - "traded goods in external storage chests." - else - answer_text = answer_text.. - "This is i.e. useful for offering a diffrent start dialog depending on the ".. - "player's progress in a quest." - end - answer_text = answer_text .. "]container_end[]" - elseif(answer_mode == 2) then - answer_text = answer_text.. - "label[1.2,0.8;One option of the dialog - for example this one - will be selected randomly.]".. - "label[1.2,1.4;The other options of this dialog will be set to random as well.]".. - "label[1.2,2.0;The NPC will proceed as if this dialog was choosen manually.]".. - "label[1.2,2.6;Useful for small talk for generic NPC but usually not for quests.]".. - "container_end[]" - end - - -- remember which option we are working at (better than a hidden field) - yl_speak_up.speak_to[pname].o_id = o_id - -- are there any preconditions? - local list_of_preconditions = "" - local prereq = d_option.o_prerequisites - local count_prereq = 0 - 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( - yl_speak_up.show_precondition(v, pname)).."," - count_prereq = count_prereq + 1 - end - end - if(count_prereq < yl_speak_up.max_prerequirements) then - list_of_preconditions = list_of_preconditions..",#00FF00,add,Add a new pre(C)ondition" - else - list_of_preconditions = list_of_preconditions..",#AAAAAA,-,".. - "Maximum amount of pre(C)onditions per option reached!" - end - - -- build action list the same way as list of preconditions and effects - local list_of_actions = "" - local actions = d_option.actions - local count_actions = 0 - local action_data = nil - -- if autoanswer or random is choosen, then there can be no action - if(answer_mode == 1 or answer_mode == 2) then - actions = nil - count_actions = 0 - caller = "" - end - if(actions) then - local sorted_key_list = yl_speak_up.sort_keys(actions) - for i, k in ipairs(sorted_key_list) do - local v = actions[ k ] - list_of_actions = list_of_actions.. - minetest.formspec_escape(v.a_id)..",#FFFF00,".. - minetest.formspec_escape(v.a_type)..",".. - minetest.formspec_escape( - yl_speak_up.show_action(v)).."," - count_actions = count_actions + 1 - action_data = v - end - end - if(count_actions < yl_speak_up.max_actions) then - list_of_actions = list_of_actions..",#00FF00,add,Add a new (A)ction" - else - list_of_actions = list_of_actions..",#AAAAAA,-,".. - "Maximum amount of (A)ctions per option reached!" - end - - -- list of (A)ctions (there can only be one per option; i.e. a trade) - local action_list_text = - "container[0.0,12.0]".. - "label[0.2,0.0;When this answer has been selected, start the following (A)ction:]".. - "tablecolumns[text;color,span=1;text;text]" - if(answer_mode == 1) then - action_list_text = action_list_text.. - "label[1.2,0.6;No actions are executed because this option here is automaticly selected.]".. - "container_end[]" - elseif(answer_mode == 2) then - action_list_text = action_list_text.. - "label[1.2,0.6;No actions are executed because this option here is selected randomly.]".. - "container_end[]" - else - action_list_text = action_list_text.. - "table[1.2,0.3;20.2,0.7;table_of_actions;".. - list_of_actions..";0]".. - "container_end[]" - end - - -- find the right target dialog for this option (if it exists) - local target_dialog = nil - -- which effect holds the information about the target dialog? - -- set this to a fallback for yl_speak_up.show_colored_dialog_text - local target_effect = {r_id = "-?-", r_type = "dialog"} - -- and build the list of effects - local results = d_option.o_results - -- create a new dialog type option if needed - if(not(results) or not(next(results))) then - target_dialog = yl_speak_up.prepare_new_dialog_for_option( - dialog, pname, n_id, d_id, o_id, - yl_speak_up.text_new_dialog_id, - results) - -- make sure we are up to date (a new option was inserted) - results = d_option.o_results - end - -- constructs the list_of_effects; may also update target_dialog and target_effect - local res = yl_speak_up.get_list_of_effects_and_target_dialog_and_effect(dialog, results, pname, - target_dialog, target_effect) - local list_of_effects = res.list - target_dialog = res.target_dialog - target_effect = res.target_effect - - -- 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]) - and target_dialog ~= "d_end" - and target_dialog ~= "d_got_item")) 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 - -- 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 - local d_name = (v.d_name or v.d_id or "?") - -- build the list of available dialogs for the dropdown list(s) - dialog_list = dialog_list..","..minetest.formspec_escape(d_name) - -- which one is the current dialog? - n = n + 1 - if(v.d_id == target_dialog) then - dialog_selected = tostring(n) - end - end - if(target_dialog == "d_end") then - dialog_selected = tostring(n + 1) - end - end - dialog_list = dialog_list..",d_end" - if(not(target_dialog)) then - target_dialog = "- none -" - 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 - -- the buttons are inside a container; thus, Y is 0.0 - if(o == o_id and sorted_list[ i-1 ]) then - button_prev = "".. - "button[7.9,0.0;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.5,0.0;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 = "".. - -- the buttons are inside a container; thus, Y is 0.0 - "button[2.4,0.0;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 - or target_dialog == "d_end") then - button_add = "" - end - - -- make all following coordinates relative - local action_text = "container[0.2,14.0]".. - "box[0.25,0.0;21.0,6.7;#555555]" - local tab_list = "tabheader[0.2,0.0;switch_tab;".. - "If the action was successful:,".. - "If the action failed:,".. - "Limit guessing:,".. - "Limit repeating:" - -- show what happens if the action fails - if(caller == "show_if_action_failed") then - -- allow to switch between successful and failed actions - action_text = action_text..tab_list..";2;true;true]".. - "label[0.4,0.6;".. - "If the player *failed* to complete the above action correctly,]" - if(action_data and action_data.a_on_failure - and dialog.n_dialogs and dialog.n_dialogs[ action_data.a_on_failure]) then - action_text = action_text.. - -- ..and what the NPC will reply to that answer - "tooltip[1.2,3.9;19.6,2.5;This is what the NPC will say next when ".. - "the player has failed to complete the action.]".. - - "container[0.0,3.2]".. - "label[0.4,0.4;..the NPC will react to this failed action with the ".. - "following dialog \""..tostring(action_data.a_on_failure).. - "\"".. - yl_speak_up.show_colored_dialog_text( - dialog, - action_data, - action_data.a_on_failure, - "1.2,0.7;19.6,2.5;d_text_next", - "with the *modified* text", - ":]", - "button_edit_action_failed_dialog").. - "container_end[]" - else - action_text = action_text.. - "label[0.4,3.6;..go back to the initial dialog.]" - end - -- show time-based restrictions (max guesses per time); - -- the values will be saved in function yl_speak_up.edit_mode_apply_changes - elseif( caller == "show_tab_limit_guessing") then - local timer_name = "timer_on_failure_"..tostring(d_id).."_"..tostring(o_id) - local timer_data = yl_speak_up.get_variable_metadata(timer_name, "parameter", true) - if(not(timer_data)) then - timer_data = {} - end - action_text = table.concat({action_text, - tab_list, - ";3;true;true]", - -- allow to switch between successful and failed actions - "label[0.4,0.6;", - "Apply the following time-based restrictions to limit wild guessing:]", - -- timer for failed actions - "label[0.4,1.6;The player can make]", - "field[4.9,1.0;1.5,0.9;timer_max_attempts_on_failure;;", - tostring(timer_data[ "max_attempts" ] or 0), - "]", - "label[6.7,1.6;attempts to complete this action successfully each]", - "field[17.5,1.0;1.5,0.9;timer_max_seconds_on_failure;;", - tostring(timer_data[ "duration" ] or 0), - "]", - "label[19.2,1.6;seconds.]", - "label[0.4,2.2;Hint: 3 attempts per 1200 seconds (=20 minutes or one MineTest day)".. - " may be good values to\navoid wild guessing while not making the player ".. - "having to wait too long to try again.]".. - "tooltip[timer_max_attempts_on_failure;How many tries shall the player have?".. - "\nA value of 0 disables this restriction.]".. - "tooltip[timer_max_seconds_on_failure;After which time can the player try again?".. - "\nA value of 0 disables this restriction.]".. - -- ..and what the NPC will explain in such a case - "tooltip[1.2,3.9;19.6,2.5;This is what the NPC will say next when ".. - "\nthe player has failed to complete the action too".. - "\nmany times for the NPC's patience and the player".. - "\nhas to wait some time before guessing again.]".. - "container[0.0,3.2]".. - "label[0.4,0.4;The NPC will explain his unwillingness to accept more ".. - "guesses ", - yl_speak_up.show_colored_dialog_text( - dialog, - {alternate_text = (timer_data[ "alternate_text" ] - or yl_speak_up.standard_text_if_action_failed_too_often)}, - d_id, -- show the same dialog again - "1.2,0.7;19.6,2.5;d_text_next", - "with the following text", - ":]", - "button_edit_limit_action_failed_repeat"), - "container_end[]" - }, "") - -- show time-based restrictions (time between repeating this action successfully) - elseif( caller == "show_tab_limit_repeating") then - local timer_name = "timer_on_success_"..tostring(d_id).."_"..tostring(o_id) - local timer_data = yl_speak_up.get_variable_metadata(timer_name, "parameter", true) - if(not(timer_data)) then - timer_data = {} - end - action_text = table.concat({action_text, - tab_list, - ";4;true;true]", - "label[0.4,0.6;", - "Apply the following time-based restrictions to limit too quick repeating:]", - -- timer for successful actions - "label[0.4,1.6;If the player completed the action successfully, he shall have to".. - " wait]", - "field[15.0,1.0;1.5,0.9;timer_max_seconds_on_success;;", - tostring(timer_data[ "duration" ] or 0), - "]", - "label[16.7,1.6;seconds until he]", - "label[0.4,2.1;can repeat the action. Hint: 1200 seconds (=20 minutes or one ", - "MineTest day) may be a good value.]", - "tooltip[timer_max_seconds_on_success;", - minetest.formspec_escape( - "If you hand out a quest item, you may not want the player".. - "\nto immediately repeat the action countless times, thus".. - "\nemptying the NPC's storage and using the quest item for".. - "\nother purposes. On the other hand, quest items may get ".. - "\nlost, so the player needs a way to repeat each step.".. - "\n1200 seconds may be a good value here as well."), - "]", - -- ..and what the NPC will explain in such a case - "tooltip[1.2,3.9;19.6,2.5;", - minetest.formspec_escape( - "This is what the NPC will say next when the player".. - "\nwants to repeat the action too soon for the NPC's".. - "\ntaste - after all the NPC does not have infinite ".. - "\ninventory ressources, and the player may abuse the ".. - "\nquest item for entirely diffrent purposes.."), - "]", - "container[0.0,3.2]", - -- this will lead back to the same dialog - "label[0.4,0.4;The NPC will explain his unwillingness to repeat the ".. - "action so soon ", - yl_speak_up.show_colored_dialog_text( - dialog, - {alternate_text = (timer_data[ "alternate_text" ] - or yl_speak_up.standard_text_if_action_repeated_too_soon)}, - d_id, -- show the same dialog again - "1.2,0.7;19.6,2.5;d_text_next", - "with the following text", - ":]", - "button_edit_limit_action_success_repeat"), - "container_end[]" - }, "") - -- show what happens if the action was successful - else - -- no action defined - if(count_actions == 0) then - -- do not show tabheader - action_text = action_text.. - "label[0.4,0.6;".. - "There is no (A)ction defined. Directly apply the following (Ef)fects:]" - else - -- allow to switch between successful and failed actions - action_text = table.concat({action_text, - tab_list, - ";1;true;true]", - "label[0.4,0.6;", - "If the player completed the above action successfully, ".. - "apply the following (Ef)fects:]" - }, "") - end - action_text = table.concat({action_text, - -- list of effects - "tablecolumns[text;color,span=1;text;text]", - "table[1.2,0.9;19.6,2.0;table_of_effects;", - list_of_effects, - ";0]", - "tooltip[1.2,0.9;19.6,2.0;".. - "*All* (Ef)fects are executed after the action (if there is\n".. - "one defined in this option) has been completed successfully\n".. - "by the player. If there is no action defined, then the\n".. - "(Ef)fects will always be executed when this option here is\n".. - "selected.\n".. - "Please click on an (Ef)fect in order to edit or delete it!]", - "container[0.0,3.2]", - "label[0.4,0.4;The NPC will react to this answer with dialog:]" - }, "") - if(d_id == "d_trade") then - action_text = action_text.. - "label[13.5,0.4;..by showing his trade list.]".. - "container_end[]" - else - action_text = table.concat({action_text, - -- allow to change the target dialog via a dropdown menu - "dropdown[11,0.0;9.8,0.7;d_id_", - minetest.formspec_escape(o_id), - ";", - dialog_list, - ";", - dialog_selected, - ",]", - "tooltip[10.2,0.0;3.0,0.7;Select the target dialog with which the NPC shall react ".. - "to this answer.\nCurrently, dialog \"", - minetest.formspec_escape(target_dialog), - "\" is beeing displayed.;#FFFFFF;#000000]", - -- ..and what the NPC will reply to that answer - "tooltip[1.2,0.7;19.6,2.5;This is what the NPC will say next when the player has ".. - "selected this answer here.]", - yl_speak_up.show_colored_dialog_text( - dialog, - -- this is either the "dialog" effect or an empty fallback - target_effect, - -- this is the text the NPC will say in reaction to this answer - target_dialog, - "1.2,0.7;19.6,2.5;d_text", - "label[13.5,0.4;with the following *modified* text:]", - "", - "button_edit_action_success_dialog"), - "container_end[]" - }, "") - end - end - action_text = action_text.."container_end[]" - - -- build up the formspec - local formspec = table.concat({ - "size[22,22]", - "bgcolor[#00000000;false]", - -- button back to the current dialog (of which this is an option) - "button[16.4,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.]", - -- tell the player what this formspec is about - "label[6.5,0.4;You are editing dialog option \"", - tostring(o_id), - "\":]", - - -- the text the NPC says - "container[0.0,0.9]", - "label[0.2,0.0;NPC says ", - minetest.formspec_escape("[dialog \""..tostring(d_id).."\"]:"), - "]", - yl_speak_up.show_colored_dialog_text( - dialog, - {r_id = "", r_type = "dialog"}, - d_id, - "1.2,0.3;20.2,2.5;d_text", - "", -- no modifications possible at this step - "", - ""), -- no edit button here as this text cannot be changed here - "tooltip[1.2,0.3;20.2,3.0;This is what the NPC says to the player.]", - "container_end[]", - - "container[0.0,3.9]", - quest_step_text, - "container_end[]", - - -- list the preconditions - "container[0.0,5.4]", - "label[0.2,0.0;If all of the following pre(C)onditions are fulfilled:]", - "tablecolumns[text;color,span=1;text;text]", - "table[1.2,0.3;20.2,2.0;table_of_preconditions;", - list_of_preconditions, - ";0]", - "tooltip[1.2,0.3;20.2,2.0;", - "*All* pre(C)onditions need to be true in order\n".. - "for the option to be offered to the player.\n".. - "Please click on a pre(C)ondition in order\n".. - "to edit or delete it!]", - "container_end[]", - - -- answer of the player (the actual option) - answer_text, - - -- list of (A)ctions (there can only be one per option; i.e. a trade) - action_list_text, - - -- list effects and target dialog for successful - and target dialog for unsuccessful - -- actions (including a toggle button) - action_text, - - -- container for the buttons/footer - "container[0.0,20.9]", - -- button: delete - "button[0.2,0.0;2.0,0.9;del_option;Delete]", - "tooltip[del_option;Delete this option/answer.]", - -- button: add new - button_add, - -- button: save - "button[4.6,0.0;2.0,0.9;save_option;Save]", - "tooltip[save_option;Save what you canged (or discard it).]", - -- button: prev/next - button_prev, - button_next, - -- button: go back to dialog (repeated from top of the page) - "button[15.8,0.0;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[10.1,0.5;Sort:]", - "field[11.1,0.0;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]", - "container_end[]" - }, "") - return formspec -end - - -yl_speak_up.get_fs_edit_option_dialog_wrapper = function(player, param) - if(not(param)) then - param = {} - end - local pname = player:get_player_name() - yl_speak_up.speak_to[pname].o_id = param.o_id - return yl_speak_up.get_fs_edit_option_dialog(player, param.n_id, param.d_id, param.o_id, param.caller) -end - - -yl_speak_up.register_fs("edit_option_dialog", - yl_speak_up.input_edit_option_dialog, - yl_speak_up.get_fs_edit_option_dialog_wrapper, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_edit_preconditions.lua b/editor/fs/fs_edit_preconditions.lua deleted file mode 100644 index 63c4758..0000000 --- a/editor/fs/fs_edit_preconditions.lua +++ /dev/null @@ -1,377 +0,0 @@ --- This file contains what is necessary to add/edit a precondition. --- --- Which diffrent types of preconditions are available? --- -> The following fields are part of a precondition: --- p_id the ID/key of the precondition/prerequirement --- p_type selected from values_what --- p_value used to store the subtype of p_type --- --- a state/variable ("state"): --- p_variable name of a variable the player has read access to; --- dropdown list with allowed options --- p_operator selected from values_operator --- p_var_cmp_value can be set freely by the player --- --- the value of a property of the NPC (for generic NPC) ("property"): --- p_value name of the property that shall be checked --- p_operator operator for cheking the property against p_expected_val --- p_var_cmp_value the expected value of the property --- --- something that has to be calculated or evaluated (=call a function) ("evaluate"): --- p_value the name of the function that is to be called --- p_param1 the first paramter (optional; depends on function) --- .. --- p_param9 the 9th parameter (optional; depends on function) --- p_operator operator for checking the result --- p_var_cmp_value compare the result of the function with this value --- --- a block in the world ("block"): --- p_pos a position in the world; determined by asking the player --- to punch the block --- p_node (follows from p_pos) --- p_param2 (follows from p_pos) --- --- a trade defined as an action ("trade"): no variables needed (buy and pay stack --- follow from the trade set as action) --- --- an inventory: ("player_inv", "npc_inv" or "block_inv") --- p_itemstack an itemstack; needs to be a minetest.registered_item[..]; --- size/count is also checked --- --- the inventory of a block on the map: ("block_inv", in addition to the ones above) --- p_pos a position in the world; determined by asking the player --- to punch the block --- p_inv_list_name name of the inventory list of the block --- --- the player offered/gave the NPC an item: ("player_offered_item"): --- p_value an itemstack; needs to be a minetest.registered_item[..]; --- size/count is checked for some subtypes --- p_match_stack_size does the NPC expect exactly one stack size - or is --- more or less etc. also ok? --- p_item_group are items of this group instead of the exact item name --- also acceptable? --- p_item_desc the description of the itemstack (set by another quest NPC --- so that the player can distinguish it from other itemstacks --- with the same item name; see action "npc_gives") --- p_item_quest_id Special ID to make sure that it is really the *right* --- item and not just something the player faked with an --- engraving table or something similar --- --- a function ("function"): requires npc_master to create and edit --- p_value the lua code to execute and evaulate --- --- depends on another option: --- p_value name of the other option of this dialog that is considered --- p_fulfilled shall option p_value be true or false? --- --- the type of the entity of the NPC: --- p_value name of the entity (i.e. npc_talk:talking_npc) - - --- some helper lists for creating the formspecs and evaulating --- the player's answers: - --- general direction of what a prerequirement may be about -local check_what = { - "- please select -", - "an internal state (i.e. of a quest)", -- 2 - "the value of a property of the NPC (for generic NPC)", - "something that has to be calculated or evaluated (=call a function)", - "a block somewhere", -- 3 - "a trade", -- 4 - "the inventory of the player", -- 5 - "the inventory of the NPC", -- 6 - "the inventory of a block somewhere", -- 7 - "an item the player offered/gave to the NPC", -- 8 - "execute Lua code (requires npc_master priv)", -- 7 -> 9 - "The preconditions of another dialog option are fulfilled/not fulfilled.", -- 9 -> 11 - "nothing - always true (useful for generic dialogs)", - "nothing - always false (useful for temporally deactivating an option)", - "the type of the entity of the NPC", -} - --- how to store these as p_type in the precondition: -local values_what = {"", "state", "property", "evaluate", "block", "trade", - "player_inv", "npc_inv", "block_inv", - "player_offered_item", - -- "function" requires npc_master priv: - "function", - -- depends on the preconditions of another option - "other", - "true", "false", - "entity_type"} - --- options for "a trade" -local check_trade = { - "- please select -", - "The NPC has the item(s) he wants to sell in his inventory.", -- 2 - "The player has the item(s) needed to pay the price.", -- 3 - "The NPC ran out of stock.", -- 4 - "The player cannot afford the price.", -- 5 -} - --- how to store these as p_value: -local values_trade = {"", "npc_can_sell", "player_can_buy", "npc_is_out_of_stock", "player_has_not_enough"} - --- options for "the inventory of " (either player or NPC; perhaps blocks later on) -local check_inv = { - "- please select -", - "The inventory contains the following item:", - "The inventory *does not* contain the following item:", - "There is room for the following item in the inventory:", - "The inventory is empty.", -} - --- how to store these as p_value (the actual itemstack gets stored as p_itemstack): -local values_inv = {"", "inv_contains", "inv_does_not_contain", "has_room_for", "inv_is_empty"} - -local check_block = { - "- please select -", - "The block is as it is now.", - "There shall be air instead of this block.", - "The block is diffrent from how it is now.", - "I can't punch it. The block is as the block *above* the one I punched.", -} - --- how to store these as p_value (the actual node data gets stored as p_node, p_param2 and p_pos): --- Note: "node_is_like" occours twice because it is used to cover blocks that --- cannot be punched as well as normal blocks. -local values_block = {"", "node_is_like", "node_is_air", "node_is_diffrent_from", "node_is_like"} - --- comparison operators for variables -local check_operator = { - "- please select -", -- 1 - "== (is equal)", -- 2 - "~= (is not equal)", -- 3 - ">= (is greater or equal)", -- 4 - "> (is greater)", -- 5 - "<= (is smaller or equal)", -- 6 - "< (is smaller)", -- 7 - "not (logically invert)", -- 8 - "is_set (has a value)", -- 9 - "is_unset (has no value)", -- 10 - "more than x seconds ago", -- 11 - "less than x seconds ago", -- 12 - "has completed quest step", -- 13 - "quest step *not* completed", -- 14 -} - --- how to store these as p_value (the actual variable is stored in p_variable, and the value in p_cmp_value): -local values_operator = {"", "==", "~=", ">=", ">", "<=", "<", "not", "is_set", "is_unset", - "more_than_x_seconds_ago","less_than_x_seconds_ago", - "quest_step_done", "quest_step_not_done"} - - - --- get the list of variables the player has read access to -yl_speak_up.get_sorted_player_var_list_read_access = function(pname) - local var_list = {} - -- copy the values that are server-specific - for i, v in ipairs(yl_speak_up.custom_server_functions.precondition_descriptions) do - table.insert(var_list, v) - end - -- get the list of variables the player can read - local tmp = yl_speak_up.get_quest_variables_with_read_access(pname) - -- sort that list (the dropdown formspec element returns just an index) - table.sort(tmp) - for i, v in ipairs(tmp) do - table.insert(var_list, v) - end - return var_list -end - - --- returns a human-readable text as description of the precondition --- (as shown in the edit options dialog and in the edit precondition formspec) -yl_speak_up.show_precondition = function(p, pname) - if(not(p.p_type) or p.p_type == "") then - return "(nothing): Always true." - elseif(p.p_type == "item") then - return "item: The player has \""..tostring(p.p_value).."\" in his inventory." - elseif(p.p_type == "quest") then - return "quest: Always false." - elseif(p.p_type == "auto") then - return "auto: Always true." - elseif(p.p_type == "true") then - return "true: Always true." - elseif(p.p_type == "false") then - return "false: Always false." - elseif(p.p_type == "function") then - return "function: evaluate "..tostring(p.p_value) - elseif(p.p_type == "state") then - local var_name = "VALUE_OF[ - ? - ]" - if(p.p_variable) then - var_name = "VALUE_OF[ "..tostring( - yl_speak_up.strip_pname_from_var(p.p_variable, pname)).." ]" - end - if(not(p.p_operator)) then - return "Error: Operator not defined." - elseif(p.p_operator == "not") then - return "not( "..var_name.." )" - elseif(p.p_operator == "is_set") then - return var_name.." ~= nil (is_set)" - elseif(p.p_operator == "is_unset") then - return var_name.." == nil (is_unset)" - elseif(p.p_operator == "more_than_x_seconds_ago") then - return var_name.." was set to current time ".. - "*more* than "..tostring(p.p_var_cmp_value).." seconds ago" - elseif(p.p_operator == "less_than_x_seconds_ago") then - return var_name.." was set to current time ".. - "*less* than "..tostring(p.p_var_cmp_value).." seconds ago" - elseif(p.p_operator == "quest_step_done") then - return var_name.." shows: player completed quest step \"".. - tostring(p.p_var_cmp_value).."\" successfully" - elseif(p.p_operator == "quest_step_not_done") then - return var_name.." shows: player has not yet completed quest step \"".. - tostring(p.p_var_cmp_value).."\"" - end - if(p.p_var_cmp_value == "") then - return var_name.." "..tostring(p.p_operator).." \"\"" - end - return var_name.." "..tostring(p.p_operator).." ".. - tostring(p.p_var_cmp_value) - elseif(p.p_type == "property") then - local i = math.max(1,table.indexof(values_operator, p.p_operator)) - return tostring(p.p_value).. - " "..tostring(check_operator[i]).. - " "..tostring(p.p_var_cmp_value) - elseif(p.p_type == "evaluate") then - local str = "" - for i = 1, 9 do - str = str..tostring(p["p_param"..tostring(i)]) - if(i < 9) then - str = str.."," - end - end - local i_op = math.max(1,table.indexof(values_operator, p.p_operator)) - return "FUNCTION["..tostring(p.p_value).."]".. - "("..str..") "..tostring(check_operator[i_op]).. - " "..tostring(p.p_var_cmp_value) - elseif(p.p_type == "block") then - if(not(p.p_pos) or type(p.p_pos) ~= "table" - or not(p.p_pos.x) or not(p.p_pos.y) or not(p.p_pos.z)) then - return "ERROR: p.p_pos is "..minetest.serialize(p.p_pos) - elseif(p.p_value == "node_is_like") then - return "The block at "..minetest.pos_to_string(p.p_pos).." is \"".. - tostring(p.p_node).."\" with param2: "..tostring(p.p_param2).."." - elseif(p.p_value == "node_is_air") then - return "There is no block at "..minetest.pos_to_string(p.p_pos).."." - elseif(p.p_value == "node_is_diffrent_from") then - return "There is another block than \""..tostring(p.p_node).."\" at ".. - minetest.pos_to_string(p.p_pos)..", or it is at least ".. - "rotated diffrently (param2 is not "..tostring(p.p_param2)..")." - end - elseif(p.p_type == "trade") then - local nr = table.indexof(values_trade, p.p_value) - if(nr and check_trade[ nr ]) then - return check_trade[ nr ] - end - elseif(p.p_type == "player_inv" or p.p_type == "npc_inv" or p.p_type == "block_inv") then - local who = "The player" - local what = "\""..tostring(p.p_itemstack).."\" in his inventory." - if(p.p_type == "npc_inv") then - who = "The NPC" - elseif(p.p_type == "block_inv") then - if(not(p.p_pos) or type(p.p_pos) ~= "table" - or not(p.p_pos.x) or not(p.p_pos.y) or not(p.p_pos.z)) then - return "ERROR: p.p_pos is "..minetest.serialize(p.p_pos) - end - who = "The block at "..minetest.pos_to_string(p.p_pos) - what = "\""..tostring(p.p_itemstack).."\" in inventory list \"".. - tostring(p.p_inv_list_name).."\"." - end - if(p.p_value == "inv_contains") then - return who.." has "..what - elseif(p.p_value == "inv_does_not_contain") then - return who.." does not have "..what - elseif(p.p_value == "has_room_for") then - return who.." has room for "..what - elseif(p.p_value == "inv_is_empty") then - if(p.p_type == "block_inv") then - return who.." has an empty inventory list \"".. - tostring(p.p_inv_list_name).."\"." - end - return who.." has an empty inventory." - end - elseif(p.p_type == "player_offered_item") then - local item = tostring(p.p_value:split(" ")[1]) - local amount = tostring(p.p_value:split(" ")[2]) - local match = "any amount" - if(p.p_match_stack_size == "any") then - match = "any amount" - elseif(p.p_match_stack_size == "exactly") then - match = "exactly "..tostring(amount) - elseif(p.p_match_stack_size == "less" - or p.p_match_stack_size == "more") then - match = p.p_match_stack_size.." than "..tostring(amount) - elseif(p.p_match_stack_size == "another") then - match = "another amount than " ..tostring(amount) - end - if(p.p_item_group and p.p_item_group ~= "") then - return "The player offered "..tostring(match).." item(s) of the group \"".. - tostring(item).."\"." - elseif((p.p_item_quest_id and p.p_item_quest_id ~= "") - or (p.p_item_desc and p.p_item_desc ~= "")) then - return "The player offered "..tostring(match).." of \"".. - tostring(p.p_item_desc or "- default description -").. - "\" (\""..tostring(item or "- ? -").."\") ".. - "with ID \""..tostring(p.p_item_quest_id or "- no special ID -").."\"." - else - return "The player offered "..tostring(match).." of \""..tostring(item).."\"." - end - elseif(p.p_type == "other") then - local fulfilled = "fulfilled" - if(not(p.p_fulfilled) or p.p_fulfilled ~= "true") then - fulfilled = "*not* fulfilled" - end - return "The preconditions for dialog option \""..tostring(p.p_value).."\" are ".. - fulfilled.."." - elseif(p.p_type == "entity_tpye") then - return "the type of the entity of the NPC is: \""..tostring(p.p_value).."\"." - end - -- fallback - return tostring(p.p_value) -end - - --- these are only wrapper functions for those in fs_edit_general.lua - -yl_speak_up.input_edit_preconditions = function(player, formname, fields) - return yl_speak_up.handle_input_fs_edit_option_related(player, formname, fields, - "p_", "o_prerequisites", yl_speak_up.max_prerequirements, - "pre(C)ondition", "tmp_prereq", - "Please punch the block you want to check in your precondition!", - values_what, values_operator, values_block, values_trade, values_inv, - check_what, check_operator, check_block, check_trade, check_inv, - -- player variables with read access - yl_speak_up.get_sorted_player_var_list_read_access, - "edit_preconditions" - ) -end - - -yl_speak_up.get_fs_edit_preconditions = function(player, table_click_result) - return yl_speak_up.build_fs_edit_option_related(player, table_click_result, - "p_", "o_prerequisites", yl_speak_up.max_prerequirements, - "pre(C)ondition", "tmp_prereq", - "What do you want to check in this precondition?", - values_what, values_operator, values_block, values_trade, values_inv, - check_what, check_operator, check_block, check_trade, check_inv, - -- player variables with read access - yl_speak_up.get_sorted_player_var_list_read_access, - -- show one precondition element - yl_speak_up.show_precondition, - "table_of_preconditions", - "The following expression shall be true:", "Operator:", - "Value to compare with (in some cases parameter):", - "The following shall be true about the block:" - ) -end - - -yl_speak_up.register_fs("edit_preconditions", - yl_speak_up.input_edit_preconditions, - yl_speak_up.get_fs_edit_preconditions, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_fashion.lua b/editor/fs/fs_fashion.lua deleted file mode 100644 index bed667b..0000000 --- a/editor/fs/fs_fashion.lua +++ /dev/null @@ -1,266 +0,0 @@ --- ### --- Fashion --- ### - --- normal skins for NPC - without wielded items or capes etc. -yl_speak_up.input_fashion = function(player, formname, fields) - if formname ~= "yl_speak_up:fashion" then - return - end - - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - - -- is the player editing this npc? if not: abort - if(not(yl_speak_up.edit_mode[pname]) - or (yl_speak_up.edit_mode[pname] ~= n_id)) then - return "" - end - - -- catch ESC as well - if(not(fields) or (fields.quit or fields.button_cancel or fields.button_exit)) then - 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 - end - - -- which texture from the textures list are we talking about? - -- this depends on the model! - local mesh = yl_speak_up.get_mesh(pname) - local texture_index = yl_speak_up.mesh_data[mesh].texture_index - if(not(texture_index)) then - texture_index = 1 - end - - -- show extra formspec with wielded item configuration and cape setup - if(fields.button_config_wielded_items - and yl_speak_up.mesh_data[mesh].can_show_wielded_items) then - yl_speak_up.show_fs(player, "fashion_extended") - return - end - - -- which skins are available? this depends on mob_type - local mob_type = yl_speak_up.get_mob_type(pname) - local skins = yl_speak_up.mob_skins[mob_type] - - - local textures = yl_speak_up.speak_to[pname].textures - - -- fallback if something went wrong (i.e. unkown NPC) - local skin = (textures[texture_index] or "") - if(not(skins)) then - skins = {skin} - end - local skin_index = table.indexof(skins, skin) - if(skin_index == -1) then - skin_index = 1 - end - local new_skin = skin - -- switch back to the stored old skin - if(fields.button_old_skin) then - local old_texture = yl_speak_up.speak_to[pname].old_texture - if(old_texture) then - new_skin = old_texture - end - -- store the new skin - elseif(fields.button_store_new_skin) then - yl_speak_up.speak_to[pname].old_texture = skin - -- show previous skin - elseif(fields.button_prev_skin) then - if(skin_index > 1) then - new_skin = skins[skin_index - 1] - else - new_skin = skins[#skins] - end - -- show next skin - elseif(fields.button_next_skin) then - if(skin_index < #skins) then - new_skin = skins[skin_index + 1] - else - new_skin = skins[1] - end - -- set directly via list - elseif(fields.set_skin_normal) then - local new_index = table.indexof(skins, fields.set_skin_normal) - if(new_index ~= -1) then - new_skin = skins[new_index] - end - end - - -- if there is a new skin to consider - if(textures[texture_index] ~= new_skin) then - textures[texture_index] = new_skin - yl_speak_up.mesh_update_textures(pname, textures) - end - if(fields.set_animation - and yl_speak_up.mesh_data[mesh] - and yl_speak_up.mesh_data[mesh].animation - and yl_speak_up.mesh_data[mesh].animation[fields.set_animation] - and yl_speak_up.speak_to[pname] - and yl_speak_up.speak_to[pname].obj) then - local obj = yl_speak_up.speak_to[pname].obj - obj:set_animation(yl_speak_up.mesh_data[mesh].animation[fields.set_animation]) - -- store the animation so that it can be restored on reload - local entity = obj:get_luaentity() - if(entity) then - entity.yl_speak_up.animation = yl_speak_up.mesh_data[mesh].animation[fields.set_animation] - end - end - if(fields.button_old_skin or fields.button_store_new_skin) then - yl_speak_up.speak_to[pname].old_texture = nil - 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 - end - yl_speak_up.show_fs(player, "fashion") -end - - --- this only sets the *skin*, depending on the mesh of the NPC; --- capes and wielded items are supported by an extended formspec for those --- NPC that can handle them -yl_speak_up.get_fs_fashion = function(pname) - -- which texture from the textures list are we talking about? - -- this depends on the model! - local mesh = yl_speak_up.get_mesh(pname) - if(not(mesh) or not(yl_speak_up.mesh_data[mesh])) then - return "size[9,2]label[0,0;Error: Mesh data missing.]" - end - local texture_index = yl_speak_up.mesh_data[mesh].texture_index - if(not(texture_index)) then - texture_index = 1 - end - - -- which skins are available? this depends on mob_type - local mob_type = yl_speak_up.get_mob_type(pname) - local skins = yl_speak_up.mob_skins[mob_type] - - local textures = yl_speak_up.speak_to[pname].textures - local skin = "" - if(textures and textures[texture_index]) then - skin = (textures[texture_index] or "") - end - -- store the old texture so that we can go back to it - local old_texture = yl_speak_up.speak_to[pname].old_texture - if(not(old_texture)) then - yl_speak_up.speak_to[pname].old_texture = skin - old_texture = skin - end - -- fallback if something went wrong - if(not(skins)) then - skins = {old_texture} - end - - local button_cancel = "Cancel" - -- is this player editing this particular NPC? then rename the button - if( yl_speak_up.edit_mode[pname] - and yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id) then - button_cancel = "Back" - end - - local skin_list = table.concat(skins, ",") - local skin_index = table.indexof(skins, skin) - if(skin_index == -1) then - skin_index = "" - end - - local tmp_textures = textures - if(texture_index ~= 1) then - tmp_textures = yl_speak_up.textures2skin(textures) - end - local preview = yl_speak_up.skin_preview_3d(mesh, tmp_textures, "2,1;6,12", "8,1;6,12") --- local preview = yl_speak_up.mesh_data[mesh].skin_preview(skin) - - local formspec = { - "container[0.5,4.0]", - "dropdown[0.75,14.1;16.25,1.5;set_skin_normal;", - skin_list or "", - ";", - tostring(skin_index) or "", - "]", - "label[0.75,13.6;The name of this skin is:]", - - "button[0.75,0.75;1.2,12;button_prev_skin;<]", - "button[15.75,0.75;1.2,12;button_next_skin;>]", - "tooltip[button_prev_skin;Select previous skin in list.]", - "tooltip[button_next_skin;Select next skin in list.]", - "tooltip[set_skin_normal;Select a skin from the list.]", - preview, - -- we add a special button for setting the skin in the player answer/reply window - } - if(yl_speak_up.mesh_data[mesh].animation - and yl_speak_up.speak_to[pname] - and yl_speak_up.speak_to[pname].obj) then - local anim_list = {} - for k, v in pairs(yl_speak_up.mesh_data[mesh].animation) do - table.insert(anim_list, k) - end - table.sort(anim_list) - -- which animation is the NPC currently running? - local obj = yl_speak_up.speak_to[pname].obj - local curr_anim = obj:get_animation(pname) - local anim = "" - -- does the current animation match any stored one? - for k, v in pairs(yl_speak_up.mesh_data[mesh].animation) do - if(v.x and v.y and curr_anim and curr_anim.x and curr_anim.y - and v.x == curr_anim.x and v.y == curr_anim.y) then - anim = k - end - end - local anim_index = table.indexof(anim_list, anim) - if(anim_index == -1) then - anim_index = "1" - end - table.insert(formspec, "label[0.75,16.4;Do the following animation:]") - table.insert(formspec, "dropdown[0.75,16.9;16.25,1.5;set_animation;") - table.insert(formspec, table.concat(anim_list, ',')) - table.insert(formspec, ";") - table.insert(formspec, tostring(anim_index) or "") - table.insert(formspec, "]") - end - table.insert(formspec, "container_end[]") - - local left_window = table.concat(formspec, "") - formspec = {} - local h = -0.8 - local button_text = "This shall be your new skin. Wear it proudly!" - if(skin == old_texture) then - button_text = "This is your old skin. It is fine. Keep it!" - end - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "button_store_new_skin", - "The NPC will wear the currently selected skin.", - button_text, - true, nil, nil, nil) - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "button_old_skin", - "The NPC will wear the skin he wore before you started changing it.", - "On a second throught - Keep your old skin. It was fine.", - (skin ~= old_texture), nil, nil, nil) - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "button_config_wielded_items", - "What shall the NPC wield, and which cape shall he wear?", - "I'll tell you what you shall wield.", - (yl_speak_up.mesh_data[mesh].can_show_wielded_items), - "You don't know how to show wielded items. Thus, we can't configure them.", - nil, nil) - return yl_speak_up.show_fs_decorated(pname, true, h, - "", - left_window, - table.concat(formspec, ""), - nil, - h) -end - -yl_speak_up.get_fs_fashion_wrapper = function(player, param) - local pname = player:get_player_name() - return yl_speak_up.get_fs_fashion(pname) -end - - -yl_speak_up.register_fs("fashion", - yl_speak_up.input_fashion, - yl_speak_up.get_fs_fashion_wrapper, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_fashion_extended.lua b/editor/fs/fs_fashion_extended.lua deleted file mode 100644 index f512f16..0000000 --- a/editor/fs/fs_fashion_extended.lua +++ /dev/null @@ -1,205 +0,0 @@ - --- inspired/derived from the wieldview mod in 3darmor -yl_speak_up.get_wield_texture = function(item) - if(not(item) or not(minetest.registered_items[ item ])) then - return "3d_armor_trans.png" - end - local def = minetest.registered_items[ item ] - if(def.inventory_image ~= "") then - return def.inventory_image - elseif(def.tiles and type(def.tiles[1]) == "string" and def.tiles[1] ~= "") then - return minetest.inventorycube(def.tiles[1]) - end - return "3d_armor_trans.png" -end - - -yl_speak_up.fashion_wield_give_items_back = function(player, pname) - -- move the item back to the player's inventory (if possible) - local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) - local player_inv = player:get_inventory() - local left_stack = trade_inv:get_stack("wield", 1) - local right_stack = trade_inv:get_stack("wield", 2) - if(left_stack and not(left_stack:is_empty()) - and player_inv:add_item("main", left_stack)) then - trade_inv:set_stack("wield", 1, "") - end - if(right_stack and not(right_stack:is_empty()) - and player_inv:add_item("main", right_stack)) then - trade_inv:set_stack("wield", 2, "") - end -end - - --- set what the NPC shall wield and which cape to wear -yl_speak_up.input_fashion_extended = function(player, formname, fields) - if formname ~= "yl_speak_up:fashion_extended" then - return - end - - local pname = player:get_player_name() - local textures = yl_speak_up.speak_to[pname].textures - - local n_id = yl_speak_up.speak_to[pname].n_id - - -- is the player editing this npc? if not: abort - if(not(yl_speak_up.edit_mode[pname]) - or (yl_speak_up.edit_mode[pname] ~= n_id)) then - return "" - end - - -- catch ESC as well - if(not(fields) - or (fields.quit or fields.button_cancel or fields.button_exit or fields.button_save)) then - yl_speak_up.fashion_wield_give_items_back(player, pname) - yl_speak_up.show_fs(player, "fashion") - return - - elseif(fields.button_wield_left - or fields.button_wield_right) then - local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname}) - local player_inv = player:get_inventory() - local left_stack = trade_inv:get_stack("wield", 1) - local right_stack = trade_inv:get_stack("wield", 2) - if(left_stack and left_stack:get_name() and fields.button_wield_left) then - textures[4] = yl_speak_up.get_wield_texture(left_stack:get_name()) - yl_speak_up.log_change(pname, n_id, - "(fashion) sword changed to "..tostring(fields.set_sword)..".") - end - if(right_stack and right_stack:get_name() and fields.button_wield_right) then - textures[3] = yl_speak_up.get_wield_texture(right_stack:get_name()) - yl_speak_up.log_change(pname, n_id, - "(fashion) shield changed to "..tostring(fields.set_shield)..".") - end - yl_speak_up.fashion_wield_give_items_back(player, pname) - - -- only change cape if there really is a diffrent one selected - elseif(fields.set_cape and fields.set_cape ~= textures[1]) then - - local mob_type = yl_speak_up.get_mob_type(pname) - local capes = yl_speak_up.mob_capes[mob_type] or {} - -- only set the cape if it is part of the list of allowed capes - if(table.indexof(capes, fields.set_cape) ~= -1) then - textures[1] = fields.set_cape - yl_speak_up.log_change(pname, n_id, - "(fashion) cape changed to "..tostring(fields.set_cape)..".") - end - end - - if(fields.button_wield_left or fields.button_wield_right or fields.set_cape or fields.button_sve) then - yl_speak_up.fashion_wield_give_items_back(player, pname) - yl_speak_up.mesh_update_textures(pname, textures) - yl_speak_up.show_fs(player, "fashion_extended") - return - end - yl_speak_up.show_fs(player, "fashion") -end - - -yl_speak_up.get_fs_fashion_extended = function(pname) - -- which texture from the textures list are we talking about? - -- this depends on the model! - local mesh = yl_speak_up.get_mesh(pname) - local texture_index = yl_speak_up.mesh_data[mesh].texture_index - if(not(texture_index)) then - texture_index = 1 - end - - local textures = yl_speak_up.speak_to[pname].textures - local skin = (textures[texture_index] or "") - - -- which skins are available? this depends on mob_type - local mob_type = yl_speak_up.get_mob_type(pname) - local skins = yl_speak_up.mob_skins[mob_type] or {skin} - local capes = yl_speak_up.mob_capes[mob_type] or {} - local cape = "" -- TODO - - -- is this player editing this particular NPC? then rename the button - if(not(yl_speak_up.edit_mode[pname]) - or yl_speak_up.edit_mode[pname] ~= yl_speak_up.speak_to[pname].n_id) then - return "label[Error. Not in Edit mode!]" - end - - -- make sure the cape can be unset again - if(#capes < 1 or capes[1] ~= "") then - table.insert(capes, 1, "") - end - local cape_list = table.concat(capes, ",") - local cape_index = table.indexof(capes, cape) - if(cape_index == -1) then - cape_index = "" - end - - local tmp_textures = textures - if(texture_index ~= 1) then - tmp_textures = yl_speak_up.textures2skin(textures) - end - local preview = yl_speak_up.skin_preview_3d(mesh, tmp_textures, "4.7,0.5;5,10", nil) - - local button_cancel = "Cancel" - -- is this player editing this particular NPC? then rename the button - if( yl_speak_up.edit_mode[pname] - and yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id) then - button_cancel = "Back" - end - local formspec = { - "size[13.4,15]", - "label[0.3,0.2;Skin: ", - minetest.formspec_escape(skin), - "]", - "label[4.6,0.65;", - yl_speak_up.speak_to[pname].n_id, - "]", - "label[6,0.65;", - (yl_speak_up.speak_to[pname].n_npc or "- nameless -"), - "]", - "dropdown[9.1,0.2;4,0.75;set_cape;", - cape_list, ";", cape_index, "]", - "label[0.3,4.2;Left:]", - "label[9.1,4.2;Right:]", - "field_close_on_enter[set_sword;false]", - "field_close_on_enter[set_shield;false]", - "image[9.1,1;4,2;", - textures[1] or "", - "]", -- Cape - "image[0.3,4.2;4,4;", - textures[4] or "", - "]", -- Sword - "image[9.1,4.2;4,4;", - textures[3] or "", - "]", --textures[3],"]", -- Shield - "tooltip[0.3,4.2;4,4;This is: ", - minetest.formspec_escape(textures[4]), - "]", - "tooltip[9.1,4.2;4,4;This is: ", - minetest.formspec_escape(textures[3]), - "]", - preview or "", - "button[0.3,8.4;3,0.75;button_cancel;"..button_cancel.."]", - "button[10.1,8.4;3,0.75;button_save;Save]", - "list[current_player;main;1.8,10;8,4;]", - -- set wielded items - "label[0.3,9.7;Wield\nleft:]", - "label[12.0,9.7;Wield\nright:]", - "list[detached:yl_speak_up_player_"..tostring(pname)..";wield;0.3,10.5;1,1;]", - "list[detached:yl_speak_up_player_"..tostring(pname)..";wield;12.0,10.5;1,1;1]", - "button[0.3,11.7;1,0.6;button_wield_left;Set]", - "button[12.0,11.7;1,0.6;button_wield_right;Set]", - "tooltip[button_wield_left;Set and store what your NPC shall wield in its left hand.]", - "tooltip[button_wield_right;Set and store what your NPC shall wield in its right hand.]", - } - return table.concat(formspec, "") -end - - -yl_speak_up.get_fs_fashion_extended_wrapper = function(player, param) - local pname = player:get_player_name() - return yl_speak_up.get_fs_fashion_extended(pname) -end - -yl_speak_up.register_fs("fashion_extended", - yl_speak_up.input_fashion_extended, - yl_speak_up.get_fs_fashion_extended_wrapper, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_get_list_of_usage_of_variable.lua b/editor/fs/fs_get_list_of_usage_of_variable.lua deleted file mode 100644 index 6118a6b..0000000 --- a/editor/fs/fs_get_list_of_usage_of_variable.lua +++ /dev/null @@ -1,93 +0,0 @@ - --- this function is called in fs_edit_general.lua when creating preconditions/effects --- and from fs_manage_variables.lua when the player clicks on a button; --- input to this formspec is sent to the respective calling functions - --- find out where this variable is used in NPCs -yl_speak_up.fs_get_list_of_usage_of_variable = function(var_name, pname, check_preconditions, - back_button_name, back_button_text, is_internal_var) - -- TODO: check if the player really has read access to this variable - if(not(is_internal_var)) then - var_name = yl_speak_up.restore_complete_var_name(var_name, pname) - end - -- which NPC (might be several) is using this variable? - -- TODO: ..or if the player at least is owner of these NPC or has extended privs - local npc_list = yl_speak_up.get_variable_metadata(var_name, "used_by_npc") - -- list of all relevant preconditions, actions and effects - local res = {} - local count_read = 0 - local count_changed = 0 - for i, n_id in ipairs(npc_list) do - -- the NPC may not even be loaded - local dialog = yl_speak_up.load_dialog(n_id, false) - if(dialog and dialog.n_dialogs) then - for d_id, d in pairs(dialog.n_dialogs) do - if(d and d.d_options) then - for o_id, o in pairs(d.d_options) do - local p_text = "" - local r_text = "" - local sort_value = 0 - if(o and o.o_prerequisites and check_preconditions) then - for p_id, p in pairs(o.o_prerequisites) do - if(p and p.p_type and p.p_type == "state" - and p.p_variable and p.p_variable == var_name) then - p_text = p_text..yl_speak_up.print_as_table_precon(p,pname) - sort_value = (p.p_var_cmp_value or 0) - count_read = count_read + 1 - end - end - end - if(o and o.o_results) then - for r_id, r in pairs(o.o_results) do - if(r and r.r_type and r.r_type == "state" - and r.r_variable and r.r_variable == var_name) then - r_text = r_text..yl_speak_up.print_as_table_effect(r,pname) - -- values set in the results are more important than - -- those set in preconditions - sort_value = (r.r_var_cmp_value or 0) - count_changed = count_changed + 1 - end - end - end - -- if preconditions or effects apply: show the action as well - if(o and o.actions and (p_text ~= "" or r_text ~= "")) then - for a_id, a in pairs(o.actions) do - -- no need to introduce an a_text; this will follow - -- directly after p_text, and p_text is finished - p_text = p_text..yl_speak_up.print_as_table_action(a, pname) - end - end - yl_speak_up.print_as_table_dialog(p_text, r_text, dialog, - n_id, d_id, o_id, res, o, sort_value) - end - end - end - end - end - - local formspec = yl_speak_up.print_as_table_prepare_formspec(res, "table_of_variable_uses", - back_button_name, back_button_text) - table.insert(formspec, - "label[20.0,1.8;".. - minetest.formspec_escape("Variable \"".. - minetest.colorize("#FFFF00", tostring(var_name or "- ? -")).. - "\" is used here:").."]") - - if(count_read > 0 or count_changed > 0) then - table.insert(formspec, - "label[16.0,31.0;The variable is accessed in ".. - minetest.colorize("#FFFF00", tostring(count_read).." pre(C)onditions").. - " and changed in ".. - minetest.colorize("#55FF55", tostring(count_changed).." (Ef)fects").. - ".]") - elseif(not(is_internal_var)) then - table.insert(formspec, - "button[0.2,30.6;56.6,1.2;delete_unused_variable;".. - minetest.formspec_escape("Delete this unused variable \"".. - tostring(var_name or "- ? -")).."\".]") - else - table.insert(formspec, - "label[16.0,31.0;This is an internal variable and cannot be deleted.]") - end - return table.concat(formspec, "\n") -end diff --git a/editor/fs/fs_initial_config_in_edit_mode.lua b/editor/fs/fs_initial_config_in_edit_mode.lua deleted file mode 100644 index 1172bdf..0000000 --- a/editor/fs/fs_initial_config_in_edit_mode.lua +++ /dev/null @@ -1,202 +0,0 @@ - --- in addition: set who can edit this npc; --- add buttons for fashion (skin editing) and properties; -local old_input_fs_initial_config = yl_speak_up.input_fs_initial_config -yl_speak_up.input_fs_initial_config = function(player, formname, fields) - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - - if(fields.back_from_error_msg) then - -- no point in showing the formspec or error message again if we did so already - if(not(yl_speak_up.may_edit_npc(player, n_id))) then - return - end - -- show this formspec again - yl_speak_up.show_fs(player, "initial_config", - {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id, false}) - return - end - - if(fields.button_export_dialog) then - yl_speak_up.show_fs(player, "export") - return - end - - if(fields.edit_skin and fields.edit_skin ~= "") then - yl_speak_up.show_fs(player, "fashion") - return - end - - if(fields.edit_properties and fields.edit_properties ~= "") then - yl_speak_up.show_fs(player, "properties") - return - end - - if((not(fields.save_initial_config) - and not(fields.show_nametag) - and not(fields.list_may_edit) - and not(fields.add_may_edit) - and not(fields.delete_may_edit) - ) or (fields and fields.exit)) then - local dialog = yl_speak_up.speak_to[pname].dialog - -- unconfigured NPC - if(fields and fields.exit and not(dialog) or not(dialog.n_dialogs)) then - minetest.chat_send_player(pname, "Aborting initial configuration.") - return - end - -- is the player editing the npc? then leaving this config - -- dialog has to lead back to the talk dialog - if(yl_speak_up.edit_mode[pname] == n_id and n_id) then - yl_speak_up.show_fs(player, "talk", - {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id}) - end - -- else we can quit here - return - end - - - - local error_msg = nil - local dialog = yl_speak_up.speak_to[pname].dialog - local done = false - if(not(yl_speak_up.may_edit_npc(player, n_id))) then - error_msg = "You are not allowed to edit this NPC." - - -- want to change who may edit this npc? - -- delete a player from the list of those allowed to edit the NPC - elseif(fields.delete_may_edit and fields.delete_may_edit ~= "" - and fields.list_may_edit and fields.list_may_edit ~= "") then - if(pname ~= yl_speak_up.npc_owner[ n_id ]) then - error_msg = "Only the owner of the NPC\ncan change this." - elseif(not(dialog)) then - error_msg = "Please set a name for your NPC first!" - else - -- actually delete the player from the list - dialog.n_may_edit[ fields.list_may_edit ] = nil - -- show the next entry - yl_speak_up.speak_to[pname].tmp_index = math.max(1, - yl_speak_up.speak_to[pname].tmp_index-1) - end - done = true - -- add a player who may edit this NPC - elseif(fields.add_may_edit_button and fields.add_may_edit and fields.add_may_edit ~= "") then - if(pname ~= yl_speak_up.npc_owner[ n_id ]) then - error_msg = "Only the owner of the NPC\ncan change this." - -- Note: The owner can now add himself as well. This may be useful before transfering - -- ownership of the NPC to an inexperienced new user who might need help. --- elseif(fields.add_may_edit == pname) then --- error_msg = "You are already the owner of this NPC!\nNo need to add you extra here." - elseif(not(minetest.check_player_privs(fields.add_may_edit, {interact=true}))) then - error_msg = "Player \""..minetest.formspec_escape(fields.add_may_edit).. - "\" not found." - elseif(not(dialog)) then - error_msg = "Please set a name for the NPC first!" - else - if(not(dialog.n_may_edit)) then - dialog.n_may_edit = {} - end - dialog.n_may_edit[ fields.add_may_edit ] = true - -- jump to the index with this player so that the player sees that he has been added - local tmp_list = yl_speak_up.sort_keys(dialog.n_may_edit, true) - local index = table.indexof(tmp_list, fields.add_may_edit) - if(index and index > 0) then - -- "Add player:" is added before all other names, so +1 - yl_speak_up.speak_to[pname].tmp_index = index + 1 - end - end - done = true - -- selected a player name in the woy may edit this NPC dropdown? - elseif(fields.list_may_edit and fields.list_may_edit ~= "") then - local tmp_list = yl_speak_up.sort_keys(dialog.n_may_edit, true) - local index = table.indexof(tmp_list, fields.list_may_edit) - if(fields.list_may_edit == "Add player:") then - index = 0 - end - if(index and index > -1) then - yl_speak_up.speak_to[pname].tmp_index = index + 1 - end - done = true - end - if(error_msg) then - yl_speak_up.show_fs(player, "msg", { input_to = "yl_speak_up:initial_config", - formspec = "size[6,2]".. - "label[0.2,0.0;"..tostring(error_msg).."]".. - "button[2,1.5;1,0.9;back_from_error_msg;Back]"}) - return - end - - if( fields.add_may_edit and fields.add_may_edit ~= "") then - yl_speak_up.save_dialog(n_id, dialog) - yl_speak_up.log_change(pname, n_id, - "Added to \"may be edited by\": "..tostring(fields.add_may_edit)) - elseif(fields.delete_may_edit and fields.delete_may_edit ~= "" - and fields.list_may_edit and fields.list_may_edit ~= "") then - yl_speak_up.save_dialog(n_id, dialog) - yl_speak_up.log_change(pname, n_id, - "Removed from \"may be edited by\": "..tostring(fields.list_may_edit)) - elseif(not(done) or fields.save_initial_config) then - return old_input_fs_initial_config(player, formname, fields) - end - -- update display after editing may_edit_npc: - yl_speak_up.show_fs(player, "initial_config", - {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id, false}) -end - - --- initialize the npc without having to use a staff; - --- add option to show, add and delete other players who may edit this npc; --- add buttons for skin change and editing properties -local old_get_fs_initial_config = yl_speak_up.get_fs_initial_config -yl_speak_up.get_fs_initial_config = function(player, n_id, d_id, is_initial_config, add_formspec) - -- nothing to add if this is the initial configuration - if(is_initial_config) then - return old_get_fs_initial_config(player, n_id, d_id, is_initial_config, nil) - end - - local pname = player:get_player_name() - local dialog = yl_speak_up.speak_to[pname].dialog - -- dialog.n_may_edit was a string for a short time in development - if(not(dialog.n_may_edit) or type(dialog.n_may_edit) ~= "table") then - dialog.n_may_edit = {} - end - local table_of_names = dialog.n_may_edit - local may_be_edited_by = { - -- these buttons and formspecs are provided by the editor: - "button[1.0,5.5;4,0.9;edit_skin;Edit Skin]", - "button[6.0,5.5;4,0.9;edit_properties;Edit Properties]", - -- who can edit this NPC? - "label[0.2,4.45;May be\nedited by:]", - -- offer a dropdown list and a text input field for player names for adding - yl_speak_up.create_dropdown_playerlist(player, pname, - table_of_names, yl_speak_up.speak_to[pname].tmp_index, - 2.2, 4.3, 0.0, 1.0, "list_may_edit", "player", - "Remove selected\nplayer from list", - "add_may_edit", - "Enter the name of the player whom you\n".. - "want to grant the right to edit your NPC.\n".. - "The player needs at least the npc_talk_owner priv\n".. - "in order to actually edit the NPC.\n".. - "Click on \"Add\" to add the new player.", - "delete_may_edit", - "If you click here, the player will no\n".. - "longer be able to edit your NPC." - )} - if(not(yl_speak_up.speak_to[pname].tmp_index) or yl_speak_up.speak_to[pname].tmp_index < 2) then - table.insert(may_be_edited_by, "button[9.8,4.3;1.0,1.0;add_may_edit_button;Add]") - table.insert(may_be_edited_by, "tooltip[add_may_edit_button;Click here to add the player ".. - "listed to the left\nto those who can edit this NPC.]") - end - -- show the formspec to the player - return old_get_fs_initial_config(player, n_id, d_id, is_initial_config, may_be_edited_by) -end - - -yl_speak_up.register_fs("initial_config", - -- this function has been changed here: - yl_speak_up.input_fs_initial_config, - -- still handled by the wrapper: - yl_speak_up.get_fs_initial_config_wrapper, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_manage_quest_steps.lua b/editor/fs/fs_manage_quest_steps.lua deleted file mode 100644 index 354dc8f..0000000 --- a/editor/fs/fs_manage_quest_steps.lua +++ /dev/null @@ -1,364 +0,0 @@ - --- Imposing an order on the quest steps is...tricky as best as what will --- be more important to the players will be the order in which the --- quest steps have to be solved/done - and not an alphabetical order. --- But we need an order here for a dropdown menu to select each --- quest step even if it hasn't been assigned any place in the chain --- of quest steps yet. So - alphabetical order. -yl_speak_up.get_sorted_quest_step_list = function(pname, q_id) - local quest_step_list = {} - if(not(pname) or not(yl_speak_up.speak_to[pname])) then - return {} - end - local q_id = yl_speak_up.speak_to[pname].q_id - - if(q_id and yl_speak_up.quests[q_id] and yl_speak_up.quests[q_id].step_data) then - for step_id, v in pairs(yl_speak_up.quests[q_id].step_data) do - table.insert(quest_step_list, step_id) - end - end - table.sort(quest_step_list) - return quest_step_list -end - - --- helper functions for yl_speak_up.input_fs_manage_quest_steps(..) --- returns the index of the new quest step -yl_speak_up.input_fs_manage_quest_steps_add_new_entry = function(pname, entry_name) - local q_id = yl_speak_up.speak_to[pname].q_id - local res = yl_speak_up.quest_step_add_quest_step(pname, q_id, entry_name) - -- might make sense to show the error message somewhere - if(res ~= "OK") then - return res - end - -- the new entry will be somewhere in it - local quest_step_list = yl_speak_up.get_sorted_quest_step_list(pname) - return table.indexof(quest_step_list, entry_name) -end - - --- helper functions for yl_speak_up.input_fs_manage_quest_steps(..) --- returns a text describing if deleting the quest worked -yl_speak_up.input_fs_manage_quest_steps_del_old_entry = function(pname, entry_name) - local q_id = yl_speak_up.speak_to[pname].q_id - return yl_speak_up.quest_step_del_quest_step(pname, q_id, entry_name) -end - - --- helper functions for yl_speak_up.input_fs_manage_quest_steps(..) --- implements all the functions that are specific to managing quest steps and not part of --- general item management -yl_speak_up.input_fs_manage_quest_steps_check_fields = function(player, formname, fields, quest_step_name, list_of_entries) - local pname = player:get_player_name() - if(not(quest_step_name)) then - quest_step_name = "" - end ---[[ TODO: implement some back button functionality? - if(fields and fields.show_variable) then - yl_speak_up.show_fs(player, "manage_variables", {var_name = quest_name}) - return - end ---]] - -- this function didn't have anything to do - return "NOTHING FOUND" -end - - - --- makes use of yl_speak_up.handle_input_fs_manage_general and is thus pretty short -yl_speak_up.input_fs_manage_quest_steps = function(player, formname, fields) - local pname = player:get_player_name() - - -- route diffrently when the task was adding a quest step - if(fields and fields.back - and pname - and yl_speak_up.speak_to[pname].d_id - and yl_speak_up.speak_to[pname].o_id) then - return yl_speak_up.show_fs(player, "edit_option_dialog", { - d_id = yl_speak_up.speak_to[pname].d_id, - o_id = yl_speak_up.speak_to[pname].o_id, - }) - end - if(not(fields) or fields.manage_quests or fields.back) then - return yl_speak_up.show_fs(player, "manage_quests") - end - local res = yl_speak_up.player_is_working_on_quest(player) - - -- show a particular quest step? - if(yl_speak_up.handle_input_routing_show_a_quest_step(player, formname, fields, "back_from_error_msg", res)) then - return - end - - if(res.current_step) then - -- forward input from that formspec... - if((yl_speak_up.speak_to[res.pname].quest_step_mode == "embedded_select") - and (fields.add_from_available - or (fields.add_step and fields.add_quest_step))) then - return yl_speak_up.input_fs_add_quest_steps(player, "yl_speak_up:add_quest_steps", fields) - end - end - - local modes = {"add_to_one_needed", "add_to_all_needed", - "insert_after_prev_step", "insert_before_next_step"} - for i, mode in ipairs(modes) do - if(fields[mode] and fields[mode] ~= "") then - -- let that function sort out what to do; - -- yl_speak_up.speak_to[pname].q_id and yl_speak_up.speak_to[pname].quest_step - -- ought to be set to the current quest and step by now - yl_speak_up.speak_to[pname].quest_step_mode = mode - yl_speak_up.show_fs(player, "add_quest_steps") - return - end - end - - local quest_step_list = yl_speak_up.get_sorted_quest_step_list(pname) - local res = yl_speak_up.handle_input_fs_manage_general(player, formname, fields, - -- what_is_the_list_about, min_length, max_length, function_add_new_entry, - "quest step", 2, 70, - yl_speak_up.input_fs_manage_quest_steps_add_new_entry, - quest_step_list, - yl_speak_up.input_fs_manage_quest_steps_del_old_entry, - yl_speak_up.input_fs_manage_quest_steps_check_fields) - return true -end - - -yl_speak_up.get_fs_manage_quest_steps = function(player, param) - -- small helper function - local em = function(text) - return minetest.colorize("#9999FF", text) - end - - local res = yl_speak_up.player_is_working_on_quest(player) - if(res.error_msg) then - return yl_speak_up.build_fs_quest_edit_error(res.error_msg, "back") - end - local step_data = res.step_data - local quest_step_list = yl_speak_up.get_sorted_quest_step_list(res.pname) - if(param and param ~= "") then - local index = table.indexof(quest_step_list, param) - yl_speak_up.speak_to[res.pname].tmp_index_general = index + 1 - end - local idx = yl_speak_up.speak_to[res.pname].tmp_index_general - if(idx and idx > 1) then - yl_speak_up.speak_to[res.pname].quest_step = quest_step_list[idx - 1] - end - - local formspec = {} - table.insert(formspec, "size[30,12]".. - "container[6,0;18.5,12]".. - "label[0.2,1.2;A quest step is a single thing a player may do in a quest - ".. - "like talking to an NPC.\n".. - "Usually not all quest steps can be done/solved at all times.]") - local selected = yl_speak_up.build_fs_manage_general(player, param, - formspec, quest_step_list, - "Create quest step", - "Create a new quest step for this quest.", - "quest step", - "Enter the name of the new quest step you want to create.\n".. - "This is an internal text shown only to yourself.\n".. - "Players cannot see the names of quest steps.", - "If you click here, the selected quest step will be deleted.\n".. - "This will only be possible if it's not used anywhere.", - "1.0") - table.insert(formspec, "container_end[]") - - if(not(selected) or selected == "" or not(step_data) or not(step_data[selected])) then - formspec = {} -- we start a new one - -- insert a nicely formated list of quest steps - yl_speak_up.speak_to[res.pname].quest_step_mode = "embedded_select" - table.insert(formspec, yl_speak_up.get_fs_add_quest_steps(player, nil)) - table.insert(formspec, "container_end[]") - local lists = yl_speak_up.quest_step_get_start_end_unconnected_lists(step_data) - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Start steps:", "select_from_start_steps", lists.start_steps, - "0.1", "2.7", "5.6", "4.3", 0, nil, "#AAFFAA", - "The quest begins with this (or one of these) steps.\n".. - "You need at least one start step.", - nil) - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Unconnected steps:", "select_from_unconnected_steps", lists.unconnected_steps, - "0.1", "7.0", "5.6", "4.3", 0, nil, "#FFAAAA", - "These steps are not used yet. They are not required\n".. - "by any other step and do not require steps either.\n".. - "Please decide what to do with them!", - nil) - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Quest ends with steps:", "select_from_end_steps", lists.end_steps, - "24", "2.7", "5.6", "8.5", "0.1", nil, "#AAFFAA", - "This quest ends with these steps. They are not required\n".. - "by any other steps and have no successor.\n".. - "Your quest needs at least one end step.", - nil) - return table.concat(formspec, "") - end - -- find out the next quest step - local required_for = yl_speak_up.quest_step_required_for(step_data, selected) - - -- middle (this quest step) - table.insert(formspec, "container[6,2.7;12,10.8]".. - "label[0.2,0.5;This quest step is named:]".. - "box[0.7,0.7;17,0.7;#000000]".. - "label[0.8,1.1;") - table.insert(formspec, minetest.colorize("#AAFFAA", minetest.formspec_escape(selected))) - table.insert(formspec, "]") - table.insert(formspec, "container_end[]") - -- show the locations where this quest step is set - local c = 0 - for where_id, d in pairs(step_data[selected].where or {}) do - c = c + 1 - end - if(c > 1) then - table.insert(formspec, "label[6.2,4.5;This quest step can be set in diffrent ways (") - table.insert(formspec, tostring(c)) - table.insert(formspec, " ways) by:]") - table.insert(formspec, "scrollbaroptions[max=") - table.insert(formspec, tostring((c-1.5) * 30)) -- 10 units for default 0.1 scroll factor - table.insert(formspec, ";thumbsize=15") - table.insert(formspec, "]") - table.insert(formspec, "scrollbar[23.2,4.7;0.3,5;vertical;scrollbar_where;0.1]") - elseif(c == 1) then - table.insert(formspec, "label[6.2,4.5;This quest step can be set by:]") - else - table.insert(formspec, "label[6.2,4.5;This quest step cannot be set yet.]") - end - table.insert(formspec, "scroll_container[6.2,4.7;17,5;scrollbar_where;vertical;]") - c = 0 - for where_id, d in pairs(step_data[selected].where or {}) do - table.insert(formspec, "container[0,") - table.insert(formspec, tostring(0.2 + c * 3.0)) - table.insert(formspec, ";17,4]") - table.insert(formspec, "box[0,0;17,2.7;") - if(c%2 == 0) then - table.insert(formspec, "#000000]") - else - table.insert(formspec, "#222222]") - end - -- describe where in the dialog of the NPC or location this quest step shall be set - local s = "This quest step can be set by " - if(c > 0) then - s = "..alternatively, this quest step can be set by " - end - yl_speak_up.quest_step_show_where_set(res.pname, formspec, s, d.n_id, d.d_id, d.o_id, - "#444488", c + 1) --"#513F23", c + 1) --"#a37e45", c + 1) - table.insert(formspec, "container_end[]") - c = c + 1 - end - table.insert(formspec, "scroll_container_end[]") - - -- left side (previous quest step) - table.insert(formspec, "container[0,0;5.8,13.5]".. - "label[0.2,2.0;"..em("Required previous").."]".. - "label[0.2,2.4;quest step(s):]".. - "style[insert_before_next_step,insert_after_prev_step,".. - "add_to_one_needed,add_to_all_needed;bgcolor=blue;textcolor=yellow]".. - "button[0.1,0.1;5.6,0.8;show_step_list;Show all quest steps]") - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - em("One of").." these quest steps:", "one_step_required", - step_data[selected].one_step_required, - "0.1", "2.7", "5.6", "4.3", 0, nil, "#AAFFAA", - "At least "..em("one of").." these previous quest steps listed here has to be\n".. - "achieved by the player who is trying to solve this quest.\n".. - "Only then can the player try to achieve this current quest\n".. - "step that you are editing here.\n".. - "If this is empty, then it's usually the/a first step of the quest.\n".. - "If there is one entry, then that entry is the previous quest step.\n".. - "If there are multiple entries, then players have alternate ways\n".. - "to achieve this current quest step here.", - "button[4.6,0.0;0.94,0.7;add_to_one_needed;Edit]".. - "tooltip[add_to_one_needed;Add or remove a quest step to this list.]") - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - em("All of").." these quest steps:", "all_steps_required", - step_data[selected].all_steps_required, - "0.1", "7.0", "5.6", "4.3", 0, nil, "#AAFFAA", - "Sometimes there may not be a particular order in which\n".. - "quest steps ought to be solved. Imagine for example getting\n".. - "indigrents for a cake and delivering them to an NPC.\n".. - "The quest steps listed here can be done in "..em("any order")..".\n".. - "They have "..em("all").." to be achieved first in order for this current\n".. - "quest step to become available.\n".. - "Usually this list is empty.", - "button[4.6,0.0;0.94,0.7;add_to_all_needed;Edit]".. - "tooltip[add_to_all_needed;Add or remove a quest step to this list.]") - if( #step_data[selected].one_step_required > 0 - or #step_data[selected].all_steps_required > 0) then - if( #step_data[selected].one_step_required - + #step_data[selected].all_steps_required > 1) then - table.insert(formspec, "style[show_prev_step;bgcolor=red]") - end - table.insert(formspec, "button[5.6,1.7;0.6,7.0;show_prev_step;<]".. - "tooltip[show_prev_step;Show the previous step according to ".. - em("your quest logic")..".\n".. - "The button turns "..minetest.colorize("#FF0000", "red").. - " if there is more than one option. In such\na case ".. - "the alphabeticly first previous quest step is choosen.\n".. - "The other "..em("< Prev").." button shows the previous step ".. - "in\n"..em("alphabetical order")..".]") - end - -- add buttons for inserting steps between this and the prev/next one - if(#step_data[selected].one_step_required <= 1) then - table.insert(formspec, - "button[5.6,8.7;0.6,2.6;insert_after_prev_step;+]".. - "tooltip[insert_after_prev_step;".. - "Insert a new quest step between the "..em("previous step").. - " (shown\n".. - "to the left) and the "..em("current step").. - " (shown in the middle).\n".. - "Note: This only makes sense if there's just one or no\n".. - " previous step.]") - end - table.insert(formspec, "container_end[]") - - - -- right side (next quest step) - table.insert(formspec, "container[23.8,0;5.8,13.5]".. - "label[0.6,2.0;Achieving this quest step]".. - "label[0.6,2.4;"..em("helps").." the quester to:]".. - "button[0.4,0.1;5.6,0.8;manage_quests;Manage quests]") - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "get these quest step(s) "..em("next")..":", "next_steps_show", - required_for, - -- the label needs to be moved slightly to the right to make room for the > button - "0.4", "2.7", "5.6", "8.5", "0.1", nil, "#AAFFAA", - "Once the current quest step has been achieved by the\n".. - "player, the player can strive to achieve these next\n".. - "quest step(s).\n".. - "If this is empty, then it's either the/a last step (quest\n".. - "solved!) - or the quest is not properly set up.", - nil) - - if(required_for and #required_for > 0) then - if(#required_for > 1) then - table.insert(formspec, "style[show_next_step;bgcolor=red]") - end - table.insert(formspec, "button[0,1.7;0.6,7.0;show_next_step;>]".. - "tooltip[show_next_step;Show the next step according to ".. - em("your quest logic")..".\n".. - "The button turns "..minetest.colorize("#FF0000", "red").. - " if there is more than one option. In such\na case ".. - "the alphabeticly first next quest step is choosen.\n".. - "The other "..em("Next >").." button shows the next step ".. - "in\n"..em("alphabetical order")..".]") - end - if(#required_for <= 1) then - table.insert(formspec, - "button[0,8.7;0.6,2.6;insert_before_next_step;+]".. - "tooltip[insert_before_next_step;".. - "Insert a new quest step between "..em("current step").. - " (shown\nin the middle) ".. - "and the "..em("next step").." (shown to the right).\n".. - "Note: This only makes sense if there's just one or no\n".. - " next step.]") - end - table.insert(formspec, "container_end[]") - - return table.concat(formspec, "") -end - - -yl_speak_up.register_fs("manage_quest_steps", - yl_speak_up.input_fs_manage_quest_steps, - yl_speak_up.get_fs_manage_quest_steps, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_manage_quests.lua b/editor/fs/fs_manage_quests.lua deleted file mode 100644 index fac3b87..0000000 --- a/editor/fs/fs_manage_quests.lua +++ /dev/null @@ -1,248 +0,0 @@ --- helper functions for yl_speak_up.input_fs_manage_quests(..) --- returns the index of the new quest -yl_speak_up.fun_input_fs_manage_quests_add_new_entry = function(pname, entry_name) - local res = yl_speak_up.add_quest(pname, entry_name, - "Name of your quest", - "Enter a longer description here for describing the quest ".. - "to players who search for one.", - "Enter a short description here describing what the quest is about.", - "Room for comments/notes") - -- might make sense to show the error message somewhere - if(res ~= "OK") then - return res - end - -- the new entry will be somewhere in it - local quest_list = yl_speak_up.get_sorted_quest_list(pname) - return table.indexof(quest_list, entry_name) -end - --- helper functions for yl_speak_up.input_fs_manage_quests(..) --- returns a text describing if deleting the quest worked -yl_speak_up.fun_input_fs_manage_quests_del_old_entry = function(pname, entry_name) - -- get q_id from entry_name - local q_id = yl_speak_up.get_quest_id_by_var_name(entry_name, pname) - return yl_speak_up.del_quest(q_id, pname) -end - --- helper functions for yl_speak_up.input_fs_manage_quests(..) --- implements all the functions that are specific to managing quests and not part of --- general item management -yl_speak_up.fun_input_fs_manage_quests_check_fields = function(player, formname, fields, quest_name, list_of_entries) - local pname = player:get_player_name() - if(not(quest_name)) then - quest_name = "" - end - if(fields and fields.show_variable) then - yl_speak_up.show_fs(player, "manage_variables", {var_name = quest_name}) - return - end - -- this function didn't have anything to do - return "NOTHING FOUND" -end - - --- makes use of yl_speak_up.handle_input_fs_manage_general and is thus pretty short -yl_speak_up.input_fs_manage_quests = function(player, formname, fields) - local pname = player:get_player_name() - if(fields and fields.manage_quest_steps and fields.manage_quest_steps ~= "") then - -- the quest we're working at is stored in yl_speak_up.speak_to[pname].q_id - yl_speak_up.show_fs(player, "manage_quest_steps") - return - end - - -- show and edit NPCs that may contribute - if( fields and fields.edit_npcs) then - return yl_speak_up.show_fs(player, "add_quest_steps", "manage_quest_npcs") - elseif(fields and fields.edit_locations) then - return yl_speak_up.show_fs(player, "add_quest_steps", "manage_quest_locations") - end - - -- show a particular quest step from the start/unconnected/end list? - local res = yl_speak_up.player_is_working_on_quest(player) - if(yl_speak_up.speak_to[pname] - and yl_speak_up.speak_to[pname].q_id - and yl_speak_up.handle_input_routing_show_a_quest_step(player, formname, fields, "back", res)) then - return - end - - local quest_list = yl_speak_up.get_sorted_quest_list(pname) - local res = yl_speak_up.handle_input_fs_manage_general(player, formname, fields, - -- what_is_the_list_about, min_length, max_length, function_add_new_entry, - "quest", 2, 80, - yl_speak_up.fun_input_fs_manage_quests_add_new_entry, - quest_list, - yl_speak_up.fun_input_fs_manage_quests_del_old_entry, - yl_speak_up.fun_input_fs_manage_quests_check_fields) - return true -end - - -yl_speak_up.get_fs_manage_quests = function(player, param) - local pname = player:get_player_name() - local quest_list = yl_speak_up.get_sorted_quest_list(pname) - local formspec = {} - if(param and param ~= "") then - local index = table.indexof(quest_list, param) - yl_speak_up.speak_to[pname].tmp_index_general = index + 1 - end - table.insert(formspec, "size[30,12]".. - "container[6,0;18.5,12]".. - "label[0.2,1.2;A quest is a linear sequence of quest steps. Quests can ".. - "depend on and influence other quests.\n".. - "Progress for each player is stored in a variable. The name of ".. - "that variable cannot be changed after creation.]") --- if(true) then return formspec[1] end -- TODO: temporally disabled for YL - local selected = yl_speak_up.build_fs_manage_general(player, param, - formspec, quest_list, - "Create quest", - "Create a new varialbe with the name\n".. - "you entered in the field to the left.", - "quest", - "Enter the name of the new quest you want to create.\n".. - "You can't change this name afterwards. But you *can*\n".. - "add and change a human readable description later on.", - "If you click here, the selected quest will be deleted.\n".. - "This will only be possible if it's not used anywhere.") - if(not(selected) or selected == "") then - table.insert(formspec, "container_end[]") - return table.concat(formspec, "") - end - local var_name = yl_speak_up.restore_complete_var_name(selected, pname) - local quest = {} - for q_id, data in pairs(yl_speak_up.quests) do - if(data and data.var_name and data.var_name == var_name) then - quest = data - end - end - - -- which quest is the player working on? that's important for showing quest steps - if(not(yl_speak_up.speak_to[pname])) then - yl_speak_up.speak_to[pname] = {} - end - yl_speak_up.speak_to[pname].q_id = quest.id - - local quest_state_selected = table.indexof({"created","testing","open","official"}, quest.state) - if(quest_state_selected == -1) then - quest_state_selected = 1 - end - -- index 1 is "Add variable:" - - table.insert(formspec, "button[12,2.15;4.5,0.6;show_variable;Show and edit this variable]") - - table.insert(formspec, "scroll_container[0,3;18,8;scr0;vertical;1]") - table.insert(formspec, "button[12,0.15;4.5,0.6;manage_quest_steps;Manage quest steps]") - - table.insert(formspec, "label[0.5,0.5;Quest ID:]") - table.insert(formspec, "label[3.5,0.5;"..minetest.formspec_escape(quest.id or "- ? -").."]") - table.insert(formspec, "label[0.5,1.1;State:]") - table.insert(formspec, "dropdown[3.5,0.8;4.0,0.5;quest_state;created,testing,open,official;"..tostring(quest_state_selected).."]") - table.insert(formspec, "label[0.5,1.7;Creator/Owner:]") - table.insert(formspec, "field[3.5,1.4;4.0,0.5;quest_owner;;"..minetest.formspec_escape(quest.owner or "- ? -").."]") - table.insert(formspec, "label[0.5,2.3;Name:]") - table.insert(formspec, "field[3.5,2.0;13.0,0.5;quest_name;;"..minetest.formspec_escape(quest.name or "- ? -").."]") - table.insert(formspec, "label[0.5,2.9;Short Description:]") - table.insert(formspec, "field[3.5,2.6;13.0,0.5;quest_short_desc;;"..minetest.formspec_escape(quest.short_desc or "- ? -").."]") - table.insert(formspec, "label[0.5,3.5;Full Description:]") - table.insert(formspec, "textarea[3.5,3.2;13.0,1.5;quest_desc;;"..minetest.formspec_escape(quest.description or "- ? -").."]") - table.insert(formspec, "label[0.5,5.1;Internal comment:]") - table.insert(formspec, "textarea[3.5,4.8;13.0,1.5;quest_comment;;"..minetest.formspec_escape(quest.comment or "- ? -").."]") - - table.insert(formspec, "button[3.5,6.5;4.0,0.8;save_changes;TODO Save changes]") - table.insert(formspec, "scroll_container_end[]") - table.insert(formspec, "container_end[]") - - -- TODO: make the content of the fields and textareas more readable (more contrast) - -- TODO: actually process and store changed entries ---[[ - -- TODO: entries that are not yet shown: - quest.var_name = var_name -- name of the variable where progress is stored for each player - quest.subquests = {} -- list of other quest_ids that contribute to this quest - -- -> determined from quests.npcs and quests.locations - quest.is_subquest_of = {} -- list of quest_ids this quest contributes to - -- -> determined from quests.npcs and quests.locations - quest.rewards = {} -- list of rewards (item stacks) for this ques - quest.testers = {} -- list of player names that can test the quest - -- -> during the created/testing phase: any player for which - -- quest.var_name is set to a value - quest.solved_by = {} -- list of names of players that solved the quest at least once ---]] - - -- left side: quest steps - -- quest.step_data = {} - -- table containing information about a quest step (=key) - -- this may also be information about WHERE a quest step shall take place - table.insert(formspec, "button[0.1,0.1;5.6,0.8;show_step_list;Show all quest steps]") - local lists = yl_speak_up.quest_step_get_start_end_unconnected_lists(quest.step_data or {}) - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Start steps:", "select_from_start_steps", lists.start_steps, - "0.1", "1.0", "5.6", "3.5", 0, nil, "#AAFFAA", - "The quest begins with this (or one of these) steps.\n".. - "You need at least one start step.", - nil) - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Unconnected steps:", "select_from_unconnected_steps", lists.unconnected_steps, - "0.1", "4.5", "5.6", "3.5", 0, nil, "#FFAAAA", - "These steps are not used yet. They are not required\n".. - "by any other step and do not require steps either.\n".. - "Please decide what to do with them!", - nil) - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Quest ends with steps:", "select_from_end_steps", lists.end_steps, - "0.1", "8.0", "5.6", "3.5", 0, nil, "#AAFFAA", - "This quest ends with these steps. They are not required\n".. - "by any other steps and have no successor.\n".. - "Your quest needs at least one end step.", - nil) - - -- right side: - -- All these values could in theory either be derived from quest.var_name - -- and/or from quest.step_data.where. - -- These lists here are needed regardless of that because they may be used - -- to add NPC/locations/quest items that are *not yet* used but are planned - -- to be used for this quest eventually. - table.insert(formspec, "style[edit_npcs,edit_locations,edit_items;bgcolor=blue;textcolor=yellow]") - -- quest.npcs = {} - -- list of NPC that *may* contribute to this quest (only IDs without leading n_) - -- turn that list into a more readable list of names - local npc_names = {} - for i, id in ipairs(quest.npcs or {}) do - local d = yl_speak_up.npc_list[id] or {} - table.insert(npc_names, "n_"..tostring(id).." "..(d.name or "- unknown -")) - end - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "NPC that (may) participate:", "select_from_npcs", npc_names, - "24", "1.0", "5.6", "3.5", 0, nil, "#AAAAFF", - "This is a list of NPC that may be relevant for this quest.\n".. - "Add an NPC to this list and then edit the NPC.\n".. - "Now you can set quest steps from this quest in the NPC's options.", - "button[4.6,0.0;0.94,0.7;edit_npcs;Edit]") - -- quest.locations = {} - -- list of locations that *may* contribute to this quest - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Locations:", "select_from_locations", quest.locations or {}, - "24", "4.5", "5.6", "3.5", 0, nil, "#AAAAFF", - "This is a list of locations that may be relevant for this quest.\n".. - "It works the same way as for the NPC above.", - "button[4.6,0.0;0.94,0.7;edit_locations;Edit]") - -- quest.items = {} - -- data of quest items that *may* be created and/or accepted in this quest - yl_speak_up.get_sub_fs_show_list_in_box(formspec, - "Quest items:", "select_from_quest_items", quest.items or {}, - "24", "8.0", "5.6", "3.5", 0, nil, "#FFFFFF", - "This is a list of quest items.\n".. - "Add quest items here in order to use them more easily in your NPC.", - "button[4.6,0.0;0.94,0.7;edit_items;Edit]") - - - -- store the quest ID so that we know what we're working at - yl_speak_up.speak_to[pname].q_id = quest.id - return table.concat(formspec, "") -end - - -yl_speak_up.register_fs("manage_quests", - yl_speak_up.input_fs_manage_quests, - yl_speak_up.get_fs_manage_quests, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_manage_variables.lua b/editor/fs/fs_manage_variables.lua deleted file mode 100644 index 794ba90..0000000 --- a/editor/fs/fs_manage_variables.lua +++ /dev/null @@ -1,483 +0,0 @@ - --- helper functions for yl_speak_up.input_fs_manage_variables(..) --- returns the index of the new variable -yl_speak_up.fun_input_fs_manage_variables_add_new_entry = function(pname, entry_name) - local res = yl_speak_up.add_quest_variable(pname, entry_name) - if(not(res)) then - return -1 - end - local var_list = yl_speak_up.get_quest_variables(pname, true) - -- make names of own variables shorter - yl_speak_up.strip_pname_from_varlist(var_list, pname) - table.sort(var_list) - return table.indexof(var_list, entry_name) -end - --- helper functions for yl_speak_up.input_fs_manage_variables(..) --- returns a text describing if deleting the variable worked -yl_speak_up.fun_input_fs_manage_variables_del_old_entry = function(pname, entry_name) - -- delete (empty) variable - return yl_speak_up.del_quest_variable(pname, entry_name, nil) -end - --- helper functions for yl_speak_up.input_fs_manage_variables(..) --- implements all the functions that are specific to managing variables and not part of --- general item management -yl_speak_up.fun_input_fs_manage_variables_check_fields = function(player, formname, fields, var_name, list_of_entries) - local pname = player:get_player_name() - if(not(var_name)) then - var_name = "" - end - local var_name_with_prefix = yl_speak_up.restore_complete_var_name(var_name, pname) - - -- show all stored values for a variable in a table - if(fields and fields.show_stored_values_for_var and var_name) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = yl_speak_up.fs_show_all_var_values(player, pname, var_name) - }) - return - -- show details about a quest (if it is a quest variable) - elseif(fields and fields.show_quest) then - yl_speak_up.show_fs(player, "manage_quests", var_name) - return - -- show where this variable is used - elseif(fields and fields.show_var_usage and fields.show_var_usage ~= "") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = yl_speak_up.fs_get_list_of_usage_of_variable( - fields.list_of_entries, pname, true, - "back_from_msg", - "Back to manage variables", - -- not an internal variable - false) - }) - return - -- enable, disable and list variables in debug mode - elseif(fields and fields.enable_debug_mode and var_name) then - yl_speak_up.set_variable_metadata(var_name, pname, "debug", pname, true) - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = "size[10,2]".. - "label[0.2,0.0;Activating debug mode for variable \"".. - minetest.colorize("#FFFF00", - minetest.formspec_escape(tostring(var_name))).. - "\".\nYou will now receive a chat message whenever the ".. - "variable changes.]".. - "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) - return - elseif(fields and fields.disable_debug_mode and var_name) then - yl_speak_up.set_variable_metadata(var_name, pname, "debug", pname, nil) - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = "size[10,2]".. - "label[0.2,0.0;Deactivating debug mode for variable \"".. - minetest.colorize("#FFFF00", - minetest.formspec_escape(tostring(var_name))).. - "\".\nYou will no longer receive a chat message whenever the ".. - "variable changes.]".. - "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) - return - elseif(fields and fields.list_debug_mode) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = "size[10,6]".. - "label[0.2,0.0;You are currently receiving debug information for the ".. - "following variables:]".. - "tablecolumns[text]".. - "table[0.8,0.8;8.8,4.0;list_of_variables_in_debug_mode;".. - -- the table entries will already be formspec_escaped - table.concat(yl_speak_up.get_list_of_debugged_variables(pname), ",").."]".. - "button[1.5,5.5;2,0.9;back_from_msg;Back]"}) - return - - -- a player name was given; the value for that player shall be shown - elseif(fields and fields.show_stored_value_for_player and var_name - and fields.stored_value_for_player and fields.stored_value_for_player ~= "") then - yl_speak_up.show_fs(player, "manage_variables", {var_name = var_name, - for_player = fields.stored_value_for_player}) - return - -- change the value for a player (possibly to nil) - elseif(fields and fields.store_new_value_for_player and var_name - and fields.stored_value_for_player and fields.stored_value_for_player ~= "") then - local old_value = yl_speak_up.get_quest_variable_value( - fields.stored_value_for_player, var_name_with_prefix) - yl_speak_up.set_quest_variable_value(fields.stored_value_for_player, var_name_with_prefix, - fields.current_value_for_player) - local new_value = yl_speak_up.get_quest_variable_value( - fields.stored_value_for_player, var_name_with_prefix) - local success_msg = minetest.colorize("#00FF00", "Successfully set variable") - if(new_value ~= fields.current_value_for_player) then - success_msg = minetest.colorize("#FF0000", "FAILED TO set variable") - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = "size[10,2.5]".. - "label[0.2,0.0;"..success_msg.." \"".. - minetest.colorize("#FFFF00", - minetest.formspec_escape(tostring(var_name))).. - "\"\nfor player ".. - minetest.formspec_escape(fields.stored_value_for_player).. - "\n(old value: ".. - minetest.colorize("#AAAAAA", old_value).. - ")\nto new value ".. - minetest.colorize("#FFFF00", fields.current_value_for_player)..".]".. - "button[1.5,2.0;2,0.9;back_from_msg;Back]"}) - return - -- remove the value for a player (set to nil) - elseif(fields and fields.unset_value_for_player and var_name - and fields.stored_value_for_player and fields.stored_value_for_player ~= "") then - local old_value = yl_speak_up.get_quest_variable_value( - fields.stored_value_for_player, var_name_with_prefix) - yl_speak_up.set_quest_variable_value(fields.stored_value_for_player, var_name_with_prefix, nil) - local new_value = yl_speak_up.get_quest_variable_value( - fields.stored_value_for_player, var_name_with_prefix) - local success_msg = minetest.colorize("#00FF00", "Unset variable") - if(new_value) then - success_msg = minetest.colorize("#FF0000", "FAILED TO unset variable") - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = "size[10,2]".. - "label[0.2,0.0;"..success_msg.." \"".. - minetest.colorize("#FFFF00", - minetest.formspec_escape(tostring(var_name))).. - "\"\nfor player ".. - minetest.formspec_escape(fields.stored_value_for_player).. - "\n(old value: ".. - minetest.colorize("#AAAAAA", old_value).. - ").]".. - "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) - return - -- revoke read or write access to a variable - elseif(fields - and ((fields.revoke_player_var_read_access and fields.revoke_player_var_read_access ~= "") - or (fields.revoke_player_var_write_access and fields.revoke_player_var_write_access ~= "")) - and var_name) then - local right = "read" - if(fields.revoke_player_var_write_access and fields.revoke_player_var_write_access ~= "") then - right = "write" - end - -- which player are we talking about? - local selected = yl_speak_up.speak_to[pname]["tmp_index_var_"..right.."_access"] - local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") - local tmp_list = {} - for k, v in pairs(pl_with_access) do - table.insert(tmp_list, k) - end - table.sort(tmp_list) - local grant_to = "" - if(selected > 1) then - grant_to = tmp_list[ selected-1 ] - end - local error_msg = "" - local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") - if(not(grant_to) or grant_to == "") then - error_msg = "For which player do you want to revoke "..right.." access?" - elseif(pname ~= yl_speak_up.npc_owner[ n_id ] - and not(minetest.check_player_privs(pname, {npc_talk_master=true}))) then - error_msg = "Only the owner of the NPC or players with\n".. - "the npc_talk_master priv can change this." - elseif(not(pl_with_access[ grant_to ])) then - error_msg = minetest.formspec_escape(grant_to).." doesn't have "..right.. - " access\nto this variable. Nothing changed." - -- try to revoke access - elseif(not(yl_speak_up.manage_access_to_quest_variable(var_name, pname, grant_to, - right.."_access", nil))) then - error_msg = "An internal error occoured." - else - -- not really an error message here...rather a success message - error_msg = "Revoked "..right.." access to variable\n\"".. - minetest.formspec_escape(var_name).. - "\"\nfor player "..minetest.formspec_escape(grant_to)..".\n".. - "Note: This will *not* affect existing preconditions/effects!" - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = "size[6,2]".. - "label[0.2,0.0;"..error_msg.."]".. - "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) - return - - -- grant read or write access to a variable - elseif(fields - and ((fields.grant_player_var_read_access and fields.grant_player_var_read_access ~= "") - or (fields.grant_player_var_write_access and fields.grant_player_var_write_access ~= "")) - and var_name) then - local right = "read" - if(fields.grant_player_var_write_access and fields.grant_player_var_write_access ~= "") then - right = "write" - end - local grant_to = fields[ "grant_player_var_"..right.."_access"] - local error_msg = "" - local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") - if(pname ~= yl_speak_up.npc_owner[ n_id ] - and not(minetest.check_player_privs(pname, {npc_talk_master=true}))) then - error_msg = "Only the owner of the NPC or players with\n".. - "the npc_talk_master priv can change this." - elseif(grant_to == pname) then - error_msg = "You already have "..right.." access to this variable." - elseif(pl_with_access[ grant_to ]) then - error_msg = minetest.formspec_escape(grant_to).." already has "..right.. - " access\nto this variable." - elseif(not(minetest.check_player_privs(grant_to, {interact=true}))) then - error_msg = "Player \""..minetest.formspec_escape(grant_to).."\" not found." - -- try to grant access - elseif(not(yl_speak_up.manage_access_to_quest_variable(var_name, pname, grant_to, - right.."_access", true))) then - error_msg = "An internal error occoured." - else - -- not really an error message here...rather a success message - error_msg = "Granted "..right.." access to variable\n\"".. - minetest.formspec_escape(var_name).. - "\"\nto player "..minetest.formspec_escape(grant_to).."." - end - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:manage_variables", - formspec = "size[6,2]".. - "label[0.2,0.0;"..error_msg.."]".. - "button[1.5,1.5;2,0.9;back_from_msg;Back]"}) - return - - -- the player clicked on a name in the list of players with read or write access - elseif(fields - and ((fields.list_var_read_access and fields.list_var_read_access ~= "") - or (fields.list_var_write_access and fields.list_var_write_access ~= "")) - and var_name) then - local right = "read" - if(fields.list_var_write_access and fields.list_var_write_access ~= "") then - right = "write" - end - local selected = fields[ "list_var_"..right.."_access"] - local pl_with_access = yl_speak_up.get_access_list_for_var(var_name, pname, right.."_access") - local tmp_list = {} - for k, v in pairs(pl_with_access) do - table.insert(tmp_list, k) - end - table.sort(tmp_list) - local index = table.indexof(tmp_list, selected) - if(selected == "Add player:") then - index = 0 - end - if(index and index > -1) then - yl_speak_up.speak_to[pname]["tmp_index_var_"..right.."_access"] = index + 1 - end - yl_speak_up.show_fs(player, "manage_variables") - return - end - -- this function didn't have anything to do - return "NOTHING FOUND" -end - - --- makes use of yl_speak_up.handle_input_fs_manage_general and is thus pretty short -yl_speak_up.input_fs_manage_variables = function(player, formname, fields) - local pname = player:get_player_name() - local list_of_entries = yl_speak_up.get_quest_variables(pname, true) - -- make names of own variables shorter - yl_speak_up.strip_pname_from_varlist(list_of_entries, pname) - table.sort(list_of_entries) - - local res = yl_speak_up.handle_input_fs_manage_general(player, formname, fields, - -- what_is_the_list_about, min_length, max_length, function_add_new_entry, - "variable", 2, 30, - yl_speak_up.fun_input_fs_manage_variables_add_new_entry, - list_of_entries, - yl_speak_up.fun_input_fs_manage_variables_del_old_entry, - yl_speak_up.fun_input_fs_manage_variables_check_fields) -end - - -yl_speak_up.get_fs_manage_variables = function(player, param) - local pname = player:get_player_name() - -- variables owned by the player - including those with write access - local var_list = yl_speak_up.get_quest_variables(pname, true) - -- make names of own variables shorter - yl_speak_up.strip_pname_from_varlist(var_list, pname) - - local formspec = {} - if(not(param) or type(param) ~= "table") then - param = {} - end - if(param and type(param) == "table" and param.var_name and param.var_name ~= "") then - local index = table.indexof(var_list, param.var_name) - yl_speak_up.speak_to[pname].tmp_index_general = index + 1 - end - table.insert(formspec, "size[18,12]".. - "label[0.2,1.2;Note: Each variable will store a diffrent value for each ".. - "player who interacts with the NPC.\n".. - "You can grant read and write access to other players for your ".. - "variables so that they can also use them as well.]") - local selected = yl_speak_up.build_fs_manage_general(player, param.var_name, - formspec, var_list, - "Create variable", - "Create a new varialbe with the name\n".. - "you entered in the field to the left.", - "variable", - "Enter the name of the new variable you\n".. - "want to create.", - "If you click here, the selected variable\n".. - "will be deleted.") - if(selected and selected ~= "") then - local k = selected - -- index 1 is "Add variable:" - local pl_with_read_access = yl_speak_up.get_access_list_for_var(k, pname, "read_access") - local pl_with_write_access = yl_speak_up.get_access_list_for_var(k, pname, "write_access") - if(not(yl_speak_up.speak_to[pname].tmp_index_var_read_access) - or yl_speak_up.speak_to[pname].tmp_index_var_read_access == 1) then - yl_speak_up.speak_to[pname].tmp_index_var_read_access = 1 - table.insert(formspec, "button[14.6,2.95;1.0,0.6;add_read_access;Add]".. - "tooltip[add_read_access;Grant the player whose name you entered\n".. - "you entered in the field to the left read access\n".. - "to your variable.]") - end - if(not(yl_speak_up.speak_to[pname].tmp_index_var_write_access) - or yl_speak_up.speak_to[pname].tmp_index_var_write_access == 1) then - yl_speak_up.speak_to[pname].tmp_index_var_write_access = 1 - table.insert(formspec, "button[14.6,3.95;1.0,0.6;add_write_access;Add]".. - "tooltip[add_write_access;Grant the player whose name you entered\n".. - "you entered in the field to the left *write* access\n".. - "to your variable.]") - end - local list_of_npc_users = "- none -" - local list_of_node_pos_users = "- none -" - -- expand name of variable k again - local k_long = yl_speak_up.add_pname_to_var(k, pname) - -- which npc and which node_pos use this variable? create a list for display - local c1 = 0 - local c2 = 0 - if(k_long - and yl_speak_up.player_vars[ k_long ] - and yl_speak_up.player_vars[ k_long ][ "$META$"]) then - local npc_users = yl_speak_up.get_variable_metadata(k_long, "used_by_npc") - c1 = #npc_users - if(npc_users and c1 > 0) then - list_of_npc_users = minetest.formspec_escape(table.concat(npc_users, ", ")) - end - local node_pos_users = yl_speak_up.get_variable_metadata(k_long, "used_by_node_pos") - c2 = #node_pos_users - if(node_pos_users and c2 > 0) then - list_of_node_pos_users = minetest.formspec_escape(table.concat( - node_pos_users, ", ")) - end - end - table.insert(formspec, "button[10.0,10.05;4.0,0.6;list_debug_mode;What am I debugging?]".. - "tooltip[list_debug_mode;".. - "Show for which variables you currently have ".. - "\nactivated the debug mode.]") - local debuggers = yl_speak_up.get_variable_metadata(k_long, "debug") - local i = table.indexof(debuggers, pname) - if(i and i > 0) then - table.insert(formspec, - "button[5.0,10.05;4.0,0.6;disable_debug_mode;Deactivate debug mode]".. - "tooltip[disable_debug_mode;".. - "You will no longer receive a chat message ".. - "\nwhen this value changes for a player.]") - else - table.insert(formspec, - "button[5.0,10.05;4.0,0.6;enable_debug_mode;Activate debug mode]".. - "tooltip[enable_debug_mode;".. - "You will receive a chat message whenever the value ".. - "\nof this variable changes for one player. The debug\n".. - "messages will be sent even after relogin.]") - end - -- checking/changing debug value for one specific player - if(not(param.for_player)) then - param.for_player = "" - end - table.insert(formspec, - "label[0.2,8.05;Show stored value for player:]".. - "field[4.9,7.75;4.0,0.6;stored_value_for_player;;") - table.insert(formspec, minetest.formspec_escape(param.for_player)) - table.insert(formspec, "]") - table.insert(formspec, - "button[9.0,7.75;4.5,0.6;show_stored_value_for_player;Show value for this player]".. - "tooltip[stored_value_for_player;Enter the name of the player for which you\n".. - "want to check (or change) the stored value.]".. - "tooltip[show_stored_value_for_player;Click here to read and the current value".. - "\nstored for this player.]") - if(param.for_player and param.for_player ~= "") then - local v = yl_speak_up.get_quest_variable_value(param.for_player, k_long) or "" - table.insert(formspec, - "label[0.2,9.05;Found stored value:]".. - "field[4.9,8.75;4.0,0.6;current_value_for_player;;") - table.insert(formspec, minetest.formspec_escape(v)) - table.insert(formspec, "]".. - "tooltip[current_value_for_player;You can see and change the current ".. - "value here.]".. - "button[9.0,8.75;4.5,0.6;store_new_value_for_player;".. - "Store this as new value]".. - "tooltip[store_new_value_for_player;".. - "Click here to update the stored value for this player.".. - "\nWARNING: Be very careful here and never do this without".. - "\n informing the player about this change!]".. - "button[13.9,8.75;3.0,0.6;unset_value_for_player;".. - "Remove this entry]".. - "tooltip[unset_value_for_player;Click here to delete the entry for this ".. - "player.\nSetting the entry to an empty string would not be ".. - "the same!]") - end - table.insert(formspec, "button[12.2,2.15;3.0,0.6;show_var_usage;Where is it used?]".. - "tooltip[show_var_usage;Show which NPC use this variable in which context.]".. - -- offer a dropdown list and a text input field for new varialbe names for adding - "label[0.2,3.25;Players with read access to this variable:]") - table.insert(formspec, yl_speak_up.create_dropdown_playerlist(player, pname, - pl_with_read_access, - yl_speak_up.speak_to[pname].tmp_index_var_read_access, - 6.9, 2.95, 0.0, 0.6, "list_var_read_access", "player", - "Remove player from list", - "grant_player_var_read_access", - "Enter the name of the player that shall\n".. - "have read access to this variable.", - "revoke_player_var_read_access", - "If you click here, the selected player\n".. - "will no longer be able to add new\n".. - "pre(C)onditions which read your variable.")) - table.insert(formspec, "label[0.2,4.25;Players with *write* access to this variable:]") - table.insert(formspec, yl_speak_up.create_dropdown_playerlist(player, pname, - pl_with_write_access, - yl_speak_up.speak_to[pname].tmp_index_var_write_access, - 6.9, 3.95, 0.0, 0.6, - "list_var_write_access", "player", "Remove player from list", - "grant_player_var_write_access", - "Enter the name of the player that shall\n".. - "have *write* access to this variable.", - "revoke_player_var_write_access", - "If you click here, the selected player\n".. - "will no longer be able to *write* new\n".. - "values into this variable.")) - local var_type = (yl_speak_up.get_variable_metadata(k_long, "var_type") - or "String/text or numerical value, depending on how you use it") - table.insert(formspec, "label[0.2,5.05;Type of variable: ") - table.insert(formspec, minetest.colorize("#FFFF00", var_type)) -- show variable type - table.insert(formspec, ".]") - if(var_type == "quest") then - table.insert(formspec, "button[4.2,4.75;4.5,0.6;show_quest;Show and edit this quest]") - end - table.insert(formspec, "label[0.2,6.05;This variable is used by the following ") - table.insert(formspec, - minetest.colorize("#FFFF00", tostring(c1)).." NPC:\n\t".. - -- those are only n_id - no need to formspec_escape that - minetest.colorize("#FFFF00", list_of_npc_users)) - table.insert(formspec, ".]") - table.insert(formspec, "label[0.2,7.05;This variable is used by the following ") - table.insert(formspec, - minetest.colorize("#FFFF00", tostring(c2)).." node positions:\n\t".. - -- those are only pos_to_string(..) - no need to formspec_escape that - minetest.colorize("#FFFF00", list_of_node_pos_users)) - table.insert(formspec, ".]") - table.insert(formspec, - "button[0.2,10.05;4.0,0.6;show_stored_values_for_var;Show all stored values]".. - "tooltip[show_stored_values_for_var;A diffrent value can be stored for each ".. - "player.\nShow these values in a table.]") - end - return table.concat(formspec, "") -end - - -yl_speak_up.register_fs("manage_variables", - yl_speak_up.input_fs_manage_variables, - yl_speak_up.get_fs_manage_variables, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_notes.lua b/editor/fs/fs_notes.lua deleted file mode 100644 index 84fd44f..0000000 --- a/editor/fs/fs_notes.lua +++ /dev/null @@ -1,66 +0,0 @@ - - -yl_speak_up.input_notes = function(player, formname, fields) - if(fields and fields.back) then - return yl_speak_up.show_fs(player, "talk") - elseif(fields and fields.store_notes and fields.notes_text) then - local pname = player:get_player_name() - local dialog = yl_speak_up.speak_to[pname].dialog - local n_id = yl_speak_up.speak_to[pname].n_id - -- update the dialog data the player sees - dialog.d_notes = fields.notes_text - -- actually store/update it on disc as well - local stored_dialog = yl_speak_up.load_dialog(n_id, false) - stored_dialog.d_notes = dialog.d_notes - yl_speak_up.save_dialog(n_id, stored_dialog) - -- log the change - yl_speak_up.log_change(pname, n_id, "Updated notes to: "..tostring(dialog.d_notes)) - return yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:notes", - formspec = "size[10,3]".. - "label[0.5,1.0;Notes successfully updated.]".. - "button[3.5,2.0;2,0.9;back_from_error_msg;Back]" - }) - else - return yl_speak_up.show_fs(player, "notes") - end -end - - -yl_speak_up.get_fs_notes = function(player, param) - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - -- generic dialogs are not part of the NPC - local dialog = yl_speak_up.speak_to[pname].dialog - return table.concat({"size[20,20]", - "label[2,0.5;Internal notes on NPC ", - minetest.formspec_escape(n_id or "- ? -"), - ", named ", - minetest.formspec_escape(dialog.n_npc) or "- ? -", - "]", - "button[17.8,0.2;2.0,0.9;back;Back]", - "button[15.0,0.2;2.0,0.9;store_notes;Save]", - "textarea[0.2,2;19.6,13;notes_text;Notes (shown only to those who can edit this NPC):;", - minetest.formspec_escape(dialog.d_notes or "Enter text here."), - "]", - "textarea[0.2,15.2;19.6,4.8;;;", - "This can be used to make your NPC more intresting by storing information about..\n".. - "* its character\n".. - "* special characteristics of the NPC\n".. - "* linguistic peculiarities and habits\n".. - "* origin, relationships, lots of lore\n".. - "* friendships / enmities\n".. - "* personal goals / motivations / background\n".. - "* planned quests\n".. - "* trades\n".. - "and whatever else you want to keep notes on for this NPC.]" - }) -end - - -yl_speak_up.register_fs("notes", - yl_speak_up.input_notes, - yl_speak_up.get_fs_notes, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_properties.lua b/editor/fs/fs_properties.lua deleted file mode 100644 index 903e2e9..0000000 --- a/editor/fs/fs_properties.lua +++ /dev/null @@ -1,139 +0,0 @@ --- allow owner to see and edit properties of the NPC - -yl_speak_up.input_properties = function(player, formname, fields) - local pname = player:get_player_name() - if(not(pname) or not(yl_speak_up.speak_to[pname])) then - return - end - local n_id = yl_speak_up.speak_to[pname].n_id - - if(fields and fields.back and fields.back ~= "") then - yl_speak_up.show_fs(player, "initial_config", - {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id, false}) - return - end - - local selected_row = nil - if(fields and fields.store_new_val and fields.store_new_val ~= "" and fields.prop_val) then - yl_speak_up.set_npc_property(pname, fields.prop_name, fields.prop_val, "manually") - - elseif(fields and fields.delete_prop and fields.delete_prop ~= "") then - -- delete the old property - yl_speak_up.set_npc_property(pname, fields.prop_name, nil, "manually") - - elseif(fields and fields.table_of_properties) then - local selected = minetest.explode_table_event(fields.table_of_properties) - if(selected.type == "CHG" or selected.type == "DLC") then - selected_row = selected.row - end - end - yl_speak_up.show_fs(player, "properties", {selected = selected_row}) -end - - -yl_speak_up.get_fs_properties = function(pname, selected) - if(not(pname)) then - return "" - end - local n_id = yl_speak_up.speak_to[pname].n_id - - -- is the player editing this npc? if not: abort - if(not(yl_speak_up.edit_mode[pname]) - or (yl_speak_up.edit_mode[pname] ~= n_id)) then - return "" - end - - -- we want the long version with additional information - local property_data = yl_speak_up.get_npc_properties_long_version(pname, true) - if(not(property_data)) then - -- something went wrong - there really is nothing useful we can do - -- if the NPC we want to interact with doesn't exist or is broken - return - end - local s = "" - if(not(property_data.prop_names)) then - property_data.prop_names = {} - end - local anz_prop = #property_data.prop_names - for i, k in ipairs(property_data.prop_names) do - local v = property_data.properties[k] - s = s.."#BBBBFF,"..minetest.formspec_escape(k)..","..minetest.formspec_escape(v).."," - end - s = s.."#00FF00,add,Add a new property" - - if(not(selected) or selected == "") then - selected = -1 - end - local add_selected = "label[3.5,6.5;No property selected.]" - selected = tonumber(selected) - if(selected > anz_prop + 1 or selected < 1) then - selected = -1 - elseif(selected > anz_prop) then - add_selected = "label[0.2,6.5;Add new property:]".. - "field[3.0,6.5;3.5,1.0;prop_name;;]".. - "label[6.5,6.5;with value:]".. - "field[8.2,6.5;4.5,1.0;prop_val;;]".. - "button[8.2,7.8;2.0,1.0;store_new_val;Store]" - -- external properties can usually only be read but not be changed - elseif(string.sub(property_data.prop_names[selected], 1, 5) == "self." - and not(yl_speak_up.custom_property_handler[property_data.prop_names[selected]])) then - add_selected = "label[3.5,6.5;Properties of the type \"self.\" usually cannot be modified.]" - elseif(string.sub(property_data.prop_names[selected], 1, 6) == "server" - and not(minetest.check_player_privs(pname, {npc_talk_admin=true}))) then - add_selected = "label[3.5,6.5;Properties starting with \"server\" can only be ".. - "changed by players\nwho have the \"npc_talk_admin\" priv." - else - local name = property_data.prop_names[selected] - local val = minetest.formspec_escape(property_data.properties[name]) - local name_esc = minetest.formspec_escape(name) - add_selected = "label[0.2,6.5;Change property:]".. - "field[3.0,6.5;3.5,1.0;prop_name;;"..name_esc.."]".. - "label[6.5,6.5;to value:]".. - "field[8.2,6.5;4.5,1.0;prop_val;;"..val.."]".. - "button[8.2,7.8;2.0,1.0;store_new_val;Store]".. - "button[10.4,7.8;2.0,1.0;delete_prop;Delete]" - end - if(selected < 1) then - selected = "" - end - local dialog = yl_speak_up.speak_to[pname].dialog - local npc_name = minetest.formspec_escape(dialog.n_npc or "- nameless -") - return table.concat({"size[12.5,8.5]", - "label[2,0;Properties of ", - npc_name, - " (ID: ", - tostring(n_id), - "):]", - "tablecolumns[color,span=1;text;text]", - "table[0.2,0.5;12,4.0;table_of_properties;", - s, - ";", - tostring(selected), - "]", - "tooltip[0.2,0.5;12,4.0;", - "Click on \"add\" to add a new property.\n", - "Click on the name of a property to change or delete it.]", - "label[2.0,4.5;".. - "Properties are important for NPC that want to make use of generic dialogs.\n".. - "Properties can be used to determine which generic dialog(s) shall apply to\n".. - "this particular NPC and how they shall be configured. You need the\n".. - "\"npc_talk_admin\" priv to edit properties starting with the text \"server\".]", - "button[5.0,7.8;2.0,0.9;back;Back]", - add_selected - }, "") -end - -yl_speak_up.get_fs_properties_wrapper = function(player, param) - if(not(param)) then - param = {} - end - local pname = player:get_player_name() - return yl_speak_up.get_fs_properties(pname, param.selected) -end - -yl_speak_up.register_fs("properties", - yl_speak_up.input_properties, - yl_speak_up.get_fs_properties_wrapper, - -- force formspec version 1: - 1 -) diff --git a/editor/fs/fs_quest_gui.lua b/editor/fs/fs_quest_gui.lua deleted file mode 100644 index e596756..0000000 --- a/editor/fs/fs_quest_gui.lua +++ /dev/null @@ -1,41 +0,0 @@ -yl_speak_up.input_quest_gui = function(player, formname, fields) - -- this return value is necessary for custom actions - local ret = {quit = true} - - local pname = player:get_player_name() - if(fields and fields.back_from_msg) then - yl_speak_up.show_fs(player, "quest_gui") - return ret - end - - -- new variables have to be added (and deleted) somewhere after all - if(fields.manage_variables) then - -- remember which formspec we are comming from - yl_speak_up.speak_to[pname][ "working_at" ] = "quest_gui" - yl_speak_up.show_fs(player, "manage_variables") - return ret - elseif(fields.manage_quests) then - yl_speak_up.speak_to[pname][ "working_at" ] = "quest_gui" - yl_speak_up.show_fs(player, "manage_quests") - return ret - end - -- the calling NPC shall no longer do anything - return ret -end - - -yl_speak_up.get_fs_quest_gui = function(player, param) - local pname = player:get_player_name() - return "size[24,20]".. - "label[0,0.5;Hi. This is a quest admin gui.]".. - "button[0.2,1.0;4.0,0.6;manage_variables;Manage variables]".. - "button[6.2,1.0;4.0,0.6;manage_quests;Manage quests]" -end - - -yl_speak_up.register_fs("quest_gui", - yl_speak_up.input_quest_gui, - yl_speak_up.get_fs_quest_gui, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_save_or_discard_or_back.lua b/editor/fs/fs_save_or_discard_or_back.lua deleted file mode 100644 index 26736a5..0000000 --- a/editor/fs/fs_save_or_discard_or_back.lua +++ /dev/null @@ -1,147 +0,0 @@ - --- when the player is editing the NPC and has changed it without having --- saved the changes yet: ask what shall be done (save? discard? back?) -yl_speak_up.input_save_or_discard_changes = function(player, formname, fields) - local pname = player:get_player_name() - -- if the player is not even talking to this particular npc - if(not(yl_speak_up.speak_to[pname])) then - return - end - - local target_dialog = yl_speak_up.speak_to[pname].target_dialog - if(not(target_dialog)) then - target_dialog = "" - end - - local edit_mode = (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id) - local d_id = yl_speak_up.speak_to[pname].d_id - local n_id = yl_speak_up.speak_to[pname].n_id - local o_id = yl_speak_up.speak_to[pname].o_id - - -- the player decided to go back and continue editing the current dialog - if(edit_mode and fields.back_to_dialog_changes) then - -- do NOT clear the list of changes; just show the old dialog again - yl_speak_up.show_fs(player, "show_last_fs", {}) - return - - -- save changes and continue on to the next dialog - elseif(edit_mode and fields.save_dialog_changes) then - -- actually save the dialog (the one the NPC currently has) - yl_speak_up.save_dialog(n_id, yl_speak_up.speak_to[pname].dialog) - -- log all the changes - for i, c in ipairs(yl_speak_up.npc_was_changed[ n_id ]) do - yl_speak_up.log_change(pname, n_id, c) - end - -- clear list of changes - yl_speak_up.npc_was_changed[ n_id ] = {} - -- save_dialog removed d_dynamic (because that is never to be saved!); we have - -- to add d_dynamic back so that we can use it as a target dialog in further editing: - yl_speak_up.speak_to[pname].dialog.n_dialogs["d_dynamic"] = {} - yl_speak_up.speak_to[pname].dialog.n_dialogs["d_dynamic"].d_options = {} - - -- discard changes and continue on to the next dialog - elseif(edit_mode and fields.discard_dialog_changes) then - -- the current dialog and the one we want to show next may both be new dialogs; - -- if we just reload the old state, they would both get lost - local target_dialog_data = yl_speak_up.speak_to[pname].dialog.n_dialogs[ target_dialog ] - -- actually restore the old state and discard the changes by loading the dialog anew - yl_speak_up.speak_to[pname].dialog = yl_speak_up.load_dialog(n_id, false) - -- clear list of changes - yl_speak_up.npc_was_changed[ n_id ] = {} - local dialog = yl_speak_up.speak_to[pname].dialog - -- do we have to save again after restoring current and target dialog? - local need_to_save = false - -- if the current dialog was a new one, it will be gone now - restore it - if(d_id and d_id ~= "" and not(dialog.n_dialogs[ d_id ])) then - -- we can't just restore the current dialog - after all the player wanted - -- to discard the changes; but we can recreate the current dialog so that it - -- is in the "new dialog" state again - local next_id = tonumber(string.sub( d_id, 3)) - yl_speak_up.add_new_dialog(dialog, pname, next_id) - yl_speak_up.log_change(pname, n_id, "Saved new dialog "..tostring( d_id )..".") - need_to_save = true - end - if(target_dialog and target_dialog ~= "" and not(dialog.n_dialogs[ target_dialog ])) then - -- restore the new target dialog - dialog.n_dialogs[ target_dialog ] = target_dialog_data - yl_speak_up.log_change(pname, n_id, "Saved new dialog "..tostring( target_dialog )..".") - need_to_save = true - end - if(need_to_save) then - yl_speak_up.save_dialog(n_id, dialog) - end - end - - -- are there any changes which might be saved or discarded? - if(edit_mode - and yl_speak_up.npc_was_changed[ n_id ] - and #yl_speak_up.npc_was_changed[ n_id ] > 0) then - - yl_speak_up.show_fs(player, "save_or_discard_changes", {}) - return - end - - yl_speak_up.show_fs(player, "proceed_after_save", {}) -end - - -yl_speak_up.get_fs_save_or_discard_changes = function(player, param) - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - -- TODO - local target_name = "quit" - local target_dialog = nil -- TODO - if(target_dialog and target_dialog ~= "") then - target_name = "go on to dialog "..minetest.formspec_escape(target_dialog) - if(target_dialog == "edit_option_dialog") then - target_name = "edit option \"".. - minetest.formspec_escape(tostring(o_id)).."\" of dialog \"".. - minetest.formspec_escape(tostring(d_id)).."\"" - end - end - - yl_speak_up.speak_to[pname].target_dialog = target_dialog - local d_id = yl_speak_up.speak_to[pname].d_id - -- reverse the order of the changes in the log so that newest are topmost - local text = "" - for i,t in ipairs(yl_speak_up.npc_was_changed[ n_id ]) do - text = minetest.formspec_escape(t).."\n"..text - end - -- build a formspec showing the changes to this dialog and ask for save - return table.concat({"size[14,6.2]", - "bgcolor[#00000000;false]", - -- TODO: make this more flexible - "label[0.2,0.2;You are about to leave dialog ", - minetest.formspec_escape(d_id), - " and ", - target_name, - ".]", - "label[0.2,0.65;These changes have been applied to dialog ", - minetest.formspec_escape(d_id), - ":]", - "hypertext[0.2,1;13.5,4;list_of_changes;", - minetest.formspec_escape(text), - "\n", - "]", - "button_exit[1.2,5.2;3,0.9;discard_dialog_changes;Discard changes]", - "button[5.7,5.2;3,0.9;back_to_dialog_changes;Back]", - "button_exit[10.2,5.2;3,0.9;save_dialog_changes;Save changes]", - "tooltip[save_dialog_changes;Save all changes to this dialog and ", - target_name, - ".]", - "tooltip[discard_dialog_changes;Undo all changes and ", - target_name, - ".]", - "tooltip[back_to_dialog_changes;Go back to dialog ", - minetest.formspec_escape(d_id), - " and continue editing it.]" - }, "") -end - - -yl_speak_up.register_fs("save_or_discard_changes", - yl_speak_up.input_save_or_discard_changes, - yl_speak_up.get_fs_save_or_discard_changes, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_show_all_var_values.lua b/editor/fs/fs_show_all_var_values.lua deleted file mode 100644 index db0389f..0000000 --- a/editor/fs/fs_show_all_var_values.lua +++ /dev/null @@ -1,64 +0,0 @@ - --- called only by mange_variables formspec -yl_speak_up.fs_show_all_var_values = function(player, pname, var_name) - -- wrong parameters? no need to show an error message here - if(not(var_name) or not(pname) or not(player)) then - return "" - end - -- TODO: check if the player really has read access to this variable - var_name = yl_speak_up.restore_complete_var_name(var_name, pname) - - -- player names with values as key; normally the player name is the key and - -- the value the value - but that would be a too long list to display, and - -- so we rearrange the array for display here - local players_with_value = {} - -- the diffrent values that exist - local values = {} - local var_data = yl_speak_up.player_vars[ var_name ] - local count_players = 0 - for player_name, v in pairs(var_data) do - -- metadata is diffrent and not of relevance here - if(player_name and player_name ~= "$META$" and v) then - if(not(players_with_value[ v ])) then - players_with_value[ v ] = {} - table.insert(values, v) - end - table.insert(players_with_value[ v ], player_name) - count_players = count_players + 1 - end - end - -- the values ought to be shown in a sorted way - table.sort(values) - - -- construct the lines that shall form the table - local lines = {"#FFFFFF,Value:,#FFFFFF,Players for which this value is stored:"} - for i, v in ipairs(values) do - table.insert(lines, - "#FFFF00,"..minetest.formspec_escape(v)..",#CCCCCC,".. - -- text, prefix, line_length, max_lines - yl_speak_up.wrap_long_lines_for_table( - table.concat(players_with_value[ v ], ", "), - ",,,#CCCCCC,", 80, 8)) - end - -- true here means: lines are already sorted; - -- ",": don't insert blank lines between entries - local formspec = yl_speak_up.print_as_table_prepare_formspec(lines, "table_of_variable_values", - "back_from_msg", "Back", true, ",", - "color,span=1;text;color,span=1;text") -- the table columns - table.insert(formspec, - "label[18.0,1.8;".. - minetest.formspec_escape("For variable \"".. - minetest.colorize("#FFFF00", tostring(var_name or "- ? -")).. - "\", these values are stored:").."]") - - if(values and #values > 0) then - table.insert(formspec, - "label[18.0,31.0;The variable holds ".. - minetest.colorize("#FFFF00", tostring(#values)).." diffrent values for ".. - minetest.colorize("#FFFF00", tostring(count_players)).." diffrent players.]") - else - table.insert(formspec, - "label[18.0,31.0;The variable does not currently hold any stored values.]") - end - return table.concat(formspec, "\n") -end diff --git a/editor/fs/fs_show_what_points_to_this_dialog.lua b/editor/fs/fs_show_what_points_to_this_dialog.lua deleted file mode 100644 index d4319e2..0000000 --- a/editor/fs/fs_show_what_points_to_this_dialog.lua +++ /dev/null @@ -1,256 +0,0 @@ --- helpful for debugging the content/texts of the created dialog structure - -yl_speak_up.input_show_what_points_to_this_dialog = function(player, formname, fields) - local pname = player:get_player_name() - if(fields.back_from_show_what_points_here - or not(fields.turn_dialog_into_alternate_text)) then - -- back to the dialog - 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 - end - -- fields.turn_dialog_into_alternate_text is set - local n_id = yl_speak_up.speak_to[pname].n_id - local this_dialog = yl_speak_up.speak_to[pname].d_id - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(dialog) - or not(dialog.n_dialogs) - or not(this_dialog) - or not(dialog.n_dialogs[ this_dialog ])) then - return - end - -- only show this information when editing this npc - if(yl_speak_up.edit_mode[pname] ~= yl_speak_up.speak_to[pname].n_id) then - return - end - -- find out what needs to be turned into an alternate dialog - local found = {} - -- how many options does the current dialog have? - local count_options = 0 - -- iterate over all dialogs - for d_id, d in pairs(dialog.n_dialogs) do - -- the dialog itself may have options that point back to the dialog itself - if(d.d_options) then - -- iterate over all options - for o_id, o in pairs(d.d_options) do - -- this is only possible if there are no options for this dialog - if(d_id == this_dialog) then - count_options = count_options + 1 - end - -- preconditions are not relevant; - -- effects are (dialog and on_failure) - if(o.o_results) then - for r_id, r in pairs(o.o_results) do - if(r and r.r_type and r.r_type == "dialog" - and r.r_value == this_dialog) then - table.insert(found, {d_id=d_id, o_id=o_id, id=r_id, - element=r, text="option was selected"}) - elseif(r and r.r_type and r.r_type == "on_failure" - and r.r_value == this_dialog) then - table.insert(found, {d_id=d_id, o_id=o_id, id=r_id, - element=r, text="the previous effect failed"}) - end - end - end - -- actions may be relevant - if(o.actions) then - for a_id, a in pairs(o.actions) do - if(a and a.a_on_failure - and a.a_on_failure == this_dialog) then - table.insert(found, {d_id=d_id, o_id=o_id, id=a_id, - element=a, text="action failed"}) - end - end - end - end - end - end - - local error_msg = "" - if(count_options > 0) then - error_msg = "This dialog still has dialog options.\nConversion not possible." - elseif(#found < 1) then - error_msg = "Found no option, action or effect\nthat points to this dialog." - elseif(#found > 1) then - error_msg = "Found more than one option, action\nor effect that points to this dialog." - end - if(error_msg ~= "") then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:show_what_points_to_this_dialog", - formspec = "size[8,2]".. - "label[0.2,0.5;Error: "..error_msg.."]".. - "button[1.5,1.5;2,0.9;back_from_error_msg;Back]"}) - return - end - - -- all fine so far; this is the text we want to set as alternate text - local d_text = dialog.n_dialogs[ this_dialog ].d_text - local f = found[1] - -- are we dealing with a result/effect or an action? - t = "o_results" - if(f.element.a_id) then - t = "actions" - end - -- there may already be an alternate text stored there - local alternate_text = dialog.n_dialogs[ f.d_id ].d_options[ f.o_id ][ t ][ f.id ].alternate_text - if(not(alternate_text)) then - -- no old text found - alternate_text = d_text - else - -- the old text may reference this d_text - alternate_text = string.gsub(alternate_text, "%$TEXT%$", d_text) - end - -- log the change - table.insert(yl_speak_up.npc_was_changed[ n_id ], - "Dialog "..tostring(this_dialog)..": Deleted this dialog and turned it into an ".. - "alternate text for dialog \""..tostring(f.d_id).."\" option \""..tostring(f.o_id).. - "\" element \""..tostring(f.id).."\".") - - -- actually set the new alternate_text - dialog.n_dialogs[ f.d_id ].d_options[ f.o_id ][ t ][ f.id ].alternate_text = alternate_text - -- delete this dialog - dialog.n_dialogs[ this_dialog ] = nil - -- we need to show a new/diffrent dialog to the player now - because the old one was deleted - yl_speak_up.speak_to[pname].d_id = f.d_id - yl_speak_up.speak_to[pname].o_id = f.o_id - if(t == "o_results") then - -- we can't really know where this ought to point to - the old dialog is gone, so - -- let's point to the current dialog to avoid errors - dialog.n_dialogs[ f.d_id ].d_options[ f.o_id ][ t ][ f.id ].r_value = f.d_id - -- dialog - normal switching to the next dialog or on_failure - the previous effect failed: - yl_speak_up.show_fs(player, "edit_effects", f.id) - else - -- the player may have to change this manually; we really can't know what would fit - -- (but the old dialog is gone) - dialog.n_dialogs[ f.d_id ].d_options[ f.o_id ][ t ][ f.id ].a_on_failure = f.d_id - -- an action failed: - yl_speak_up.show_fs(player, "edit_actions", f.id) - end -end - - --- show which dialogs point/lead to this_dialog -yl_speak_up.get_fs_show_what_points_to_this_dialog = function(player, this_dialog) - local pname = player:get_player_name() - local dialog = yl_speak_up.speak_to[pname].dialog - if(not(dialog) - or not(dialog.n_dialogs) - or not(this_dialog) - or not(dialog.n_dialogs[ this_dialog ])) then - return "" - end - - -- only show this information when editing this npc - if(yl_speak_up.edit_mode[pname] ~= yl_speak_up.speak_to[pname].n_id) then - return "" - end - local found = {} - -- colored lines for the table showing the results - local res = {} - -- iterate over all dialogs - for d_id, d in pairs(dialog.n_dialogs) do - -- the dialog itself may have options that point back to the dialog itself - if(d.d_options) then - -- iterate over all options - for o_id, o in pairs(d.d_options) do - local r_text = "" - local p_text = "" - local alternate_dialog = nil - local alternate_text = nil - -- preconditions are not relevant; - -- effects are (dialog and on_failure) - if(o.o_results) then - for r_id, r in pairs(o.o_results) do - if(r and r.r_type and r.r_type == "dialog" - and r.r_value == this_dialog) then - r_text = r_text..yl_speak_up.print_as_table_effect( - r, pname) - table.insert(found, {d_id, o_id, r_id, - "option was selected"}) - alternate_dialog = r.r_value - if(r.alternate_text) then - alternate_text = - "Show alternate text: ".. - tostring(r.alternate_text) - end - elseif(r and r.r_type and r.r_type == "on_failure" - and r.r_value == this_dialog) then - r_text = r_text..yl_speak_up.print_as_table_effect( - r, pname) - table.insert(found, {d_id, o_id, r_id, - "the previous effect failed"}) - alternate_dialog = r.r_value - alternate_text = "The previous effect failed. " - if(r.alternate_text) then - alternate_text = alternate_text.. - "Show alternate text: ".. - tostring(r.alternate_text) - else - alternate_text = alternate_text.. - "Show this dialog here." - end - end - end - end - -- actions may be relevant - if(o.actions) then - for a_id, a in pairs(o.actions) do - if(a and a.a_on_failure - and a.a_on_failure == this_dialog) then - p_text = p_text..yl_speak_up.print_as_table_action( - a, pname) - table.insert(found, {d_id, o_id, a_id, - "action failed"}) - alternate_dialog = a.a_on_failure - alternate_text = "The action failed. " - if(a.alternate_text) then - alternate_text = alternate_text.. - "Show this alternate text: ".. - tostring(a.alternate_text) - else - alternate_text = alternate_text.. - "Show this dialog here." - end - end - end - end - yl_speak_up.print_as_table_dialog(p_text, r_text, dialog, - dialog.n_id, d_id, o_id, - -- sort value: formed by dialog and option id (not perfect but - -- good enough) - res, o, tostring(d_id).." "..tostring(o_id), - alternate_dialog, alternate_text) - end - end - end - - local d_id = this_dialog - local formspec = yl_speak_up.print_as_table_prepare_formspec(res, "table_of_dialog_uses", - "back_from_show_what_points_here", "Back to dialog \""..tostring(d_id).."\"") - table.insert(formspec, - "label[20.0,1.8;Dialog \""..minetest.formspec_escape(this_dialog).. - "\" is referenced here:]") - if(#found ~= 1) then - table.insert(formspec, - "label[16.0,31.0;".. - minetest.formspec_escape("This dialog \""..tostring(d_id).. - "\" can be reached from ".. - minetest.colorize("#FFFF00", tostring(#found)).. - " options/actions/results.").."]") - else - table.insert(formspec, - "button[0.2,30.6;56.6,1.2;turn_dialog_into_alternate_text;".. - minetest.formspec_escape("Turn this dialog \"".. - tostring(d_id)).."\" into an alternate text.]") - end - return table.concat(formspec, "\n") -end - - -yl_speak_up.register_fs("show_what_points_to_this_dialog", - yl_speak_up.input_show_what_points_to_this_dialog, - yl_speak_up.get_fs_show_what_points_to_this_dialog, - -- no special formspec required: - nil -) diff --git a/editor/fs/fs_talkdialog_edit_mode.lua b/editor/fs/fs_talkdialog_edit_mode.lua deleted file mode 100644 index 4b7645e..0000000 --- a/editor/fs/fs_talkdialog_edit_mode.lua +++ /dev/null @@ -1,753 +0,0 @@ - --- we have a better version of this in the editor - so not offer this particular entry: -yl_speak_up.get_fs_talkdialog_add_basic_edit = function( - pname, formspec, h, pname_for_old_fs, is_a_start_dialog, - active_dialog, luaentity, may_edit_npc, anz_options) - return {h = h, formspec = formspec} -end - - --- This is the main talkdialog the NPC shows when right-clicked. (now in edit_mode) -local old_input_talk = yl_speak_up.input_talk -yl_speak_up.input_talk = function(player, formname, fields) - local pname = player:get_player_name() - -- Is the player working on this particular npc? - local edit_mode = yl_speak_up.in_edit_mode(pname) - -- if not: do the normal things outside edit mode - if(not(edit_mode) and not(fields.button_start_edit_mode)) then - return old_input_talk(player, formname, fields) - end - -- selected option/answer - local o = "" - -- do all the processing and executing old_input_talk (in non-edit_mode) - -- can do - but do not execute any actions; just return o - fields.just_return_selected_option = true - o = old_input_talk(player, formname, fields) - -- old_input_talk handled it (including some error detection like - -- wrong formname, not talking to npc, npc not configured) - - -- if in edit mode: detect if something was changed; - local result = yl_speak_up.edit_mode_apply_changes(pname, fields) - -- o is only nil if the old function returned nil; it does that - -- when it found a fitting reaction to a button press - if(not(o) and not(fields.button_start_edit_mode)) then - return - end - local n_id = yl_speak_up.speak_to[pname].n_id - - -- 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_talk_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 - -- make sure the inventory of the NPC is loaded - yl_speak_up.load_npc_inventory(n_id, true, nil) - -- 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 - - - -- show which dialogs point to this one - if(fields.show_what_points_to_this_dialog) then - local dialog = yl_speak_up.speak_to[pname].dialog - local d_id = yl_speak_up.speak_to[pname].d_id - yl_speak_up.show_fs(player, "show_what_points_to_this_dialog", - yl_speak_up.speak_to[pname].d_id) - return - end - - -- the player wants to change name and description; show the formspec - if(fields.button_edit_name_and_description) then - -- this is not the initial config - but the same formspec can be used - yl_speak_up.show_fs(player, "initial_config", - {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id, false}) - return - end - - -- change skin, cape and wielded items - if(fields.edit_skin) then - local dialog = yl_speak_up.speak_to[pname].dialog - -- necessary so that the fashin formspec can be created - yl_speak_up.speak_to[pname].n_npc = dialog.n_npc - yl_speak_up.show_fs(player, "fashion") - return - end - - if(fields.button_save_dialog) then - yl_speak_up.show_fs(player, "talk", - {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id, do_save = true}) - return - end - - if(fields.button_export_dialog) then - yl_speak_up.show_fs(player, "export") - return - end - - if(fields.button_edit_notes) then - yl_speak_up.show_fs(player, "notes") - return - end - - -- the player wants to give something to the NPC - -- (more complex in edit mode) - if(fields.player_offers_item) then - local dialog = yl_speak_up.speak_to[pname].dialog - local future_d_id = "d_got_item" - -- make sure this dialog exists; create if needed - if(not(dialog.n_dialogs[ future_d_id ])) then - dialog.n_dialogs[future_d_id] = { - d_id = future_d_id, - d_type = "text", - d_text = "", - d_sort = 9999 -- make this the last option - } - end - -- in edit mode: allow to edit the options - yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = future_d_id}) - return - end - - - -- button was clicked, now let's execute the results - local d_id = yl_speak_up.speak_to[pname].d_id - 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 - 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["quests_"..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 - - -- we may soon need actions and o_results from the selected_option - local selected_option = {} - if(yl_speak_up.check_if_dialog_has_option(dialog, d_id, o)) then - 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 - -- 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 - if(v and v.r_type == "dialog") then - show_dialog = v.r_value - 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 -end - - --- in edit mode, *all* options are displayed -local old_calculate_displayable_options = yl_speak_up.calculate_displayable_options -yl_speak_up.calculate_displayable_options = function(pname, d_options, allow_recursion) - if(yl_speak_up.in_edit_mode(pname)) then - -- no options - nothing to do - if(not(d_options)) then - return {} - end - -- in edit mode: show all options (but sort them first) - local retval = {} - local sorted_list = yl_speak_up.get_sorted_options(d_options, "o_sort") - for i, o_k in ipairs(sorted_list) do - retval[o_k] = true - end - return retval - end - -- outside edit mode: really calculate what can be displayed - return old_calculate_displayable_options(pname, d_options, allow_recursion) -end - - --- in edit mode, autoanswer, random dialogs and d_got_item play no role and are *not* applied --- (we want to see and edit all options regardless of preconditions) -local old_apply_autoanswer_etc = yl_speak_up.apply_autoanswer_and_random_and_d_got_item -yl_speak_up.apply_autoanswer_and_random_and_d_got_item = function(player, pname, d_id, dialog, allowed, active_dialog, recursion_depth) - -- no automatic switching in edit_mode - if(yl_speak_up.in_edit_mode(pname)) then - return - end - return old_apply_autoanswer_etc(player, pname, d_id, dialog, allowed, active_dialog, recursion_depth) -end - - --- helper function for yl_speak_up.get_fs_talkdialog: --- shows the text the NPC "speaks" and adds edit and navigation buttons --- (all only in *edit_mode*) -local old_talkdialog_main_text = yl_speak_up.get_fs_talkdialog_main_text -yl_speak_up.get_fs_talkdialog_main_text = function(pname, formspec, h, dialog, dialog_list, c_d_id, active_dialog, alternate_text) - if(not(yl_speak_up.in_edit_mode(pname))) then - return old_talkdialog_main_text(pname, formspec, h, dialog, dialog_list, c_d_id, active_dialog, alternate_text) - end - local d_id_to_dropdown_index = {} - -- allow to change skin, wielded items etc. - table.insert(formspec, "button[15.75,3.5;3.5,0.9;edit_skin;Edit Skin]") - - if(not(dialog) or not(dialog.n_dialogs)) then - return {h = h, formspec = formspec, d_id_to_dropdown_index = {}, dialog_list = dialog_list} - end - - -- display the window with the text the NPC is saying - -- 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 - 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_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", "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", "17.6,5.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 - - - 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[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", "3.5,5.0;1,0.9", "show_new_dialog", - "+", - "Create a new dialog.", - true) - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", "11.0,0.3;2,1.0", "button_edit_notes", - "Notes", - "Keep notes of what this NPC is for, how his character is etc.", - true) - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", "13.2,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, - "button", "15.4,0.3;2,0.9", "button_save_dialog", - "Save", - "Save this dialog.", - true) - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", "17.5,0.3;2.4,0.9", "button_export_dialog", - "Export", - "Export: Show the dialog in .json format which you can copy and store on your computer.", - 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"..tmp.. - "Note:\nThis is a special dialog. ".. - "It will be called when the player clicks on ".. - "I want to give you something.".. - "\nMost of the things listed below will be added automaticly when you add a ".. - "new option to this dialog. In most cases you may just have to edit the ".. - "precondition so that the right item is accepted, and then ".. - "set the target dialog according to your needs. Please also ".. - "edit the alternate text so that it fits your item!".. - "\nThis is how it works in detail:".. - "\nEach option you add here ought to deal with one item(stack) that ".. - "the NPC expects from the player, i.e. farming:bread 2. ".. - "Each option needs to be selected automaticly and ought to contain:".. - "\n* a precondition regarding ".. - "an item the player offered/gave to the NPC ".. - "(shown as player_offered_item in overview) ".. - "where you define which item(stack) is relevant for this option".. - "\n* an effect regarding an item the player offered to the NPC ".. - "(shown as deal_with_offered_item in overview) ".. - "where you define what shall happen to the offered item. Usually ".. - "the NPC will accept the item and put it into its inventory.".. - "\n* Don't forget to set a suitable target dialog for the effect! ".. - "Your NPC ought to comment on what he got, i.e. ".. - "Thank you for those two breads! You saved me from starving.".. - "You can also work with an alternate text here (as is done in the ".. - "default setup when adding a new option here).".. - "\n]") - -- static help text instead of text input field for d_trade - elseif(c_d_id == "d_trade") then - table.insert(formspec, "hypertext"..tmp.. - "Note:\nThis is a special dialog. ".. - "It will be called when the player clicks on ".. - "Let's trade!.".. - "\nSome of the things listed below will be added automaticly when you add a ".. - "new option to this dialog. In most cases you may just have to edit the ".. - "precondition so that the right item(stack) is beeing ".. - "searched for, and you need to add suitable effects. The ones added ".. - "automaticly are just an example.".. - "\nNote that once the NPC found a matching precondition, it will execute the ".. - "relevant effects and present the player the trade list. Any further options ".. - "that might also fit will not be executed this time. Only one option ".. - "(or none) will be selected each time.".. - "\nThis is how it works in detail:".. - "\nEach option you add here ought to deal with one item(stack) that ".. - "the NPC might or might not have in its inventory, ".. - "i.e. default:stick 4. ".. - "Each option needs to be selected automaticly and ought to contain:".. - "\n* at least one precondition regarding ".. - "the inventory of the NPC ".. - "where you define which item(stack) is relevant for this option ".. - "(you can add multiple such preconditions for each option)".. - "\n* at least one effect regarding what the NPC shall do if the ".. - "precondition matches. In most cases, NPC crafts something, ".. - "put item from the NPC's inventory into a chest etc. or ".. - "take item from a chest etc. and put it into the NPC's inventory ".. - "will be what you are looking for. More than one effect is possible.".. - "\n* In this particular case, no target dialog needs to be selected. After ".. - "executing the effect(s), the trade list view will be shown to the ".. - "player.".. - "\n]") - elseif(c_d_id == "d_dynamic") then - table.insert(formspec, "hypertext"..tmp.. - "Note:\nThis is a special dialog. ".. - "Each time right before this special dialog is displayed, a ".. - "function is called that can fill the d_dynamic dialog ".. - "with text and options.".. - "\nThat function has to decide based on NPC, player and context what ".. - "it wants to display this time.".. - "\nThe d_dynamic dialog is never saved 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 legitimate target ".. - "dialog 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]") - elseif(active_dialog and active_dialog.d_text) then - table.insert(formspec, "textarea"..tmp..";".. - minetest.formspec_escape(active_dialog.d_text or "?").. - "]") - else - table.insert(formspec, "textarea"..tmp..";".. - minetest.formspec_escape("[no text]").. - "]") - end - return {h = h, formspec = formspec, d_id_to_dropdown_index = d_id_to_dropdown_index, - dialog_list = dialog_list} -end - - --- helper function for yl_speak_up.get_fs_talkdialog: --- prints one entry (option/answer) in normal and *edit_mode* -local old_talkdialog_line = yl_speak_up.get_fs_talkdialog_line -yl_speak_up.get_fs_talkdialog_line = function( - formspec, h, pname_for_old_fs, oid, sb_v, - dialog, allowed, pname, - -- these additional parameters are needed *here*, in edit_mode: - active_dialog, dialog_list, d_id_to_dropdown_index, - current_index, anz_options) - - if(not(yl_speak_up.in_edit_mode(pname))) then - -- in normal mode: - return old_talkdialog_line(formspec, h, pname_for_old_fs, oid, sb_v, - dialog, allowed, pname, - active_dialog, dialog_list, d_id_to_dropdown_index, - current_index, anz_options) - end - - -- in edit mode: - local offset = 0.0 - local field_length = 43.8 - if(pname_for_old_fs) then - offset = 0.7 - field_length = 41.8 - 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.9+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 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 - 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! - local arrow = "->" - local only_once = "" - if(sb_v.o_visit_only_once and sb_v.o_visit_only_once == 1) then - arrow = "*" - 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(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.".. - only_once, - (target_dialog)) - - -- allow to set a new target dialog - 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")..",]") - -- add a tooltip "Change target dialog" - table.insert(formspec, "tooltip[5.0,"..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)) - - local d_option = active_dialog.d_options[sb_v.o_id] - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", tostring(2.25+offset)..","..h..";0.6,0.9", "quests_"..oid, - "Q", - "This option sets a (Q)est step if possible.\n".. - "A special precondition is evaluated automaticly\n".. - "to check if the quest step can be set.", - (d_option and d_option.quest_id and d_option.quest_step)) - - -- 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.05+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))) - - if(sb_v.o_autoanswer) then - table.insert(formspec, - "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(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(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..".", - true) - end - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, - "button", tostring(10.5+offset+field_length-2.2)..","..h..";1.0,0.9", "delete_option_"..oid, - "Del", - "Delete this option/answer.", - true) - - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, --- "image_button", tostring(9.9+offset+field_length-0.5)..","..h..";0.5,0.9".. --- ";gui_furnace_arrow_bg.png^[transformR180", - "button", tostring(10.5+offset+field_length-1.1)..","..h..";0.5,0.9", - "option_move_down_"..oid, - "v", - "Move this option/answer one down.", - (current_index < anz_options)) - yl_speak_up.add_formspec_element_with_tooltip_if(formspec, --- "image_button", tostring(9.9+offset+field_length-1.0)..","..h..";0.5,0.9".. --- ";gui_furnace_arrow_bg.png", - "button", tostring(10.5+offset+field_length-0.5)..","..h..";0.5,0.9", - "option_move_up_"..oid, - "^", - "Move this option/answer one up.", - (current_index > 1)) - return {h = h, formspec = formspec} -end - - --- add a prefix to "I want to give you something." dialog option in edit_mode: -local old_talkdialog_offers_item = yl_speak_up.get_fs_talkdialog_add_player_offers_item -yl_speak_up.get_fs_talkdialog_add_player_offers_item = function(pname, formspec, h, dialog, add_text, pname_for_old_fs) - local offer_item_add_text = nil - if(yl_speak_up.in_edit_mode(pname)) then - -- force showing the "I want to give you something"-text - offer_item_add_text = minetest.formspec_escape("[dialog d_got_item] -> ") - end - return old_talkdialog_offers_item(pname, formspec, h, dialog, offer_item_add_text, pname_for_old_fs) -end - - --- helper function for yl_speak_up.get_fs_talkdialog: --- if the player can edit the NPC, --- either add a button for entering edit mode --- or add the buttons needed to edit the dialog when in *edit mode* -local old_talkdialog_add_edit_and_command_buttons = yl_speak_up.get_fs_talkdialog_add_edit_and_command_buttons -yl_speak_up.get_fs_talkdialog_add_edit_and_command_buttons = function( - pname, formspec, h, pname_for_old_fs, is_a_start_dialog, - active_dialog, luaentity, may_edit_npc, anz_options) - -- add the buttons that are added to all editable NPC *first*: - -- inventory access, commands for mobs_npc, custom commands - local res = old_talkdialog_add_edit_and_command_buttons( - pname, formspec, h, pname_for_old_fs, is_a_start_dialog, - active_dialog, luaentity, may_edit_npc, anz_options) - formspec = res.formspec - h = res.h - -- if the player cannot *enter* edit_mode: - if(not(may_edit_npc)) then - return res - end - local edit_mode = yl_speak_up.in_edit_mode(pname) - -- button "show log" for those who can edit the NPC (entering edit mode is not required) - local text = minetest.formspec_escape( - "[Log] Show me your log.") - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "show_log", - text, text, - true, nil, nil, pname_for_old_fs) - -- Offer to enter edit mode if the player has the npc_talk_owner priv OR is allowed to edit the NPC. - -- The npc_talk_master priv allows to edit all NPC. - if(not(edit_mode)) then - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "button_start_edit_mode", - "Enters edit mode. In this mode, you can edit the texts the NPC says and the ".. - "answers that can be given.", - -- chat option: "I am your owner. I have new orders for you. - "I am your owner. I have new orders for you.", - true, nil, true, pname_for_old_fs) -- is button_exit - return {h = h, formspec = formspec} - end - - local offset = 0.0 - -- If in edit mode, add new menu entries: "add new options", "end edit mode" and what else is needed. - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "add_option", - -- chat option: "Add a new answer/option to this dialog." - "Adds a new option to this dialog. You can delete options via the option edit menu.", - "Add a new option/answer to this dialog. You can delete options via the option ".. - "edit menu.", - -- the amount of allowed options/answers has been reached - (anz_options < yl_speak_up.max_number_of_options_per_dialog), - "Maximum number of allowed answers/options reached. No further options/answers ".. - "can be added.", nil, pname_for_old_fs) - - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "delete_this_empty_dialog", - -- chat option: "Delete this dialog." - "Dialogs can only be deleted when they are empty and have no more ".. - "options/answers. This is the case here, so the dialog can be deleted.", - "Delete this empty dialog.", - (active_dialog and active_dialog.d_text == "" and anz_options == 0), - -- (but only show this option if the dialog is empty) - "If you want to delete this dialog, you need to delete all options and its ".. - "text first.", nil, pname_for_old_fs) - - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "show_what_points_to_this_dialog", - -- chat option: "Show what points to this dialog." - "Show which other dialog options or failed actions\n".. - "or effects lead the player to this dialog here.", - "Show what points to this dialog.", - -- there is no alternate text to show - true, nil, nil, pname_for_old_fs) - - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "make_first_option", - -- chat option: "Make this dialog the first one shown when starting to talk." - "The NPC has to start with one dialog when he is right-clicked. ".. - "Make this dialog the one shown.", - "Make this dialog the first one shown when starting a conversation.", - (active_dialog and active_dialog.d_sort and tonumber(active_dialog.d_sort) ~= 0), - -- (but only show this option if it's not already the first one) - "This dialog will be shown whenever a conversation is started.", nil,pname_for_old_fs) - - local b_text = "Turn this into" - if(is_a_start_dialog) then - b_text = "This shall no longer be" - end - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "turn_into_a_start_dialog", - "With automatic selection of options, it is possible that the real\n".. - "start dialog will never be shown to the player. However, we need\n".. - "to add some buttons to that start dialog for i.e. giving items\n".. - "to the NPC and for trading. Therefore, dialogs can be marked as\n".. - "*a* start dialog so that these buttons will be added to those dialogs.", - b_text.." *a* start dialog where buttons for trade etc. are shown.", - not(active_dialog and active_dialog.d_sort and tonumber(active_dialog.d_sort) == 0), - "The start dialog automaticly counts as *a* start dialog where buttons for ".. - "trade etc. are shown.", nil, pname_for_old_fs) - - -- chat option: Mute/Unmute NPC - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "mute_npc", - -- chat option: mute the NPC - "The NPC will no longer show his dialogs when he is right-clicked. This is ".. - "useful while you edit the NPC and don't want players to see ".. - "unfinished entries and/or quests.", - "State: Not muted. Stop talking to other players while I give you new orders.", - (luaentity and luaentity.yl_speak_up.talk), nil, nil, pname_for_old_fs) - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "un_mute_npc", - -- unmute the NPC - "The NPC will show his dialogs to other players when he is right-clicked. ".. - "This is the normal mode of operation. Choose this when you are ".. - "finished editing.", - "State: You are currently muted. Talk to anyone again who wants to talk to you.", - -- the NPC has to be there - (luaentity and not(luaentity.yl_speak_up.talk)), nil, nil, pname_for_old_fs) - - - h = yl_speak_up.add_edit_button_fs_talkdialog(formspec, h, - "button_end_edit_mode", - "Ends edit mode. From now on, your NPC will talk to you like he talks to other ".. - "players. You can always give him new orders by entering edit mode again.", - -- chat option:"That was all. I'm finished with giving you new orders. Remember them!" - "That was all. I'm finished with giving you new orders. Remember them!", - true, nil, true, pname_for_old_fs) -- is button_exit - return {h = h, formspec = formspec} -end - - --- apply force_edit_mode if necessary -local old_get_fs_talkdialog = yl_speak_up.get_fs_talkdialog -yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, recursion_depth) - if(not(player)) then - return - end - local pname = player:get_player_name() - -- are we in force edit mode, and can the player edit this NPC? - if(yl_speak_up.force_edit_mode[pname] - -- not already in edit mode? - and (not(yl_speak_up.edit_mode[pname]) or yl_speak_up.edit_mode[pname] ~= n_id) - and yl_speak_up.may_edit_npc(player, n_id)) then - yl_speak_up.edit_mode[pname] = n_id - end - return old_get_fs_talkdialog(player, n_id, d_id, alternate_text, recursion_depth) -end - ---[[ -yl_speak_up.get_fs_talk_wrapper = function(player, param) - if(not(param)) then - param = {} - end - -- recursion depth from autoanswer: 0 (the player selected manually) - return yl_speak_up.get_fs_talkdialog(player, param.n_id, param.d_id, param.alternate_text,0) -end ---]] - -yl_speak_up.register_fs("talk", - -- this function is changed here: - yl_speak_up.input_talk, - -- the underlying function is changed as well - but the wrapper calls that already; so ok: - yl_speak_up.get_fs_talk_wrapper, - -- no special formspec required: - nil -) - diff --git a/editor/print_as_table.lua b/editor/print_as_table.lua deleted file mode 100644 index 66ecdc7..0000000 --- a/editor/print_as_table.lua +++ /dev/null @@ -1,124 +0,0 @@ --- helper function -yl_speak_up.wrap_long_lines_for_table = function(text, prefix, line_length, max_lines) - -- show newlines as <\n> in order to save space - local text = (text or "?") - text = string.gsub(text, "\n", minetest.formspec_escape("
")) - -- break the text up into lines of length x - local parts = minetest.wrap_text(text, line_length, true) - if(not(parts) or #parts < 2) then - return minetest.formspec_escape(text) - end - local show_parts = {} - -- only show the first two lines (we don't have infinite room) - for i, p in ipairs(parts) do - if(i <= max_lines) then - table.insert(show_parts, minetest.formspec_escape(p)) - end - end - if(#parts > max_lines) then - return table.concat(show_parts, prefix)..minetest.formspec_escape(" [...]") - end - return table.concat(show_parts, prefix) -end - - --- helper functions for yl_speak_up.fs_get_list_of_usage_of_variable --- and yl_speak_up.show_what_points_to_this_dialog -yl_speak_up.print_as_table_precon = function(p, pname) - return ",#FFFF00,".. - minetest.formspec_escape(tostring(p.p_id)).. - ",#FFFF00,pre(C)ondition,#FFFF00,".. - minetest.formspec_escape(p.p_type)..",#FFFF00,".. - minetest.formspec_escape(yl_speak_up.show_precondition(p, pname)) -end - - -yl_speak_up.print_as_table_effect = function(r, pname) - return ",#55FF55,".. - minetest.formspec_escape(tostring(r.r_id)).. - ",#55FF55,(Ef)fect,#55FF55,".. - minetest.formspec_escape(r.r_type)..",#55FF55,".. - minetest.formspec_escape(yl_speak_up.show_effect(r, pname)) -end - - -yl_speak_up.print_as_table_action = function(a, pname) - return ",#FF9900,".. - minetest.formspec_escape(tostring(a.a_id)).. - ",#FF9900,(A)ction,#FF9900,".. - minetest.formspec_escape(a.a_type)..",#FF9900,".. - -- these lines can get pretty long when a description for a quest item is set - yl_speak_up.wrap_long_lines_for_table( - yl_speak_up.show_action(a, pname), - ",#FFFFFF,,#FFFFFF,,#FFFFFF,,#FF9900,", - 80, 4) -end - - -yl_speak_up.print_as_table_dialog = function(p_text, r_text, dialog, n_id, d_id, o_id, res, o, sort_value, - alternate_dialog, alternate_text) - if(p_text == "" and r_text == "" ) then - return - end - local d_text = yl_speak_up.wrap_long_lines_for_table( - dialog.n_dialogs[ d_id ].d_text or "?", - ",#FFFFFF,,#FFFFFF,,#FFFFFF,,#BBBBFF,", - 80, 3) - if(not(alternate_dialog) or not(alternate_text)) then - alternate_text = "" - else - alternate_text = ",#BBBBFF,"..minetest.formspec_escape(tostring(alternate_dialog)).. - -- show alternate text in a diffrent color - ",#BBBBFF,Dialog,#BBBBFF,says next:,#FFBBBB,".. - yl_speak_up.wrap_long_lines_for_table( - alternate_text, - ",#FFFFFF,,#FFFFFF,,#FFFFFF,,#FFBBBB,", - 80, 3) - end - res[ tostring(n_id).." "..tostring(d_id).." "..tostring(o_id) ] = { - text = "#6666FF,".. - tostring(n_id)..",#6666FF,NPC,#6666FF,named:,#6666FF,".. - minetest.formspec_escape(dialog.n_npc or "?")..",".. - "#BBBBFF,".. - tostring(d_id)..",#BBBBFF,Dialog,#BBBBFF,says:,#BBBBFF,".. - d_text..",".. - "#FFFFFF,".. - tostring(o_id)..",#FFFFFF,Option,#FFFFFF,A:,#FFFFFF,".. - minetest.formspec_escape(tostring(o.o_text_when_prerequisites_met or "?")).. - p_text..r_text.. - alternate_text, - sort_value = sort_value} -end - - -yl_speak_up.print_as_table_prepare_formspec = function(res, table_name, back_button_name, back_button_text, - is_already_sorted, concat_with, table_columns) - local sorted_res = {} - -- this is the default for "show where a variable is used" - if(not(is_already_sorted)) then - local sorted_list = yl_speak_up.get_sorted_options(res, "sort_value") - for i, k in pairs(sorted_list) do - table.insert(sorted_res, res[ k ].text) - end - table_columns = "color,span=1;text;color,span=1;text;color,span=1;text;color,span=1;text" - else - sorted_res = res - end - if(not(concat_with)) then - -- insert blank lines between lines belonging together - concat_with = ",#FFFFFF,,#FFFFFF,,#FFFFFF,,#FFFFFF,," - end - local formspec = { - "size[57,33]", - -- back to the list with that one precondition or effect - "button[0.2,0.2;56.6,1.2;"..back_button_name..";".. - minetest.formspec_escape(back_button_text).."]", - "button[0.2,31.6;56.6,1.2;"..back_button_name..";".. - minetest.formspec_escape(back_button_text).."]", - "tablecolumns["..tostring(table_columns).."]", - } - table.insert(formspec, - "table[1.2,2.4;55.0,28.0;"..tostring(table_name)..";".. - table.concat(sorted_res, concat_with).."]") - return formspec -end diff --git a/editor/show_fs_in_edit_mode.lua b/editor/show_fs_in_edit_mode.lua deleted file mode 100644 index 5a53c7f..0000000 --- a/editor/show_fs_in_edit_mode.lua +++ /dev/null @@ -1,98 +0,0 @@ - --- when in edit mode: ask for saving dialogs when needed -local old_show_fs = yl_speak_up.show_fs -yl_speak_up.show_fs = function(player, fs_name, param) - if(not(player)) then - return - end - local pname = player:get_player_name() - if(not(yl_speak_up.speak_to[pname])) then - return - end - - local last_fs = yl_speak_up.speak_to[pname].last_fs - -- show the save or discard changes dialog - if(fs_name and fs_name == "save_or_discard_changes") then - yl_speak_up.show_fs_ver(pname, "yl_speak_up:save_or_discard_changes", - yl_speak_up.get_fs_save_or_discard_changes(player, param)) - return - - -- the player either saved or discarded; we may proceed now - elseif(fs_name and fs_name == "proceed_after_save") then - fs_name = yl_speak_up.speak_to[pname].next_fs - param = yl_speak_up.speak_to[pname].next_fs_param - yl_speak_up.speak_to[pname].next_fs = nil - yl_speak_up.speak_to[pname].next_fs_param = nil - yl_speak_up.speak_to[pname].last_fs = fs_name - yl_speak_up.speak_to[pname].last_fs_param = param - if(not(fs_name) or fs_name == "quit") then - yl_speak_up.reset_vars_for_player(pname, false) - return - end - - -- the player clicked on "back" in the above dialog - elseif(fs_name and fs_name == "show_last_fs") then - -- call the last formspec again - and with the same parameters - fs_name = yl_speak_up.speak_to[pname].last_fs - param = yl_speak_up.speak_to[pname].last_fs_param - - -- do we need to check if there is something that needs saving? - elseif(fs_name - -- msg is just a loop for displaying (mostly error) messages - and fs_name ~= "msg" - and fs_name ~= "player_offers_item" - -- is the player editing the NPC? that is: might there be any changes? - and (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id)) then - local last_fs = yl_speak_up.speak_to[pname].last_fs - local d_id = yl_speak_up.speak_to[pname].d_id - local o_id = yl_speak_up.speak_to[pname].o_id - -- only these two formspecs need to ask specificly if the data ought to be saved - if(last_fs == "talk" or last_fs == "edit_option_dialog" or fs_name == "quit") then - local last_param = yl_speak_up.speak_to[pname].last_fs_param - local show_save_fs = false - if(not(param)) then - param = {} - end - -- set the target dialog - yl_speak_up.speak_to[pname].target_dialog = param.d_id - -- if we are switching from one dialog to another: is it the same? - if(last_fs == "talk" and fs_name == last_fs - and param and param.d_id and param.d_id ~= d_id) then - -- diffrent parameters: save (if needed) - show_save_fs = true - elseif(fs_name == "talk" and param and param.do_save) then - -- player clicked on save button - show_save_fs = true - -- leaving a dialog: save! - elseif(last_fs == "talk" and fs_name ~= last_fs) then - show_save_fs = true - -- clicking on "save" in an edit option dialog: save! - elseif(last_fs == "edit_option_dialog" and fs_name == last_fs - and param and param.caller and param.caller == "save_option") then - show_save_fs = true - -- leaving editing an option: save! - elseif(last_fs == "edit_option_dialog" and fs_name ~= last_fs) then - show_save_fs = true - -- quitting: save! - elseif(fs_name == "quit") then - yl_speak_up.speak_to[pname].target_dialog = nil - show_save_fs = true - end - -- show the save or discard dialog - if(show_save_fs) then - yl_speak_up.speak_to[pname].next_fs = fs_name - yl_speak_up.speak_to[pname].next_fs_param = param - -- check first if it's necessary to ask for save or discard - yl_speak_up.input_save_or_discard_changes(player, "", {}) - return - end - end - -- store the new formspec - yl_speak_up.speak_to[pname].last_fs = fs_name - -- and its parameter - yl_speak_up.speak_to[pname].last_fs_param = param - end - - -- Note: fs_name and param *may* have been changed in edit_mode by the code above - old_show_fs(player, fs_name, param) -end diff --git a/editor/trade_in_edit_mode.lua b/editor/trade_in_edit_mode.lua deleted file mode 100644 index 35d5a6f..0000000 --- a/editor/trade_in_edit_mode.lua +++ /dev/null @@ -1,70 +0,0 @@ --- overrides for api/api_trade_inv.lua: - --- the player *can* place something into the npc_gives inventory list in edit_mode: -local old_trade_inv_allow_put = yl_speak_up.trade_inv_allow_put -yl_speak_up.trade_inv_allow_put = function(inv, listname, index, stack, player) - if(not(player)) then - return 0 - end - -- allow putting something in in edit mode - but not otherwise - if(listname and listname == "npc_gives") then - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - -- only in edit mode! else the NPC manages this slot - if(n_id and yl_speak_up.in_edit_mode(pname)) then - return stack:get_count() - end - end - return old_trade_inv_allow_put(inv, listname, index, stack, player) -end - - --- prevent do_trade_simple from executing trade and reporting successful action: -local old_do_trade_simple = yl_speak_up.do_trade_simple -yl_speak_up.do_trade_simple = function(player, count) - if(not(player)) then - return - end - - local pname = player:get_player_name() - -- which trade are we talking about? - local trade = yl_speak_up.trade[pname] - - if(trade.n_id and yl_speak_up.edit_mode[pname] == trade.n_id) then - -- instruct old_do_trade_simple to neither execute the trade nor see this - -- as an action that was executed - trade.dry_run_no_exec = true - end - return old_do_trade_simple(player, count) -end - - - --- overrides for api/api_trade.lua: - --- do not allow deleting trades that are actions of an option if not in edit mode: -local old_delete_trade_simple = yl_speak_up.delete_trade_simple -yl_speak_up.delete_trade_simple = function(player, trade_id) - local pname = player:get_player_name() - local n_id = yl_speak_up.speak_to[pname].n_id - -- get the necessary dialog data - local dialog = yl_speak_up.speak_to[pname].dialog - if(dialog and dialog.trades and trade_id - and dialog.trades[ trade_id ] and n_id) then - - if( dialog.trades[ trade_id ].d_id - and yl_speak_up.edit_mode[pname] ~= n_id) then - yl_speak_up.show_fs(player, "msg", { - input_to = "yl_speak_up:do_trade_simple", - formspec = "size[6,2]".. - "label[0.2,-0.2;".. - "Trades that are attached to dialog options\n".. - "can only be deleted in edit mode. Please tell\n".. - "your NPC that you are its owner and have\n".. - "new commands!]".. - "button[2,1.5;1,0.9;back_from_error_msg;Back]"}) - return - end - end - return old_delete_trade_simple(player, trade_id) -end diff --git a/init.lua b/init.lua index 6d6636c..eeed388 100644 --- a/init.lua +++ b/init.lua @@ -229,7 +229,8 @@ yl_speak_up.reload = function(modpath, log_entry) dofile(modpath .. "export_to_ink.lua") dofile(modpath .. "fs/fs_export.lua") - dofile(modpath .. "editor/edit_mode.lua") + -- edit_mode.lua has been moved to the mod npc_talk_edit: +-- dofile(modpath .. "editor/edit_mode.lua") -- initialize and load all registered generic dialogs yl_speak_up.load_generic_dialogs() diff --git a/readme.md b/readme.md index d3aea33..dd79400 100644 --- a/readme.md +++ b/readme.md @@ -17,6 +17,12 @@ Reporting bugs: Please report issues ContentDB. +In order to be able to edit the dialogs of the NPC ingame, please install +npc_talk_edit. +The only situation where you might not need this extra mod is when you +design your own adventure game and your players are not expected to edit +the NPC. + Optional dependency: mobs_redo is highly recommended. You may be able to use other mob mods with @@ -30,7 +36,7 @@ You might also wish to use npc_talk if installed. -To get started, best install `yl_speak_up`, `npc_talk`, `mobs_redo` and `mobs_npc` in your world. +To get started, best install `yl_speak_up`, `npc_talk_edit`, `npc_talk`, `mobs_redo` and `mobs_npc` in your world. ## Table of Content