added autoanswer/autoselect function (without loop detection)

This commit is contained in:
Sokomine 2021-12-29 04:10:41 +01:00
parent b33ba52d00
commit 788960ca0a
3 changed files with 134 additions and 44 deletions

View File

@ -172,6 +172,60 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
" does not exist.]".. " does not exist.]"..
"button_exit[2,1.5;1,0.9;exit;Exit]" "button_exit[2,1.5;1,0.9;exit;Exit]"
end end
-- offer the correct preselection for hidden/grey/show text
local alternate_answer_option = "3"
if(d_option.o_hide_when_prerequisites_not_met == "true") then
alternate_answer_option = "1"
elseif(d_option.o_grey_when_prerequisites_not_met == "true") then
alternate_answer_option = "2"
end
-- shall this option be choosen automaticly?
local autoanswer = 0
if(d_option.o_autoanswer and d_option.o_autoanswer == 1) then
autoanswer = 1
end
local answer_text =
-- answer of the player (the actual option)
"container[0.0,7.3]"..
"label[0.2,0.0;..the player may answer with this text"..
minetest.formspec_escape(" [dialog option \""..tostring(o_id).."\"]:").."]"..
"dropdown[16.0,-0.4;5.3,0.7;option_autoanswer;"..
"by clicking on it,automaticly;"..tostring(autoanswer+1)..";]"
-- (automaticly *by fulfilling the prerequirements*)
if(autoanswer == 0) then
answer_text = 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[]"
else
answer_text = answer_text..
"label[1.2,0.8;This option 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 dialog was choosen manually.]"..
"label[1.2,2.6;This is useful for offering a diffrent start dialog depending on the "..
"player's progress in a quest.]"..
"container_end[]"
end
-- remember which option we are working at (better than a hidden field) -- remember which option we are working at (better than a hidden field)
yl_speak_up.speak_to[pname].o_id = o_id yl_speak_up.speak_to[pname].o_id = o_id
-- are there any preconditions? -- are there any preconditions?
@ -202,6 +256,12 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
local actions = d_option.actions local actions = d_option.actions
local count_actions = 0 local count_actions = 0
local action_data = nil local action_data = nil
-- if autoanswer is choosen, then there can be no action
if(autoanswer == 1) then
actions = nil
count_actions = 0
caller = ""
end
if(actions) then if(actions) then
local sorted_key_list = yl_speak_up.sort_keys(actions) local sorted_key_list = yl_speak_up.sort_keys(actions)
for i, k in ipairs(sorted_key_list) do for i, k in ipairs(sorted_key_list) do
@ -222,6 +282,22 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
"Maximum amount of (A)ctions per option reached!" "Maximum amount of (A)ctions per option reached!"
end end
-- list of (A)ctions (there can only be one per option; i.e. a trade)
local action_list_text =
"container[0.0,11.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(autoanswer == 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[]"
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) -- find the right target dialog for this option (if it exists)
local target_dialog = nil local target_dialog = nil
-- which effect holds the information about the target dialog? -- which effect holds the information about the target dialog?
@ -298,13 +374,6 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
target_dialog = "- none -" target_dialog = "- none -"
end end
-- offer the correct preselection for hidden/grey/show text
local alternate_answer_option = "3"
if(d_option.o_hide_when_prerequisites_not_met == "true") then
alternate_answer_option = "1"
elseif(d_option.o_grey_when_prerequisites_not_met == "true") then
alternate_answer_option = "2"
end
-- can the button "prev(ious)" be shown? -- can the button "prev(ious)" be shown?
local button_prev = "" local button_prev = ""
@ -566,36 +635,10 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
"container_end[]".. "container_end[]"..
-- answer of the player (the actual option) -- answer of the player (the actual option)
"container[0.0,7.3]".. answer_text..
"label[0.2,0.0;..the player may answer with this text"..
minetest.formspec_escape(" [dialog option \""..tostring(o_id).."\"]:").."]"..
"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[]"..
-- list of (A)ctions (there can only be one per option; i.e. a trade) -- list of (A)ctions (there can only be one per option; i.e. a trade)
"container[0.0,11.0]".. action_list_text..
"label[0.2,0.0;When this answer has been selected, start the following (A)ction:]"..
"tablecolumns[text;color,span=1;text;text]"..
"table[1.2,0.3;20.2,0.7;table_of_actions;"..
list_of_actions..";0]"..
"container_end[]"..
-- list effects and target dialog for successful - and target dialog for unsuccessful -- list effects and target dialog for successful - and target dialog for unsuccessful
-- actions (including a toggle button) -- actions (including a toggle button)

View File

@ -249,7 +249,7 @@ end
-- this is called directly in yl_speak_up.get_fs_talkdialog -- this is called directly in yl_speak_up.get_fs_talkdialog
-- it returns a list of options whose preconditions are fulfilled -- it returns a list of options whose preconditions are fulfilled
yl_speak_up.calculate_displayable_options = function(pname, d_options) yl_speak_up.calculate_displayable_options = function(pname, d_options, in_edit_mode)
-- Let's go through all the options and see if we need to display them to the user -- Let's go through all the options and see if we need to display them to the user
local retval = {} local retval = {}
@ -264,9 +264,20 @@ yl_speak_up.calculate_displayable_options = function(pname, d_options)
-- list can work without causing loops or the like -- list can work without causing loops or the like
local sorted_list = yl_speak_up.get_sorted_options(d_options, "o_sort") local sorted_list = yl_speak_up.get_sorted_options(d_options, "o_sort")
for i, o_k in ipairs(sorted_list) do for i, o_k in ipairs(sorted_list) do
local o_v = d_options[ o_k ] if(not(in_edit_mode)) then
-- Can we display this option? local o_v = d_options[ o_k ]
retval[o_k] = yl_speak_up.eval_all_preconditions(player, o_v.o_prerequisites, o_k, retval) -- Can we display this option?
retval[o_k] = yl_speak_up.eval_all_preconditions(player, o_v.o_prerequisites, o_k, retval)
-- do we need to take care of an automatic autoanswer?
if(retval[o_k] and retval[o_k] == true and o_v.o_autoanswer and o_v.o_autoanswer == 1) then
-- abort here - because we already know which option needs to be selected next
retval["autoanswer"] = o_k
return retval
end
-- if in edit mode: no need to evaluate preconditions
else
retval[o_k ] = true
end
end end
return retval return retval
end end

View File

@ -301,8 +301,30 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text)
return "size[6,2]".. return "size[6,2]"..
"label[0.2,0.5;Ups! Something went wrong. Please try again.]" "label[0.2,0.5;Ups! Something went wrong. Please try again.]"
end end
-- Is the player working on this particular npc?
local edit_mode = (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id)
-- evaluate the preconditions of each option and check if the option can be offered -- evaluate the preconditions of each option and check if the option can be offered
local allowed = yl_speak_up.calculate_displayable_options(pname, active_dialog.d_options) local allowed = yl_speak_up.calculate_displayable_options(pname, active_dialog.d_options, edit_mode)
-- abort here if needed - the autoanswer/autoselection did choose an option for us alread
if(not(edit_mode) and allowed and allowed["autoanswer"] and allowed["autoanswer"] ~= "") then
-- no actions shall be executed
local o_id = allowed["autoanswer"]
local effects = active_dialog.d_options[o_id].o_results
-- execute all effects/results
local res = yl_speak_up.execute_all_relevant_effects(player, effects, o_id, true)
local target_dialog = res.next_dialog
yl_speak_up.speak_to[pname].o_id = nil
yl_speak_up.speak_to[pname].a_id = nil
if(not(target_dialog)
or target_dialog == ""
or not(dialog.n_dialogs[target_dialog])) then
target_dialog = yl_speak_up.speak_to[pname].d_id
end
-- show the new target dialog and exit
return yl_speak_up.get_fs_talkdialog(player, n_id, target_dialog, res.alternate_text)
end
yl_speak_up.speak_to[pname].allowed = allowed yl_speak_up.speak_to[pname].allowed = allowed
local portrait = calculate_portrait(pname, n_id) local portrait = calculate_portrait(pname, n_id)
@ -372,9 +394,6 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text)
"]", "]",
} }
-- 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)
-- this is used to build a list of all available dialogs for a dropdown menu in edit mode -- this is used to build a list of all available dialogs for a dropdown menu in edit mode
-- (only relevant in edit mode) -- (only relevant in edit mode)
local dialog_list = yl_speak_up.text_new_dialog_id local dialog_list = yl_speak_up.text_new_dialog_id
@ -1391,6 +1410,23 @@ yl_speak_up.edit_mode_apply_changes = function(pname, fields)
d_option.o_text_when_prerequisites_not_met = fields.option_text_not_met d_option.o_text_when_prerequisites_not_met = fields.option_text_not_met
end end
-- toggle autoselection/autoclick of an option
if(d_option and fields.option_autoanswer and fields.option_autoanswer ~= "") then
if(d_option.o_autoanswer and d_option.o_autoanswer == 1
and fields.option_autoanswer == "by clicking on it") then
d_option.o_autoanswer = nil
table.insert(yl_speak_up.npc_was_changed[ n_id ],
"Dialog "..d_id..": The modus for option "..tostring(o_id)..
" was changed from \"automaticly\" to \"by clicking on it\".")
elseif((not(d_option.o_autoanswer) or d_option.o_autoanswer ~= 1)
and fields.option_autoanswer == "automaticly") then
d_option.o_autoanswer = 1
table.insert(yl_speak_up.npc_was_changed[ n_id ],
"Dialog "..d_id..": The modus for option "..tostring(o_id)..
" was changed from \"by clicking on it\" to \"automaticly\".")
end
end
-- handle hide/grey out/show alternate answer -- handle hide/grey out/show alternate answer
-- (only happens in options edit menu) -- (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 and d_option) then
@ -1532,7 +1568,7 @@ yl_speak_up.input_talk = function(player, formname, fields)
end end
-- show which dialogs point to this one -- show which dialogs point to this one
if(fields.show_what_points_to_this_dialog) then if(edit_mode and fields.show_what_points_to_this_dialog) then
local dialog = yl_speak_up.speak_to[pname].dialog local dialog = yl_speak_up.speak_to[pname].dialog
local d_id = yl_speak_up.speak_to[pname].d_id 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.show_fs(player, "show_what_points_to_this_dialog",