forked from Sokomine/yl_speak_up
added random option for dialogs
This commit is contained in:
parent
7f60031ab1
commit
90dc2d34d5
19
README.md
19
README.md
@ -300,6 +300,25 @@ once it hits an option where selecting has been set to "automaticly" and all oth
|
||||
preconditions are true, it will abort processing the current dialog and move on to
|
||||
the dialog stated in the automaticly selected option/answer and display that one.
|
||||
|
||||
Random Dialogs
|
||||
==============
|
||||
If you want the NPC to answer with one of several texts (randomly selected), then
|
||||
add a new dialog with options/answers that lead to your random texts and edit one
|
||||
of these options so that it is "randomly" selected.
|
||||
Note that random selection affects the entire dialog! That dialogs' text isn't shown
|
||||
anymore, and neither are the texts of the options/answers shown. Whenever your NPC
|
||||
ends up at this dialog, he'll automaticly choose one of the options/answers randomly
|
||||
and continue there!
|
||||
|
||||
Maximum recursion depth
|
||||
=======================
|
||||
Autoselect/autoanswer and random dialogs may both lead to further dialogs with further
|
||||
autoanswers and/or random selections. As this might create infinite loops, there's a
|
||||
maximum number of "redirections" through autoanswer and random selection that your NPC
|
||||
can take. It is configured in config.lua as
|
||||
yl_speak_up.max_allowed_recursion_depth
|
||||
and usually set to 5.
|
||||
|
||||
Giving things to the NPC
|
||||
========================
|
||||
There are several ways of giving items to the NPC: trade, using an action where the
|
||||
|
@ -349,18 +349,41 @@ yl_speak_up.edit_mode_apply_changes = function(pname, fields)
|
||||
|
||||
-- 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\".")
|
||||
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.otpion_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
|
||||
|
||||
|
@ -187,27 +187,31 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
|
||||
alternate_answer_option = "2"
|
||||
end
|
||||
|
||||
local answer_mode = 0
|
||||
-- shall this option be choosen automaticly?
|
||||
local autoanswer = 0
|
||||
if(d_option.o_autoanswer and d_option.o_autoanswer == 1) then
|
||||
autoanswer = 1
|
||||
answer_mode = 1
|
||||
-- or randomly?
|
||||
elseif(n_dialog.o_random) then
|
||||
answer_mode = 2
|
||||
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)..";]"
|
||||
"by clicking on it,automaticly,randomly;"..tostring(answer_mode+1)..";]"
|
||||
-- (automaticly *by fulfilling the prerequirements*)
|
||||
if(d_id == "d_got_item") then
|
||||
autoanswer = 1
|
||||
answer_mode = 1
|
||||
d_option.o_autoanswer = 1
|
||||
answer_text =
|
||||
"container[0.0,7.3]"..
|
||||
"label[0.2,0.0;..this option will be selected automaticly.]"
|
||||
end
|
||||
if(autoanswer == 0 and d_id ~= "d_got_item") then
|
||||
if(answer_mode == 0 and d_id ~= "d_got_item") 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)..";;"..
|
||||
@ -228,7 +232,7 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
|
||||
"tooltip[option_text_not_met;This is the answer the player may choose if the "..
|
||||
"preconditions are NOT all fulfilled.]"..
|
||||
"container_end[]"
|
||||
else
|
||||
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.]"..
|
||||
@ -237,6 +241,13 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
|
||||
"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[]"
|
||||
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)
|
||||
@ -269,8 +280,8 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
|
||||
local actions = d_option.actions
|
||||
local count_actions = 0
|
||||
local action_data = nil
|
||||
-- if autoanswer is choosen, then there can be no action
|
||||
if(autoanswer == 1) then
|
||||
-- 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 = ""
|
||||
@ -300,10 +311,14 @@ yl_speak_up.get_fs_edit_option_dialog = function(player, n_id, d_id, o_id, calle
|
||||
"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
|
||||
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;"..
|
||||
|
@ -530,6 +530,11 @@ yl_speak_up.get_fs_talkdialog_line_in_edit_mode = function(
|
||||
"label["..tostring(9.9+offset+0.2)..","..tostring(h+0.5)..";"..
|
||||
minetest.formspec_escape("[Automaticly selected if preconditions are met]")..
|
||||
"]")
|
||||
elseif(active_dialog.o_random) then
|
||||
table.insert(formspec,
|
||||
"label["..tostring(9.9+offset+0.2)..","..tostring(h+0.5)..";"..
|
||||
minetest.formspec_escape("[One of these options is randomly selected]")..
|
||||
"]")
|
||||
else
|
||||
-- show the actual text for the option
|
||||
yl_speak_up.add_formspec_element_with_tooltip_if(formspec,
|
||||
@ -724,10 +729,30 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, rec
|
||||
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))
|
||||
-- autoanswer or o_random may force to select a particular dialog
|
||||
local go_to_next_dialog = nil
|
||||
-- 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
|
||||
go_to_next_dialog = allowed["autoanswer"]
|
||||
-- randomly select an answer
|
||||
elseif(not(edit_mode) and allowed and active_dialog.o_random
|
||||
and (recursion_depth < yl_speak_up.max_allowed_recursion_depth)) then
|
||||
local liste = {}
|
||||
-- only allowed options can be randomly selected from
|
||||
for o_id, v in pairs(allowed) do
|
||||
if(v) then
|
||||
table.insert(liste, o_id)
|
||||
end
|
||||
end
|
||||
-- randomly select one of the possible dialogs
|
||||
if(#liste > 0) then
|
||||
go_to_next_dialog = liste[math.random(1, #liste)]
|
||||
end
|
||||
end
|
||||
|
||||
if(go_to_next_dialog and go_to_next_dialog ~= "") then
|
||||
-- no actions shall be executed
|
||||
local o_id = allowed["autoanswer"]
|
||||
local o_id = go_to_next_dialog
|
||||
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)
|
||||
@ -769,6 +794,7 @@ yl_speak_up.get_fs_talkdialog = function(player, n_id, d_id, alternate_text, rec
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
yl_speak_up.speak_to[pname].allowed = allowed
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user