removed yl_speak_up.save_changes_and_switch_to_other_dialog; handled now by show_fs.lua and the new fs_save_or_discard_or_back.lua

This commit is contained in:
Sokomine 2021-06-27 04:33:14 +02:00
parent 1b28dd6a07
commit 661caaff4e
4 changed files with 217 additions and 176 deletions

View File

@ -0,0 +1,123 @@
-- 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 ] = {}
-- 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)
-- 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"
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 "formspec_version[3]"..
"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;<normal>"..
minetest.formspec_escape(text) .. "\n</normal>".."]"..
"button[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[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

View File

@ -1722,154 +1722,6 @@ yl_speak_up.get_result_id_by_type = function(dialog, d_id, o_id, result_type)
end
-- this is always called when switching to a new dialog; but only in edit_mode does
-- it show a formspec asking for change/back/discard
yl_speak_up.save_changes_and_switch_to_other_dialog = function(player, fields, target_dialog)
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
if(not(target_dialog)) then
target_dialog = yl_speak_up.speak_to[pname].target_dialog
if(not(target_dialog)) then
target_dialog = ""
end
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, "talk", {n_id = n_id, d_id = d_id})
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 ] = {}
-- 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)
-- 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(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(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
local target_name = "quit"
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
local formspec =
"formspec_version[3]"..
"size[14,6.2]"..
"bgcolor[#00000000;false]"..
"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;<normal>"..
minetest.formspec_escape(text) .. "\n</normal>".."]"..
"button[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[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.]"
-- actaully show the formspec to the player
yl_speak_up.show_fs(player, "msg", {input_to = "yl_speak_up:confirm_save",
formspec = formspec})
return
end
-- if there is nothing that needs to be saved or discarded: allow quit/exit
if fields.quit or fields.button_exit then
yl_speak_up.edit_mode[pname] = nil
-- Formspec was quit
yl_speak_up.speak_to[pname] = nil
return
end
-- end edit mode and start a new chat - but this time in normal mode
if not(target_dialog) or target_dialog == "" then
yl_speak_up.edit_mode[pname] = nil
target_dialog = nil
end
-- the trade list is not really a dialog...
if(target_dialog == "trade_list") then
yl_speak_up.speak_to[pname].target_dialog = nil
yl_speak_up.show_fs(player, "trade_list")
return
-- edit an option
elseif(target_dialog == "edit_option_dialog" and o_id and d_id) then
yl_speak_up.speak_to[pname].target_dialog = nil
yl_speak_up.show_fs(player, "edit_option_dialog",
{n_id = n_id, d_id = d_id, o_id = o_id, caller= "confirm_save"})
return
end
yl_speak_up.speak_to[pname].target_dialog = nil
-- move on to the target dialog
yl_speak_up.speak_to[pname].d_id = target_dialog
yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = target_dialog})
end
-- helper function for sorting options/answers using options[o_id].o_sort
-- (or dialogs by d_sort)
yl_speak_up.get_sorted_options = function(options, sort_by)
@ -2279,14 +2131,6 @@ end
-- end of yl_speak_up.edit_mode_apply_changes
yl_speak_up.input_confirm_save = function(player, formname, fields)
if formname ~= "yl_speak_up:confirm_save" then
return
end
yl_speak_up.save_changes_and_switch_to_other_dialog(player, fields, fields.goto_target_dialog)
end
-- identify multiple results that lead to target dialogs
yl_speak_up.check_for_disambigous_results = function(n_id, pname)
@ -2398,13 +2242,13 @@ yl_speak_up.input_talk = function(player, formname, fields)
-- 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.save_changes_and_switch_to_other_dialog(player, fields, nil)
yl_speak_up.show_fs(player, "quit", nil)
return
end
if fields.quit or fields.button_exit then
-- if there are any changes done: ask first and don't quit yet
yl_speak_up.save_changes_and_switch_to_other_dialog(player, fields, nil)
yl_speak_up.show_fs(player, "quit", nil)
return
end
@ -2429,11 +2273,7 @@ yl_speak_up.input_talk = function(player, formname, fields)
-- the player wants to see the trade list
if(fields.show_trade_list) then
if(edit_mode) then
yl_speak_up.save_changes_and_switch_to_other_dialog(player, fields, "trade_list")
return
end
yl_speak_up.show_fs(player, "trade_list")
yl_speak_up.show_fs(player, "trade_list", nil)
return
end
@ -2497,8 +2337,9 @@ yl_speak_up.input_talk = function(player, formname, fields)
-- 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.save_changes_and_switch_to_other_dialog(
player, fields, "edit_option_dialog")
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
@ -2534,13 +2375,7 @@ yl_speak_up.input_talk = function(player, formname, fields)
end
end
end
-- if there are any changes done: ask first and don't switch to the new dialog yet
if(show_dialog ~= d_id) then
yl_speak_up.save_changes_and_switch_to_other_dialog(player, fields, show_dialog)
-- show the same dialog again
else
yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id})
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

View File

@ -19,6 +19,8 @@ dofile(modpath .. "config.lua")
dofile(modpath .. "privs.lua")
-- handle on_player_receive_fields and showing of formspecs
dofile(modpath .. "show_fs.lua")
-- ask if the player wants to save, discard or go back in edit mode
dofile(modpath .. "fs_save_or_discard_or_back.lua")
-- common functions for editing preconditions and effects
dofile(modpath .. "fs_edit_general.lua")
-- edit preconditions (can be reached through edit options dialog)

View File

@ -8,8 +8,9 @@ minetest.register_on_player_receive_fields( function(player, formname, fields)
elseif formname == "yl_speak_up:setdialog" then
yl_speak_up.input_setdialog(player, formname, fields)
return true
elseif formname == "yl_speak_up:confirm_save" then
yl_speak_up.input_confirm_save(player, formname, fields)
-- handled in fs_save_or_discard_or_back.lua
elseif formname == "yl_speak_up:save_or_discard_changes" then
yl_speak_up.input_save_or_discard_changes(player, formname, fields)
return true
-- handled in fs_edit_options_dialog.lua
elseif formname == "yl_speak_up:edit_option_dialog" then
@ -82,6 +83,84 @@ yl_speak_up.show_fs = function(player, fs_name, param)
end
local pname = player:get_player_name()
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
minetest.show_formspec(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
-- 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"
-- 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
-- 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
elseif(fs_name == "quit") then
-- player wanted to quit
return
end
-- this is here mostly to fascilitate debugging - so that really all calls to
-- minetest.show_formspec are routed through here
if(fs_name == "msg") then
@ -91,6 +170,9 @@ yl_speak_up.show_fs = function(player, fs_name, param)
minetest.show_formspec(pname, param.input_to, param.formspec)
elseif(fs_name == "quit") then
return
-- staff-based editing
elseif(fs_name == "optiondialog") then
if(not(param)) then
@ -106,13 +188,12 @@ yl_speak_up.show_fs = function(player, fs_name, param)
minetest.show_formspec(pname, "yl_speak_up:setdialog",
yl_speak_up.get_fs_setdialog(player, param.n_id, param.d_id))
-- "confirm_save" does not have its own option here; doesn't have a get_fs_-function either
elseif(fs_name == "edit_option_dialog") then
-- the optional "caller" parameter can be used for debugging
if(not(param)) then
param = {}
end
yl_speak_up.speak_to[pname].o_id = param.o_id
minetest.show_formspec(pname, "yl_speak_up:edit_option_dialog",
yl_speak_up.get_fs_edit_option_dialog(player, param.n_id, param.d_id, param.o_id))