players can now add others that may edit their npc with just npc_talk_owner priv

This commit is contained in:
Sokomine 2021-07-26 19:39:31 +02:00
parent 3e019907da
commit 430cbd65bb
2 changed files with 105 additions and 13 deletions

View File

@ -5,6 +5,11 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
local pname = player:get_player_name()
local n_id = yl_speak_up.speak_to[pname].n_id
-- not in edit mode? then abort
if(yl_speak_up.edit_mode[pname] ~= n_id or not(n_id)) then
return
end
if(fields.back_from_error_msg) then
-- no point in showing the formspec or error message again if we did so already
if(not(yl_speak_up.may_edit_npc(player, n_id))) then
@ -16,7 +21,7 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
return
end
if(not(fields.save_initial_config)) then
if(not(fields.save_initial_config) and (fields.quit or fields.exit)) then
-- is the player editing the npc? then leaving this config
-- dialog has to lead back to the talk dialog
if(yl_speak_up.edit_mode[pname] == n_id and n_id) then
@ -34,6 +39,7 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
if(fields.n_npc) then
fields.n_npc = fields.n_npc:match("^%s*(.-)%s*$")
end
local dialog = yl_speak_up.speak_to[pname].dialog
-- the player is trying to save the initial configuration
-- is the player allowed to initialize this npc?
if(not(yl_speak_up.may_edit_npc(player, n_id))) then
@ -56,6 +62,55 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
"have the \"npc_talk_owner\" priv. Else the\n"..
"new owner could not edit his own NPC."
end
-- want to change who may edit this npc?
-- delete a player from the list of those allowed to edit the NPC
elseif(fields.delete_may_edit and fields.delete_may_edit ~= ""
and fields.list_may_edit and fields.list_may_edit ~= "") then
if(pname ~= yl_speak_up.npc_owner[ n_id ]) then
error_msg = "Only the owner of the NPC\ncan change this."
elseif(not(dialog)) then
error_msg = "Please set a name for your NPC first!"
else
-- actually delete the player from the list
dialog.n_may_edit[ fields.list_may_edit ] = nil
-- show the next entry
yl_speak_up.speak_to[pname].tmp_index = math.max(1,
yl_speak_up.speak_to[pname].tmp_index-1)
end
-- add a player who may edit this NPC
elseif(fields.add_may_edit and fields.add_may_edit ~= "") then
if(pname ~= yl_speak_up.npc_owner[ n_id ]) then
error_msg = "Only the owner of the NPC\ncan change this."
elseif(fields.add_may_edit == pname) then
error_msg = "You are already the owner of this NPC!\nNo need to add you extra here."
elseif(not(minetest.check_player_privs(fields.add_may_edit, {interact=true}))) then
error_msg = "Player \""..minetest.formspec_escape(fields.add_may_edit)..
"\" not found."
elseif(not(dialog)) then
error_msg = "Please set a name for the NPC first!"
else
if(not(dialog.n_may_edit)) then
dialog.n_may_edit = {}
end
dialog.n_may_edit[ fields.add_may_edit ] = true
-- jump to the index with this player so that the player sees that he has been added
local tmp_list = yl_speak_up.sort_keys(dialog.n_may_edit, true)
local index = table.indexof(tmp_list, fields.add_may_edit)
if(index and index > 0) then
-- "Add player:" is added before all other names, so +1
yl_speak_up.speak_to[pname].tmp_index = index + 1
end
end
-- selected a player name in the why may edit this NPC dropdown?
elseif(fields.list_may_edit and fields.list_may_edit ~= "") then
local tmp_list = yl_speak_up.sort_keys(dialog.n_may_edit, true)
local index = table.indexof(tmp_list, fields.list_may_edit)
if(fields.list_may_edit == "Add player:") then
index = 0
end
if(index and index > -1) then
yl_speak_up.speak_to[pname].tmp_index = index + 1
end
end
if(error_msg) then
yl_speak_up.show_fs(player, "msg", { input_to = "yl_speak_up:initial_config",
@ -65,7 +120,6 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
return
end
local dialog = yl_speak_up.speak_to[pname].dialog
local d_id = yl_speak_up.speak_to[pname].d_id
local count = 0
if(dialog and dialog.n_dialogs) then
@ -102,11 +156,12 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
local dialog = yl_speak_up.fields_to_dialog(pname, f)
yl_speak_up.save_dialog(n_id, dialog)
yl_speak_up.speak_to[pname].dialog = dialog
dialog.n_may_edit = {}
yl_speak_up.log_change(pname, n_id,
"Initial config saved. "..
"NPC name: \""..tostring(fields.n_npc)..
"\" Description: \""..tostring(fields.n_description).."\"")
"\" Description: \""..tostring(fields.n_description).."\".")
-- just change name and description
else
dialog = yl_speak_up.speak_to[pname].dialog
@ -117,7 +172,9 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
yl_speak_up.log_change(pname, n_id,
"Name and/or description changed. "..
"NPC name: \""..tostring(fields.n_npc)..
"\" Description: \""..tostring(fields.n_description).."\"")
"\" Description: \""..tostring(fields.n_description)..
"\" May be edited by: \""..
table.concat(yl_speak_up.sort_keys(dialog.n_may_edit, true), " ").."\".")
end
dialog = yl_speak_up.speak_to[pname].dialog
@ -138,6 +195,11 @@ yl_speak_up.input_fs_initial_config = function(player, formname, fields)
end
end
if(not(save_initial_config)) then
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
-- actually start a chat with our new npc
yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id})
end
@ -159,14 +221,20 @@ yl_speak_up.get_fs_initial_config = function(player, n_id, d_id, is_initial_conf
local tmp_descr = "A new NPC without description"
local tmp_text = "Please provide your new NPC with a name and description!"
local tmp_owner = (yl_speak_up.npc_owner[ n_id ] or "- none -")
local table_of_names = {}
-- use existing name and description as presets when just editing
if(not(is_initial_config)) then
local dialog = yl_speak_up.speak_to[pname].dialog
tmp_name = (dialog.n_npc or tmp_name)
tmp_descr = (dialog.n_description or tmp_descr)
tmp_text = "You can change the name and description of your NPC."
-- dialog.n_may_edit was a string for a short time in development
if(not(dialog.n_may_edit) or type(dialog.n_may_edit) ~= "table") then
dialog.n_may_edit = {}
end
table_of_names = dialog.n_may_edit
end
local formspec = "size[10,5]"..
local formspec = "size[10,6]"..
"label[0.2,0.2;"..tmp_text.."]"..
-- name of the npc
"label[0.2,1.05;Name:]"..
@ -181,10 +249,21 @@ yl_speak_up.get_fs_initial_config = function(player, n_id, d_id, is_initial_conf
"field[2.0,3.2;8,0.9;n_owner;;"..minetest.formspec_escape(tmp_owner).."]"..
"tooltip[n_owner;The owner of the NPC. This can only be changed\n"..
"if you have the npc_talk_master priv.;#FFFFFF;#000000]"..
-- who can edit this NPC?
"label[0.2,4.05;May be edited by:]"..
-- offer a dropdown list and a text input field for player names for adding
yl_speak_up.create_dropdown_playerlist(player, pname,
table_of_names, yl_speak_up.speak_to[pname].tmp_index,
2.5, 3.9, "list_may_edit",
"add_may_edit", "edit your NPC.\n"..
"The player needs at least the npc_talk_owner priv\n"..
"in order to actually edit the NPC.",
"delete_may_edit",
"edit your NPC."
)..
-- save and exit buttons
"button_exit[3.2,4.2;2,0.9;save_initial_config;Save]"..
"button_exit[5.4,4.2;2,0.9;exit;Exit]"
"button_exit[3.2,5.2;2,0.9;save_initial_config;Save]"..
"button_exit[5.4,5.2;2,0.9;exit;Exit]"
-- show the formspec to the player
return formspec
end

View File

@ -1037,16 +1037,21 @@ end
-- simple sort of keys of a table numericly;
-- this is not efficient - but that doesn't matter: the lists are small and
-- it is only executed when configuring an NPC
yl_speak_up.sort_keys = function(t)
-- simple: if the parameter is true, the keys will just be sorted (i.e. player names) - which is
-- not enough for d_<nr>, o_<nr> etc. (which need more care when sorting)
yl_speak_up.sort_keys = function(t, simple)
local keys = {}
for k, v in pairs(t) do
-- add a prefix so that p_2 ends up before p_10
if(string.len(k) == 3) then
if(not(simple) and string.len(k) == 3) then
k = "a"..k
end
table.insert(keys, k)
end
table.sort(keys)
if(simple) then
return keys
end
for i,k in ipairs(keys) do
-- avoid cutting the single a from a_1 (action 1)
if(k and string.sub(k, 1, 1) == "a" and string.sub(k, 2, 2) ~= "_") then
@ -1830,6 +1835,13 @@ function yl_speak_up.talk(self, clicker)
yl_speak_up.speak_to[pname].option_index = 1
yl_speak_up.speak_to[pname].obj = self.object
-- is this player explicitly allowed to edit this npc?
if(yl_speak_up.speak_to[pname].dialog
and yl_speak_up.speak_to[pname].dialog.n_may_edit
and yl_speak_up.speak_to[pname].dialog.n_may_edit[pname] ) then
yl_speak_up.speak_to[pname].may_edit_this_npc = true
end
yl_speak_up.show_fs(clicker, "talk", {n_id = n_id})
local dialog = yl_speak_up.speak_to[pname].dialog
@ -1885,10 +1897,11 @@ yl_speak_up.may_edit_npc = function(player, n_id)
end
local pname = player:get_player_name()
-- is the player allowed to edit this npc?
return (yl_speak_up.npc_owner[ n_id ] == pname
and minetest.check_player_privs(player, {npc_talk_owner=true})
return ((yl_speak_up.npc_owner[ n_id ] == pname
and minetest.check_player_privs(player, {npc_talk_owner=true}))
or minetest.check_player_privs(player, {npc_talk_master=true})
or minetest.check_player_privs(player, {npc_master=true}))
or minetest.check_player_privs(player, {npc_master=true})
or yl_speak_up.speak_to[pname].may_edit_this_npc)
end