split up input function of fs/fs_talkdialog.lua
This commit is contained in:
parent
682cc3bccd
commit
630287d99a
189
edit_mode.lua
189
edit_mode.lua
@ -7,6 +7,195 @@ yl_speak_up.in_edit_mode = function(pname)
|
||||
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
|
||||
-- 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
|
||||
|
||||
-- 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)
|
||||
|
||||
@ -60,6 +60,9 @@ end
|
||||
-- (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
|
||||
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
-- This is the main talkdialog the NPC shows when right-clicked.
|
||||
-- Returns o (selected dialog option) if fields.just_return_selected_option
|
||||
-- is set (useful for edit_mode).
|
||||
yl_speak_up.input_talk = function(player, formname, fields)
|
||||
if formname ~= "yl_speak_up:talk" then
|
||||
return
|
||||
end
|
||||
|
||||
local pname = player:get_player_name()
|
||||
local o = ""
|
||||
|
||||
-- error: not talking?
|
||||
if(not(yl_speak_up.speak_to[pname])) then
|
||||
@ -62,96 +63,7 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
return
|
||||
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)
|
||||
|
||||
-- if in edit mode: detect if something was changed;
|
||||
if(edit_mode or fields.button_edit_name_and_description) then
|
||||
local result = yl_speak_up.edit_mode_apply_changes(pname, fields)
|
||||
end
|
||||
|
||||
-- show which dialogs point to this one
|
||||
if(edit_mode and 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(edit_mode and 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
|
||||
|
||||
-- the player wants to access the inventory of the NPC
|
||||
if((edit_mode and fields.show_inventory)
|
||||
or (fields.show_inventory and yl_speak_up.may_edit_npc(player, n_id))) then
|
||||
-- the inventory is just an inventory with a back button; come back to this dialog here
|
||||
yl_speak_up.show_fs(player, "inventory")
|
||||
return
|
||||
end
|
||||
|
||||
-- change skin, cape and wielded items
|
||||
if(edit_mode and 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(edit_mode and 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(edit_mode and fields.button_export_dialog) then
|
||||
yl_speak_up.show_fs(player, "export")
|
||||
return
|
||||
end
|
||||
|
||||
if(edit_mode and fields.button_edit_notes) then
|
||||
yl_speak_up.show_fs(player, "notes")
|
||||
return
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- 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
|
||||
|
||||
-- normal mode + edit_mode (not exclusive to edit_mode):
|
||||
if fields.quit or fields.button_exit then
|
||||
-- if there are any changes done: ask first and don't quit yet
|
||||
yl_speak_up.show_fs(player, "quit", nil)
|
||||
@ -164,6 +76,27 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
return
|
||||
end
|
||||
|
||||
-- the player wants to give something to the NPC
|
||||
-- (less complex outside edit mode)
|
||||
if(fields.player_offers_item) then
|
||||
-- normal mode: take the item the player wants to offer
|
||||
yl_speak_up.show_fs(player, "player_offers_item", nil)
|
||||
return
|
||||
end
|
||||
|
||||
-- the player wants to access the inventory of the NPC
|
||||
if(fields.show_inventory and yl_speak_up.may_edit_npc(player, n_id)) then
|
||||
-- the inventory is just an inventory with a back button; come back to this dialog here
|
||||
yl_speak_up.show_fs(player, "inventory")
|
||||
return
|
||||
end
|
||||
|
||||
-- the player wants to see the trade list
|
||||
if(fields.show_trade_list) then
|
||||
yl_speak_up.show_fs(player, "trade_list", nil)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if fields.button_up then
|
||||
yl_speak_up.speak_to[pname].option_index =
|
||||
@ -184,35 +117,9 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
yl_speak_up.speak_to[pname].option_index = 1
|
||||
end
|
||||
|
||||
-- the player wants to see the trade list
|
||||
if(fields.show_trade_list) then
|
||||
yl_speak_up.show_fs(player, "trade_list", nil)
|
||||
return
|
||||
end
|
||||
|
||||
-- the player wants to give something to the NPC
|
||||
if(fields.player_offers_item) then
|
||||
if(not(edit_mode)) then
|
||||
-- normal mode: take the item the player wants to offer
|
||||
yl_speak_up.show_fs(player, "player_offers_item", nil)
|
||||
else
|
||||
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})
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- has an option/answer been selected?
|
||||
local o = ""
|
||||
for k, v in pairs(fields) do
|
||||
-- only split into 2 parts at max
|
||||
local s = string.split(k, "_", false, 2)
|
||||
@ -223,102 +130,37 @@ yl_speak_up.input_talk = function(player, formname, fields)
|
||||
o = s[2] .. "_" .. s[3]
|
||||
end
|
||||
end
|
||||
|
||||
if not(edit_mode) and o == "" then
|
||||
-- this is for edit mode - we need a diffrent reaction there, not executing actions
|
||||
if(fields.just_return_selected_option) then
|
||||
return o
|
||||
end
|
||||
-- nothing selected
|
||||
if(o == "") then
|
||||
return
|
||||
end
|
||||
|
||||
-- Let's check if the button was among the "allowed buttons". Only those may be executed
|
||||
if not(edit_mode) and (yl_speak_up.speak_to[pname].allowed and yl_speak_up.speak_to[pname].allowed[o] == false) then
|
||||
if(not(yl_speak_up.speak_to[pname].allowed) or not(yl_speak_up.speak_to[pname].allowed[o])) then
|
||||
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
|
||||
|
||||
-- we may soon need actions and o_results from the selected_option
|
||||
local selected_option = {}
|
||||
if(d_id and o and dialog
|
||||
and dialog.n_dialogs
|
||||
and dialog.n_dialogs[d_id]
|
||||
and dialog.n_dialogs[d_id].d_options
|
||||
and dialog.n_dialogs[d_id].d_options[o]) then
|
||||
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
|
||||
|
||||
if(not(edit_mode)) then
|
||||
-- abort if the option does not exist
|
||||
if(not(selected_option)) then
|
||||
return
|
||||
end
|
||||
yl_speak_up.speak_to[pname].o_id = o
|
||||
-- start with executing the first action
|
||||
yl_speak_up.execute_next_action(player, nil, true, formname)
|
||||
-- abort if the option does not exist
|
||||
if(not(selected_option)) then
|
||||
return
|
||||
end
|
||||
|
||||
-- if(edit_mode) (the other case has been dealt with above)
|
||||
-- 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
|
||||
|
||||
|
||||
-- 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
|
||||
yl_speak_up.speak_to[pname].o_id = o
|
||||
-- start with executing the first action
|
||||
yl_speak_up.execute_next_action(player, nil, true, formname)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- helper function for yl_speak_up.get_fs_talkdialog:
|
||||
-- shows the text the NPC "speaks"
|
||||
-- (this is pretty boring; the more intresting stuff happens in edit_mode)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user