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