forked from Sokomine/yl_speak_up
		
	
		
			
				
	
	
		
			286 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			286 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- 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) or (fields and 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
 | |
| 			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})) then
 | |
| 		error_msg = "You cannot name your NPC\nafter an existing player."
 | |
| 	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 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",
 | |
| 			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
 | |
| 
 | |
| 	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
 | |
| 		local f = {}
 | |
| 		-- create a new dialog
 | |
| 		f.d_id = yl_speak_up.text_new_dialog_id
 | |
| 		-- ...with this text
 | |
| 		f.d_text = "$GOOD_DAY$ $PLAYER_NAME$,\nI am $NPC_NAME$. I don't know much yet.\n"..
 | |
| 			"Hopefully $OWNER_NAME$ will teach me to talk soon."
 | |
| 		-- it is the first, initial dialog
 | |
| 		f.d_sort = "0"
 | |
| 		f.n_npc = fields.n_npc
 | |
| 		f.n_description = fields.n_description
 | |
| 		f.npc_owner = yl_speak_up.npc_owner[ n_id ]
 | |
| 		-- create and save the first dialog for this npc
 | |
| 		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).."\".")
 | |
| 	-- 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
 | |
| 		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
 | |
| 
 | |
| 	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
 | |
| 			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
 | |
| 	-- actually start a chat with our new npc
 | |
| 	yl_speak_up.show_fs(player, "talk", {n_id = n_id, d_id = d_id})
 | |
| end
 | |
| 
 | |
| 
 | |
| -- initialize the npc without having to use a staff;
 | |
| -- returns true when initialization possible
 | |
| yl_speak_up.get_fs_initial_config = function(player, n_id, d_id, is_initial_config)
 | |
| 	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_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 -")
 | |
| 	local table_of_names = {}
 | |
| 	local may_be_edited_by = ""
 | |
| 	-- 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
 | |
| 		may_be_edited_by =
 | |
| 			-- who can edit this NPC?
 | |
| 			"label[0.2,4.75;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,
 | |
| 				3.0, 4.3, 0.0, "list_may_edit", "player", "Remove player from list",
 | |
| 				"add_may_edit",
 | |
| 					"Enter the name of the player whom you\n"..
 | |
| 					"want to grant the right to 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",
 | |
| 					"If you click here, the player will no\n"..
 | |
| 					"longer be able to edit your NPC."
 | |
| 			)
 | |
| 	end
 | |
| 	local formspec = "size[11,8.0]"..
 | |
| 		"label[0.2,0.5;"..tmp_text.."]"..
 | |
| 		-- name of the npc
 | |
| 		"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]"..
 | |
| 		may_be_edited_by..
 | |
| 		"button[1.0,5.5;4,0.9;edit_skin;Edit Skin]"..
 | |
| 		"button[6.0,5.5;4,0.9;edit_properties;Edit Properties]"..
 | |
| 		-- 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]"
 | |
| 	-- show the formspec to the player
 | |
| 	return formspec
 | |
| end
 |