-- set name, description and owner of the NPC -- (owner can only be set if the player has the npc_talk_master -- priv - not with npc_talk_owner priv alone) 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 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 return end -- show this formspec again 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 if(fields.edit_skin and fields.edit_skin ~= "") then yl_speak_up.show_fs(player, "fashion") return end if(fields.edit_properties and fields.edit_properties ~= "") then yl_speak_up.show_fs(player, "properties") return end if((not(fields.save_initial_config) and not(fields.show_nametag) and not(fields.list_may_edit) and not(fields.add_may_edit) ) or (fields and fields.exit)) then local dialog = yl_speak_up.speak_to[pname].dialog -- unconfigured NPC if(fields and fields.exit and not(dialog) or not(dialog.n_dialogs)) then minetest.chat_send_player(pname, "Aborting initial configuration.") return end -- 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 yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id}) end -- else we can quit here return end local error_msg = nil -- remove leading and tailing spaces from the potential new NPC name in order to avoid -- confusing names where a player's name (or that of another NPC) is beginning/ending -- with blanks 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 error_msg = "You are not allowed to edit this NPC." elseif(not(fields.n_npc) or string.len(fields.n_npc) < 2) then error_msg = "The name of your NPC needs to be\nat least two characters long." elseif(minetest.check_player_privs(fields.n_npc, {interact=true}) and not(minetest.check_player_privs(player, {npc_talk_master=true})) and not(minetest.check_player_privs(player, {npc_talk_admin=true}))) then error_msg = "You cannot name your NPC after an existing player.\n".. "Only those with the npc_talk_admin priv can do so." elseif(not(fields.n_description) or string.len(fields.n_description) < 2) then error_msg = "Please provide a description of your NPC!" -- sensible length limit elseif(string.len(fields.n_npc)>40 or string.len(fields.n_description)>40) then error_msg = "The name and description of your NPC\ncannot be longer than 40 characters." -- want to change the owner? elseif(fields.n_owner and fields.n_owner ~= yl_speak_up.npc_owner[ n_id ]) then if( not(minetest.check_player_privs(player, {npc_talk_master=true}))) then error_msg = "You need the \"npc_talk_master\" priv\nin order to change the owner." elseif(not(minetest.check_player_privs(fields.n_owner, {npc_talk_owner=true}))) then error_msg = "The NPC can only be owned by players that\n".. "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 woy 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", formspec = "size[6,2]".. "label[0.2,0.0;"..tostring(error_msg).."]".. "button[2,1.5;1,0.9;back_from_error_msg;Back]"}) return end -- warn players with npc_talk_master priv if the name of an npc is used by a player already if(minetest.check_player_privs(fields.n_npc, {interact=true})) then minetest.chat_send_player(pname, "WARNING: A player named \'"..tostring(fields.n_npc).. "\' exists. This NPC got assigned the same name!") end local d_id = yl_speak_up.speak_to[pname].d_id local count = 0 if(dialog and dialog.n_dialogs) then for k,v in pairs(dialog.n_dialogs) do count = count + 1 end end -- we checked earlier if the player doing this change and the -- player getting the NPC have appropriate privs if(fields.n_owner ~= yl_speak_up.npc_owner[ n_id ]) then yl_speak_up.log_change(pname, n_id, "Owner changed from "..tostring(yl_speak_up.npc_owner[ n_id ]).. " to "..tostring(fields.n_owner).." for ".. "NPC name: \""..tostring(fields.n_npc)) -- the owner will actually be changed further down, at the end of this function yl_speak_up.npc_owner[ n_id ] = fields.n_owner end -- give the NPC its first dialog if(not(dialog) or count==0) then -- TODO: pname == yl_speak_up.npc_owner[ n_id ] required -- initialize the NPC with first dialog, name, description and owner: yl_speak_up.initialize_npc_dialog_once(pname, nil, n_id, fields.n_npc, fields.n_description) elseif(fields.add_may_edit and fields.add_may_edit ~= "") then yl_speak_up.save_dialog(n_id, dialog) yl_speak_up.log_change(pname, n_id, "Added to \"may be edited by\": "..tostring(fields.add_may_edit)) elseif(fields.delete_may_edit and fields.delete_may_edit ~= "" and fields.list_may_edit and fields.list_may_edit ~= "") then yl_speak_up.save_dialog(n_id, dialog) yl_speak_up.log_change(pname, n_id, "Removed from \"may be edited by\": "..tostring(fields.list_may_edit)) -- just change name and description elseif((fields.n_npc and fields.n_npc ~= "") or (fields.n_description and fields.n_description ~= "")) then dialog = yl_speak_up.speak_to[pname].dialog if(dialog.n_npc ~= fields.n_npc or dialog.n_description ~= fields.n_description) then dialog.n_npc = fields.n_npc dialog.n_description = fields.n_description yl_speak_up.save_dialog(n_id, dialog) yl_speak_up.log_change(pname, n_id, "Name and/or description changed. ".. "NPC name: \""..tostring(fields.n_npc).. "\" Description: \""..tostring(fields.n_description).. "\" May be edited by: \"".. table.concat(yl_speak_up.sort_keys(dialog.n_may_edit, true), " ").."\".") end end dialog = yl_speak_up.speak_to[pname].dialog -- show nametag etc. if yl_speak_up.speak_to[pname].obj then local obj = yl_speak_up.speak_to[pname].obj local ent = obj:get_luaentity() if ent ~= nil then if(fields.show_nametag) then local new_nametag_state = "- UNDEFINED -" if(fields.show_nametag == "false") then ent.yl_speak_up.hide_nametag = true dialog.hide_nametag = true new_nametag_state = "HIDE" -- update_nametag else will only work on reload obj:set_nametag_attributes({text=""}) elseif(fields.show_nametag == "true") then ent.yl_speak_up.hide_nametag = nil dialog.hide_nametag = nil new_nametag_state = "SHOW" end yl_speak_up.save_dialog(n_id, dialog) yl_speak_up.log_change(pname, n_id, tostring(new_nametag_state).." nametag.") minetest.chat_send_player(pname, tostring(dialog.n_npc)..": I will ".. tostring(new_nametag_state).." my nametag.") end ent.yl_speak_up.npc_name = dialog.n_npc ent.yl_speak_up.npc_description = dialog.n_description ent.owner = yl_speak_up.npc_owner[ n_id ] or dialog.npc_owner local i_text = dialog.n_npc .. "\n" .. dialog.n_description .. "\n" .. yl_speak_up.infotext obj:set_properties({infotext = i_text}) yl_speak_up.update_nametag(ent) end end if(not(fields.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 if((fields.add_may_edit and fields.add_may_edit ~= "") or (fields.delete_may_edit and fields.delete_may_edit ~= "")) then -- show this formspec again yl_speak_up.show_fs(player, "initial_config", {n_id = n_id, d_id = yl_speak_up.speak_to[pname].d_id, false}) else -- actually start a chat with our new npc yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id}) end end -- initialize the npc without having to use a staff; -- returns true when initialization possible -- the entries from add_formspec are added to the output yl_speak_up.get_fs_initial_config = function(player, n_id, d_id, is_initial_config, add_formspec) local pname = player:get_player_name() -- is the player allowed to edit this npc? if(not(yl_speak_up.may_edit_npc(player, n_id))) then return "size[6,2]".. "label[0.2,0.0;Sorry. You are not authorized\nto edit this NPC.]".. "button_exit[2,1.5;1,0.9;back_from_error_msg;Exit]" end local tmp_show_nametag = "true" local tmp_name = n_id 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 -") -- 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_show_nametag = not(dialog.hide_nametag) 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." end local formspec = {"size[11,8.0]", "label[0.2,0.5;", tmp_text, "]", -- name of the npc "checkbox[2.2,0.9;show_nametag;;", tostring(tmp_show_nametag), "]", "label[2.7,0.9;Show nametag]", "label[0.2,1.65;Name:]", "field[2.2,1.2;4,0.9;n_npc;;", minetest.formspec_escape(tmp_name), "]", "label[7.0,1.65;NPC ID: ", minetest.colorize("#FFFF00",tostring(n_id)), "]", "tooltip[n_npc;n_npc: The name of the NPC;#FFFFFF;#000000]", -- description of the npc "label[0.2,2.65;Description:]", "field[2.2,2.2;8,0.9;n_description;;", minetest.formspec_escape(tmp_descr), "]", "tooltip[n_description;n_description: A description for the NPC;#FFFFFF;#000000]", -- the owner of the NPC "label[0.2,3.65;Owner:]", "field[2.2,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]", -- save and exit buttons "button[3.2,7.0;2,0.9;save_initial_config;Save]", "button_exit[5.4,7.0;2,0.9;exit;Exit]" } -- add some entries in edit mode if(add_formspec) then for _, v in ipairs(add_formspec) do table.insert(formspec, v) end elseif(not(is_initial_config)) then -- TODO: add import/export/show texture? end -- show the formspec to the player return table.concat(formspec, "") end yl_speak_up.get_fs_initial_config_wrapper = function(player, param) if(not(param)) then param = {} end return yl_speak_up.get_fs_initial_config(player, param.n_id, param.d_id, param.is_initial_config, nil) end yl_speak_up.register_fs("initial_config", yl_speak_up.input_fs_initial_config, yl_speak_up.get_fs_initial_config_wrapper, -- no special formspec required: nil )