added save/discard/back menu for saving changes

This commit is contained in:
Sokomine 2021-05-02 17:43:17 +02:00
parent 8c732e2dc4
commit fe5e5c40e8

View File

@ -1697,10 +1697,113 @@ yl_speak_up.add_new_dialog = function(dialog, pname)
return future_d_id
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)
if(not(target_dialog)) then
target_dialog = ""
end
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 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
-- 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
minetest.show_formspec(pname, "yl_speak_up:talk", get_fs_talkdialog(player, n_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)
save_dialog(n_id, yl_speak_up.speak_to[pname].dialog)
-- 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
-- actually restore the old state and discard the changes by loading the dialog anew
yl_speak_up.speak_to[pname].dialog = load_dialog(n_id)
-- clear list of changes
yl_speak_up.npc_was_changed[ n_id ] = {}
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)
end
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
-- some entries may be more than one line long
local tmp = ""
local parts = string.split(t, "\n", false)
for i, part in ipairs(parts) do
tmp = tmp..minetest.formspec_escape(part)..","
end
text = tmp..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)..":]"..
"textlist[0.2,1;13.5,4;list_of_changes;"..text.."]"..
"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.]"..
-- hidden field telling about the target dialog
"field[20,20;0.1,0.1;goto_target_dialog;target_dialog;"..minetest.formspec_escape(target_dialog).."]"
-- actaully show the formspec to the player
minetest.show_formspec(pname, "yl_speak_up:confirm_save", 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
-- move on to the target dialog
yl_speak_up.speak_to[pname].d_id = target_dialog
minetest.show_formspec(pname, "yl_speak_up:talk", get_fs_talkdialog(player, n_id, target_dialog))
end
-- helper function for formspec "yl_speak_up:talk" when a parameter was changed in edit mode;
-- this is called when the player is in edit_mode (editing the NPC);
-- the function checks if the player has changed any parameters
-- TODO: implement the change detection and ask the user what to do (save? discard?)
-- Parameters:
-- pname player name
-- fields the fields returned from the formspec
@ -1820,15 +1923,19 @@ yl_speak_up.edit_mode_apply_changes = function(pname, fields)
fields["d_id"] = d_id
fields["show_new_dialog"] = nil
end
-- TODO just for debugging
for k,v in pairs(yl_speak_up.npc_was_changed[ yl_speak_up.edit_mode[pname] ]) do
minetest.chat_send_player(pname, v )
end
end
-- end of yl_speak_up.edit_mode_apply_changes
minetest.register_on_player_receive_fields(
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
)
minetest.register_on_player_receive_fields(
function(player, formname, fields)
@ -1865,16 +1972,14 @@ minetest.register_on_player_receive_fields(
return
-- end edit mode (does not require the priv; will only switch back to normal behaviour)
elseif fields.button_end_edit_mode then
yl_speak_up.edit_mode[pname] = nil
-- start a new chat - but this time in normal mode
yl_speak_up.speak_to[pname].d_id = nil
minetest.show_formspec(pname, "yl_speak_up:talk", get_fs_talkdialog(player, yl_speak_up.speak_to[pname].n_id, nil))
-- 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)
return
end
if fields.quit or fields.button_exit then
-- Formspec was quit
yl_speak_up.speak_to[pname] = nil
-- 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)
return
end
@ -1948,8 +2053,8 @@ minetest.register_on_player_receive_fields(
end
end
end
yl_speak_up.speak_to[pname].d_id = show_dialog
minetest.show_formspec(pname, "yl_speak_up:talk", get_fs_talkdialog(player, yl_speak_up.speak_to[pname].n_id, show_dialog))
-- if there are any changes done: ask first and don't switch to the new dialog yet
yl_speak_up.save_changes_and_switch_to_other_dialog(player, fields, show_dialog)
return
end
@ -2079,9 +2184,9 @@ minetest.register_on_player_receive_fields(
end
if v.r_type == "dialog" then
if dialog.n_dialogs[v.r_value] ~= nil then
yl_speak_up.speak_to[pname].d_id = v.r_value
local n_id = yl_speak_up.speak_to[pname].n_id
minetest.show_formspec(pname, "yl_speak_up:talk", get_fs_talkdialog(player, n_id, v.r_value))
-- if there are any changes done: ask first and don't switch to the new dialog yet
yl_speak_up.save_changes_and_switch_to_other_dialog(player, fields, v.r_value)
return
else
say("This dialog does not exist")
end