forked from Sokomine/yl_speak_up
avoid infinite loop in automatic/autoselect mode; added yl_speak_up.max_allowed_recursion_depth config option
This commit is contained in:
parent
788960ca0a
commit
8a7d6e24b3
@ -28,6 +28,12 @@ yl_speak_up.player_vars_save_file = "yl_speak_up_player_vars"
|
|||||||
-- (more time can pass if no variable is changed)
|
-- (more time can pass if no variable is changed)
|
||||||
yl_speak_up.player_vars_min_save_time = 60
|
yl_speak_up.player_vars_min_save_time = 60
|
||||||
|
|
||||||
|
-- An option may be choosen automaticly without the player having to click if all of its
|
||||||
|
-- preconditions are true and the mode is set to automatic. Now, if the choosen target
|
||||||
|
-- dialog has an option that also uses this automatic mode, infinite loops might be
|
||||||
|
-- created. This option exists to avoid them. Any small value will do.
|
||||||
|
yl_speak_up.max_allowed_recursion_depth = 5
|
||||||
|
|
||||||
-- Texts
|
-- Texts
|
||||||
|
|
||||||
yl_speak_up.message_button_option_exit = "Farewell!"
|
yl_speak_up.message_button_option_exit = "Farewell!"
|
||||||
|
@ -249,7 +249,8 @@ 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, in_edit_mode)
|
-- allow_recursion may be false - we need to avoid infinite loops
|
||||||
|
yl_speak_up.calculate_displayable_options = function(pname, d_options, in_edit_mode, allow_recursion)
|
||||||
-- 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 = {}
|
||||||
@ -269,7 +270,8 @@ yl_speak_up.calculate_displayable_options = function(pname, d_options, in_edit_m
|
|||||||
-- Can we display this option?
|
-- Can we display this option?
|
||||||
retval[o_k] = yl_speak_up.eval_all_preconditions(player, o_v.o_prerequisites, o_k, retval)
|
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?
|
-- 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
|
if(retval[o_k] and retval[o_k] == true and o_v.o_autoanswer and o_v.o_autoanswer == 1
|
||||||
|
and allow_recursion) then
|
||||||
-- abort here - because we already know which option needs to be selected next
|
-- abort here - because we already know which option needs to be selected next
|
||||||
retval["autoanswer"] = o_k
|
retval["autoanswer"] = o_k
|
||||||
return retval
|
return retval
|
||||||
|
@ -228,7 +228,8 @@ end
|
|||||||
|
|
||||||
-- talk
|
-- talk
|
||||||
|
|
||||||
yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text)
|
-- recursion_depth is increased each time autoanswer is automaticly selected
|
||||||
|
yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, recursion_depth)
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
local dialog = yl_speak_up.speak_to[pname].dialog
|
local dialog = yl_speak_up.speak_to[pname].dialog
|
||||||
local context_d_id = yl_speak_up.speak_to[pname].d_id
|
local context_d_id = yl_speak_up.speak_to[pname].d_id
|
||||||
@ -306,7 +307,9 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text)
|
|||||||
local edit_mode = (yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id)
|
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, edit_mode)
|
local allowed = yl_speak_up.calculate_displayable_options(pname, active_dialog.d_options, edit_mode,
|
||||||
|
-- avoid loops by limiting max recoursion depths for autoanswers
|
||||||
|
(recursion_depth < yl_speak_up.max_allowed_recursion_depth))
|
||||||
-- abort here if needed - the autoanswer/autoselection did choose an option for us alread
|
-- 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
|
if(not(edit_mode) and allowed and allowed["autoanswer"] and allowed["autoanswer"] ~= "") then
|
||||||
-- no actions shall be executed
|
-- no actions shall be executed
|
||||||
@ -323,7 +326,10 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text)
|
|||||||
target_dialog = yl_speak_up.speak_to[pname].d_id
|
target_dialog = yl_speak_up.speak_to[pname].d_id
|
||||||
end
|
end
|
||||||
-- show the new target dialog and exit
|
-- show the new target dialog and exit
|
||||||
return yl_speak_up.get_fs_talkdialog(player, n_id, target_dialog, res.alternate_text)
|
-- the recursion_depth will be increased by one (we did autoselect here and need to
|
||||||
|
-- avoid infinite loops)
|
||||||
|
return yl_speak_up.get_fs_talkdialog(player, n_id, target_dialog, res.alternate_text,
|
||||||
|
recursion_depth + 1)
|
||||||
end
|
end
|
||||||
yl_speak_up.speak_to[pname].allowed = allowed
|
yl_speak_up.speak_to[pname].allowed = allowed
|
||||||
|
|
||||||
|
@ -215,7 +215,8 @@ yl_speak_up.show_fs = function(player, fs_name, param)
|
|||||||
param = {}
|
param = {}
|
||||||
end
|
end
|
||||||
minetest.show_formspec(pname, "yl_speak_up:talk",
|
minetest.show_formspec(pname, "yl_speak_up:talk",
|
||||||
yl_speak_up.get_fs_talkdialog(player, param.n_id, param.d_id, param.alternate_text))
|
-- recursion depth from autoanswer: 0 (the player selected manually)
|
||||||
|
yl_speak_up.get_fs_talkdialog(player, param.n_id, param.d_id, param.alternate_text,0))
|
||||||
|
|
||||||
elseif(fs_name == "fashion") then
|
elseif(fs_name == "fashion") then
|
||||||
minetest.show_formspec(pname, "yl_speak_up:fashion",
|
minetest.show_formspec(pname, "yl_speak_up:fashion",
|
||||||
|
Loading…
Reference in New Issue
Block a user