forked from Sokomine/yl_speak_up
		
	looks like much, but only extracted yl_speak_up.save_element_p_or_a_or_e from yl_speak_up.input_fs_edit_option_related and adjusted identation
This commit is contained in:
		
							parent
							
								
									b03ab2e6b5
								
							
						
					
					
						commit
						c44ee99fbc
					
				@ -193,6 +193,476 @@ yl_speak_up.delete_element_p_or_a_or_e = function(
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- helper function for yl_speak_up.input_fs_edit_option_related
 | 
			
		||||
yl_speak_up.save_element_p_or_a_or_e = function(
 | 
			
		||||
			player, pname, n_id, d_id, o_id, x_id, id_prefix, tmp_data_cache,
 | 
			
		||||
			element_list_name, element_desc, max_entries_allowed,
 | 
			
		||||
			values_what, values_operator, values_block, values_trade, values_inv,
 | 
			
		||||
			formspec_input_to, data, fields)
 | 
			
		||||
 | 
			
		||||
	-- for creating the new prerequirement; normal elements: p_type, p_value, p_id
 | 
			
		||||
	local v = {}
 | 
			
		||||
	-- determine p_type
 | 
			
		||||
	v[ id_prefix.."type" ] = values_what[ data.what ]
 | 
			
		||||
 | 
			
		||||
	local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
	if(not(dialog) or not(dialog.n_dialogs)
 | 
			
		||||
	  or not(dialog.n_dialogs[d_id])
 | 
			
		||||
	  or not(dialog.n_dialogs[d_id].d_options)
 | 
			
		||||
	  or not(dialog.n_dialogs[d_id].d_options[o_id])) then
 | 
			
		||||
		-- this really should not happen during the normal course of operation
 | 
			
		||||
		-- (only if the player sends forged formspec data or a bug occoured)
 | 
			
		||||
		minetest.chat_send_player(pname, "Dialog or option does not exist.")
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local elements = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ]
 | 
			
		||||
	if(not(elements)) then
 | 
			
		||||
		dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] = {}
 | 
			
		||||
		elements = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ]
 | 
			
		||||
		x_id = "new"
 | 
			
		||||
	end
 | 
			
		||||
	-- set x_id appropriately
 | 
			
		||||
	if(not(x_id) or x_id == "new") then
 | 
			
		||||
		x_id = id_prefix..yl_speak_up.find_next_id(elements)
 | 
			
		||||
	end
 | 
			
		||||
	v[ id_prefix.."id" ] = x_id
 | 
			
		||||
 | 
			
		||||
	-- if needed: show a message after successful save so that the player can take
 | 
			
		||||
	-- his items back from the trade_inv slots
 | 
			
		||||
	local show_save_msg = nil
 | 
			
		||||
	local sorted_key_list = yl_speak_up.sort_keys(elements)
 | 
			
		||||
	if( x_id == "new" and #sorted_key_list >= max_entries_allowed) then
 | 
			
		||||
		-- this really should not happen during the normal course of operation
 | 
			
		||||
		-- (only if the player sends forged formspec data or a bug occoured)
 | 
			
		||||
		minetest.chat_send_player(pname, "Maximum number of allowed entries exceeded.")
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	-- "an internal state (i.e. of a quest)", -- 2
 | 
			
		||||
	if(data.what == 2 and id_prefix ~= "a_") then
 | 
			
		||||
		v[ id_prefix.."value" ] = "expression"
 | 
			
		||||
		v[ id_prefix.."operator" ] = values_operator[ data.operator ]
 | 
			
		||||
		v[ id_prefix.."var_cmp_value" ] = (data.var_cmp_value or "")
 | 
			
		||||
		v[ id_prefix.."variable" ] = data.variable_name
 | 
			
		||||
 | 
			
		||||
	-- "a block somewhere", -- 3
 | 
			
		||||
	elseif(data.what == 3 and id_prefix ~= "a_") then
 | 
			
		||||
		v[ id_prefix.."value" ] = values_block[ data.block ]
 | 
			
		||||
		if(not(data.block_pos) or not(data.node_data) or not(data.node_data.name)) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[8,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Please select a block first!]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- for "node_is_air", there is no need to store node name and parameter
 | 
			
		||||
		if(v[ id_prefix.."value" ]
 | 
			
		||||
		  and (v[ id_prefix.."value" ] == "node_is_like"
 | 
			
		||||
		    or v[ id_prefix.."value" ] == "node_is_diffrent_from")
 | 
			
		||||
		    or v[ id_prefix.."value" ] == "place"
 | 
			
		||||
		    or v[ id_prefix.."value" ] == "dig"
 | 
			
		||||
		    or v[ id_prefix.."value" ] == "punch"
 | 
			
		||||
		    or v[ id_prefix.."value" ] == "right-click") then
 | 
			
		||||
			v[ id_prefix.."node" ]   = data.node_data.name
 | 
			
		||||
			v[ id_prefix.."param2" ] = data.node_data.param2
 | 
			
		||||
		end
 | 
			
		||||
		-- preconditions can be applied to all blocks; effects may be more limited
 | 
			
		||||
		if(id_prefix == "r_"
 | 
			
		||||
		  and yl_speak_up.check_blacklisted(v[id_prefix.."value"],
 | 
			
		||||
				-- we don't know yet which node will be there later on
 | 
			
		||||
				data.node_data.name, data.node_data.name)) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[8,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Blocks of type \""..
 | 
			
		||||
					tostring(data.node_data.name).."\" do not allow\n"..
 | 
			
		||||
					"interaction of type \""..tostring(v[id_prefix.."value"])..
 | 
			
		||||
					"\" for NPC.]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- we also need to store the position of the node
 | 
			
		||||
		v[ id_prefix.."pos" ] = {x = data.block_pos.x, y = data.block_pos.y, z = data.block_pos.z }
 | 
			
		||||
		-- "I can't punch it. The block is as the block *above* the one I punched.",
 | 
			
		||||
		if(id_prefix == "p_" and data.block == 5) then
 | 
			
		||||
			v.p_pos.y = v.p_pos.y + 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
	-- "a trade", -- 4
 | 
			
		||||
	-- (only for preconditions; not for effects)
 | 
			
		||||
	elseif(data.what == 4 and id_prefix == "p_") then
 | 
			
		||||
		-- this depends on the trade associated with that option; therefore,
 | 
			
		||||
		-- it does not need any more parameters (they come dynamicly from the
 | 
			
		||||
		-- trade)
 | 
			
		||||
		v.p_value = values_trade[ data.trade ]
 | 
			
		||||
 | 
			
		||||
	-- "the inventory of the player", -- 5
 | 
			
		||||
	-- "the inventory of the NPC", -- 6
 | 
			
		||||
	-- (only for preconditions; not for effects)
 | 
			
		||||
	elseif((data.what == 5 or data.what == 6) and id_prefix == "p_") then
 | 
			
		||||
		v.p_value = values_inv[ data.inv ]
 | 
			
		||||
		if(v.p_value and v.p_value ~= "inv_is_empty") then
 | 
			
		||||
			-- we have checked this value earlier on
 | 
			
		||||
			v[ "p_itemstack" ] = data.inv_stack_name
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
	-- "give item (created out of thin air) to player (requires npc_master priv)", -- 7
 | 
			
		||||
	-- "take item from player and destroy it (requires npc_master priv)", -- 8
 | 
			
		||||
	elseif(data.what and id_prefix == "r_" and (data.what == 7 or data.what == 8)) then
 | 
			
		||||
		if(not(data.inv_stack_name) or data.inv_stack_name == "") then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[8,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Please provide the name of the "..
 | 
			
		||||
						"\nitem you want to give or take!]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if(not(minetest.check_player_privs(player, {npc_master=true}))) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: You need the \"npc_master\" priv "..
 | 
			
		||||
						" in order to set this effect.]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		v[ "r_value" ] = data.inv_stack_name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	-- "move the player to a given position (requires npc_master priv)", -- 9
 | 
			
		||||
	elseif(data.what and id_prefix == "r_" and data.what == 9) then
 | 
			
		||||
		if(not(data.move_to_x) or not(data.move_to_y) or not(data.move_to_z)) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Please provide valid coordinates "..
 | 
			
		||||
						" x, y and z!]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if(not(minetest.check_player_privs(player, {npc_master=true}))) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: You need the \"npc_master\" priv "..
 | 
			
		||||
						" in order to set this effect.]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		v[ "r_value" ] = minetest.pos_to_string(
 | 
			
		||||
			{x = data.move_to_x, y = data.move_to_y, z = data.move_to_z})
 | 
			
		||||
 | 
			
		||||
	-- effect "execute Lua code (requires npc_master priv)", -- precondition: 7; effect: 10
 | 
			
		||||
	elseif((data.what and id_prefix == "p_" and data.what ==  7)
 | 
			
		||||
	    or (data.what and id_prefix == "r_" and data.what == 10)) then
 | 
			
		||||
		if(not(data.lua_code) or data.lua_code == "") then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Please enter the Lua code you want "..
 | 
			
		||||
						"to execute!]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if(not(minetest.check_player_privs(player, {npc_master=true}))) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: You need the \"npc_master\" priv "..
 | 
			
		||||
						" in order to set this.]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		v[ id_prefix.."value" ] = data.lua_code
 | 
			
		||||
 | 
			
		||||
	-- "NPC crafts something", -- 4
 | 
			
		||||
	-- (only for effects; not for preconditions)
 | 
			
		||||
	elseif(data.what and id_prefix == "r_" and data.what == 4) then
 | 
			
		||||
		local player_inv = player:get_inventory()
 | 
			
		||||
		if(player_inv:get_stack("craftpreview", 1):is_empty()) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[8,2]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Please prepare your craft grid first!"..
 | 
			
		||||
						"\nYour NPC needs to know what to craft.]"..
 | 
			
		||||
					"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- store the craft result (Note: the craft result may change in the future
 | 
			
		||||
		-- if the server changes its craft result, making this craft invalid)
 | 
			
		||||
		v[ "r_value" ] = player_inv:get_stack("craftpreview", 1):to_string()
 | 
			
		||||
		v[ "r_craft_grid"] = {}
 | 
			
		||||
		for i = 1, 9 do
 | 
			
		||||
			-- store all the indigrents of the craft grid
 | 
			
		||||
			table.insert( v[ "r_craft_grid" ],
 | 
			
		||||
				player_inv:get_stack("craft", i):to_string())
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
	-- "go to other dialog if the *previous* effect failed", -- 5
 | 
			
		||||
	-- (only for effects; not for preconditions)
 | 
			
		||||
	elseif(data.what and id_prefix == "r_" and data.what == 5) then
 | 
			
		||||
		v[ "r_value" ] = data.on_failure
 | 
			
		||||
 | 
			
		||||
	-- "send a chat message to all players", -- 6
 | 
			
		||||
	-- (only for effects; not for preconditions)
 | 
			
		||||
	elseif(data.what and id_prefix == "r_" and data.what == 6) then
 | 
			
		||||
		data.chat_msg_text = fields.chat_msg_text
 | 
			
		||||
		-- allow saving only if the placeholders are all present
 | 
			
		||||
		-- (reason for requiring them: players and server owners ought to
 | 
			
		||||
		-- be able to see who is responsible for a message)
 | 
			
		||||
		if(not(string.find(data.chat_msg_text, "%$NPC_NAME%$"))
 | 
			
		||||
		  or not(string.find(data.chat_msg_text, "%$PLAYER_NAME%$"))
 | 
			
		||||
		  or not(string.find(data.chat_msg_text, "%$OWNER_NAME%$"))) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Your chat message needs to contain "..
 | 
			
		||||
						"the following\nplaceholders: $NPC_NAME$, "..
 | 
			
		||||
						"$PLAYER_NAME$ and $OWNER_NAME$.\nThat way, other "..
 | 
			
		||||
						"players will know who sent the message.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		v[ "r_value" ] = data.chat_msg_text
 | 
			
		||||
 | 
			
		||||
	-- "Normal trade - one item(stack) for another item(stack).", -- 3
 | 
			
		||||
	-- (only for actions)
 | 
			
		||||
	elseif(data.what and id_prefix == "a_" and data.what == 3) then
 | 
			
		||||
		-- remember which option was selected
 | 
			
		||||
		yl_speak_up.speak_to[pname].o_id = o_id
 | 
			
		||||
		-- do not switch target dialog (we are in edit mode)
 | 
			
		||||
		yl_speak_up.speak_to[pname].target_d_id = nil
 | 
			
		||||
		-- just to make sure that the trade_id is properly set...
 | 
			
		||||
		if(not(data.trade_id)) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Missing trade ID.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- the button is called store_trade_simple instead of save_element in
 | 
			
		||||
		-- the trade simple function(s); we want to store a trade
 | 
			
		||||
		fields.store_trade_simple = true
 | 
			
		||||
		local res = yl_speak_up.input_add_trade_simple(player, "", fields)
 | 
			
		||||
		-- the above function sets:
 | 
			
		||||
		--    dialog.trades[ trade_id ] = {pay={ps},buy={bs}, d_id = d_id, o_id = o_id}
 | 
			
		||||
		-- store the trade as an action:
 | 
			
		||||
		local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
		if(res and dialog.trades and dialog.trades[ data.trade_id ]) then
 | 
			
		||||
			v[ "a_value" ] = data.trade_id
 | 
			
		||||
			v[ "a_pay"   ] = dialog.trades[ data.trade_id ].pay
 | 
			
		||||
			v[ "a_buy"   ] = dialog.trades[ data.trade_id ].buy
 | 
			
		||||
			v[ "a_on_failure" ] = ""
 | 
			
		||||
			if(data.action_failure_dialog) then
 | 
			
		||||
				local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
				local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
				v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
	-- "The NPC gives something to the player (i.e. a quest item).", -- 4
 | 
			
		||||
	-- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5
 | 
			
		||||
	-- (only for actions)
 | 
			
		||||
	elseif(data.what and id_prefix == "a_" and (data.what == 4 or data.what == 5)) then
 | 
			
		||||
		local trade_inv_list = "npc_gives"
 | 
			
		||||
		if(data.what == 5) then
 | 
			
		||||
			trade_inv_list = "npc_wants"
 | 
			
		||||
		end
 | 
			
		||||
		local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname})
 | 
			
		||||
		if(not(trade_inv) or trade_inv:is_empty( trade_inv_list )) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;Please insert an item first! Your NPC "..
 | 
			
		||||
						"needs\nto know what it shall give to the player.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		v[ "a_on_failure" ] = ""
 | 
			
		||||
		if(data.action_failure_dialog) then
 | 
			
		||||
			local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
			local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
			v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
		end
 | 
			
		||||
		-- change the node in the slot
 | 
			
		||||
		local stack = trade_inv:get_stack( trade_inv_list, 1)
 | 
			
		||||
		if(not(stack) or not(minetest.registered_items[ stack:get_name() ])) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;This item is unkown. Please use only known"..
 | 
			
		||||
						"items.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- is this particular item blacklisted on this server?
 | 
			
		||||
		if(yl_speak_up.blacklist_action_quest_item[ stack:get_name() ]) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;Sorry. This item is blacklisted on this "..
 | 
			
		||||
						"server.\nYou can't use it as a quest item.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local meta = stack:get_meta()
 | 
			
		||||
		-- what does the NPC want to give?
 | 
			
		||||
		v[ "a_value" ] = stack:get_name().." "..stack:get_count()
 | 
			
		||||
		-- for displaying as a background image
 | 
			
		||||
		data.item_string = v[ "a_value" ]
 | 
			
		||||
		if(data.what == 5) then
 | 
			
		||||
			-- try to reconstruct $PLAYER_NAME$ (may not always work)
 | 
			
		||||
			local item_was_for = meta:get_string("yl_speak_up:quest_item_for")
 | 
			
		||||
			local new_desc = meta:get_string("description")
 | 
			
		||||
			if(item_was_for and item_was_for ~= "") then
 | 
			
		||||
				new_desc = string.gsub(new_desc, item_was_for, "$PLAYER_NAME$")
 | 
			
		||||
			end
 | 
			
		||||
			data.item_desc = new_desc
 | 
			
		||||
		end
 | 
			
		||||
		-- set new description if there is one set (optional)
 | 
			
		||||
		if(data.item_desc
 | 
			
		||||
		  and data.item_desc ~= ""
 | 
			
		||||
		  and data.item_desc ~= "- none set -") then
 | 
			
		||||
			if(data.what == 4) then
 | 
			
		||||
				meta:set_string("description", data.item_desc)
 | 
			
		||||
			end
 | 
			
		||||
			v[ "a_item_desc" ] = data.item_desc
 | 
			
		||||
		end
 | 
			
		||||
		if(data.what == 5) then
 | 
			
		||||
			data.item_quest_id = meta:get_string("yl_speak_up:quest_id")
 | 
			
		||||
		end
 | 
			
		||||
		-- set special ID (optional)
 | 
			
		||||
		if(data.item_quest_id
 | 
			
		||||
		  and data.item_quest_id ~= ""
 | 
			
		||||
		  and data.item_quest_id ~= "- no item set -") then
 | 
			
		||||
			if(data.what == 4) then
 | 
			
		||||
				-- which player got this quest item?
 | 
			
		||||
				meta:set_string("yl_speak_up:quest_item_for", pname)
 | 
			
		||||
				-- include the NPC id so that we know which NPC gave it
 | 
			
		||||
				meta:set_string("yl_speak_up:quest_item_from", tostring(n_id))
 | 
			
		||||
				-- extend quest_id by NPC id so that it becomes more uniq
 | 
			
		||||
				meta:set_string("yl_speak_up:quest_id",
 | 
			
		||||
					tostring(n_id).." "..tostring(data.item_quest_id))
 | 
			
		||||
			end
 | 
			
		||||
			v[ "a_item_quest_id" ] = data.item_quest_id
 | 
			
		||||
		end
 | 
			
		||||
		if( v["a_item_quest_id"] and not(v[ "a_item_desc"]) and data.what == 4) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;You can't set a special quest ID without "..
 | 
			
		||||
					"also changing\nthe description. The player would be "..
 | 
			
		||||
					"unable to tell\nthe quest item and normal items "..
 | 
			
		||||
					"apartapart.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local player_inv = player:get_inventory()
 | 
			
		||||
		if(not(player_inv:room_for_item("main", stack))) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;You have no room in your inventory for "..
 | 
			
		||||
					"the example\nitem. Please make room so that it can be"..
 | 
			
		||||
					"given back to you!]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		player_inv:add_item("main", stack)
 | 
			
		||||
		trade_inv:remove_item(trade_inv_list, stack)
 | 
			
		||||
		-- just send a message that the save was successful and give the player time to
 | 
			
		||||
		-- take his items back
 | 
			
		||||
		show_save_msg = "size[9,2.5]"..
 | 
			
		||||
			"label[0.2,0.5;The information was saved successfully.\n"..
 | 
			
		||||
				"The item has been returned to your inventory.]"..
 | 
			
		||||
			"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"
 | 
			
		||||
		return
 | 
			
		||||
 | 
			
		||||
	-- "The player has to manually enter a password or passphrase or some other text.", -- 6
 | 
			
		||||
	elseif(data.what and id_prefix == "a_" and data.what == 6) then
 | 
			
		||||
		if(not(data.quest_question)) then
 | 
			
		||||
			data.quest_question = "Your answer:"
 | 
			
		||||
		end
 | 
			
		||||
		v[ "a_question" ] = data.quest_question
 | 
			
		||||
		-- the player setting this up needs to provide the correct answer
 | 
			
		||||
		if(not(data.quest_answer)) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Please provide the correct answer!\n"..
 | 
			
		||||
					"The answer the player gives is checked against this.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		v[ "a_value" ] = data.quest_answer
 | 
			
		||||
		if(not(data.action_failure_dialog)) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = "size[9,2.5]"..
 | 
			
		||||
					"label[0.2,0.5;Error: Please provide a target dialog if "..
 | 
			
		||||
					"the player gives the wrong answer.]"..
 | 
			
		||||
					"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
		local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
		v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
 | 
			
		||||
	-- "Call custom functions that are supposed to be overridden by the server.", --
 | 
			
		||||
	-- precondition: 8; action: 7; effect: 11
 | 
			
		||||
	elseif(data.what
 | 
			
		||||
	  and ((id_prefix == "a_" and data.what == 7)
 | 
			
		||||
	    or (id_prefix == "p_" and data.what == 8)
 | 
			
		||||
	    or (id_prefix == "r_" and data.what == 11))) then
 | 
			
		||||
		v[ id_prefix.."value" ] = data.custom_param
 | 
			
		||||
		if(id_prefix == "a_") then
 | 
			
		||||
			local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
			v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	v[ "alternate_text" ] = data.alternate_text
 | 
			
		||||
 | 
			
		||||
	-- only save if something was actually selected
 | 
			
		||||
	if(v[ id_prefix.."value"]) then
 | 
			
		||||
		if(not(dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ])) then
 | 
			
		||||
			dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] = {}
 | 
			
		||||
		end
 | 
			
		||||
		-- store the change in the dialog
 | 
			
		||||
		dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ][ x_id ] = v
 | 
			
		||||
		-- clear up data
 | 
			
		||||
		yl_speak_up.speak_to[pname][ id_prefix.."id" ] = nil
 | 
			
		||||
		yl_speak_up.speak_to[pname][ tmp_data_cache ] = nil
 | 
			
		||||
		-- record this as a change, but do not save do disk yet
 | 
			
		||||
			table.insert(yl_speak_up.npc_was_changed[ n_id ],
 | 
			
		||||
			"Dialog "..tostring(d_id)..": "..element_desc.." "..tostring(x_id)..
 | 
			
		||||
			" added/changed for option "..tostring(o_id)..".")
 | 
			
		||||
		if(show_save_msg) then
 | 
			
		||||
			yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
				input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
				formspec = show_save_msg})
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- TODO: when trying to save: save to disk as well?
 | 
			
		||||
		-- show the new/changed precondition
 | 
			
		||||
		yl_speak_up.show_fs(player, formspec_input_to, x_id)
 | 
			
		||||
		return
 | 
			
		||||
	else
 | 
			
		||||
		-- make sure the player is informed that saving failed
 | 
			
		||||
		yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
			input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
			formspec = "size[8,2]"..
 | 
			
		||||
				"label[0.2,0.5;Error: There is no \""..tostring(id_prefix)..
 | 
			
		||||
					"value\" set.\n"..
 | 
			
		||||
					"\nCould not save.]"..
 | 
			
		||||
				"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- These two functions
 | 
			
		||||
--   * yl_speak_up.input_fs_edit_option_related and
 | 
			
		||||
--   * yl_speak_up.get_fs_edit_option_related
 | 
			
		||||
@ -383,458 +853,15 @@ yl_speak_up.input_fs_edit_option_related = function(player, formname, fields,
 | 
			
		||||
 | 
			
		||||
	-- the save button was pressed
 | 
			
		||||
	if(fields.save_element and data and data.what and values_what[ data.what ]) then
 | 
			
		||||
		-- for creating the new prerequirement; normal elements: p_type, p_value, p_id
 | 
			
		||||
		local v = {}
 | 
			
		||||
		-- determine p_type
 | 
			
		||||
		v[ id_prefix.."type" ] = values_what[ data.what ]
 | 
			
		||||
 | 
			
		||||
		local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
		if(not(dialog) or not(dialog.n_dialogs)
 | 
			
		||||
		  or not(dialog.n_dialogs[d_id])
 | 
			
		||||
		  or not(dialog.n_dialogs[d_id].d_options)
 | 
			
		||||
		  or not(dialog.n_dialogs[d_id].d_options[o_id])) then
 | 
			
		||||
			-- this really should not happen during the normal course of operation
 | 
			
		||||
			-- (only if the player sends forged formspec data or a bug occoured)
 | 
			
		||||
			minetest.chat_send_player(pname, "Dialog or option does not exist.")
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local elements = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ]
 | 
			
		||||
		if(not(elements)) then
 | 
			
		||||
			dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] = {}
 | 
			
		||||
			elements = dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ]
 | 
			
		||||
			x_id = "new"
 | 
			
		||||
		end
 | 
			
		||||
		-- set x_id appropriately
 | 
			
		||||
		if(not(x_id) or x_id == "new") then
 | 
			
		||||
			x_id = id_prefix..yl_speak_up.find_next_id(elements)
 | 
			
		||||
		end
 | 
			
		||||
		v[ id_prefix.."id" ] = x_id
 | 
			
		||||
 | 
			
		||||
		-- if needed: show a message after successful save so that the player can take
 | 
			
		||||
		-- his items back from the trade_inv slots
 | 
			
		||||
		local show_save_msg = nil
 | 
			
		||||
		local sorted_key_list = yl_speak_up.sort_keys(elements)
 | 
			
		||||
		if( x_id == "new" and #sorted_key_list >= max_entries_allowed) then
 | 
			
		||||
			-- this really should not happen during the normal course of operation
 | 
			
		||||
			-- (only if the player sends forged formspec data or a bug occoured)
 | 
			
		||||
			minetest.chat_send_player(pname, "Maximum number of allowed entries exceeded.")
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- "an internal state (i.e. of a quest)", -- 2
 | 
			
		||||
		if(data.what == 2 and id_prefix ~= "a_") then
 | 
			
		||||
			v[ id_prefix.."value" ] = "expression"
 | 
			
		||||
			v[ id_prefix.."operator" ] = values_operator[ data.operator ]
 | 
			
		||||
			v[ id_prefix.."var_cmp_value" ] = (data.var_cmp_value or "")
 | 
			
		||||
			v[ id_prefix.."variable" ] = data.variable_name
 | 
			
		||||
 | 
			
		||||
		-- "a block somewhere", -- 3
 | 
			
		||||
		elseif(data.what == 3 and id_prefix ~= "a_") then
 | 
			
		||||
			v[ id_prefix.."value" ] = values_block[ data.block ]
 | 
			
		||||
			if(not(data.block_pos) or not(data.node_data) or not(data.node_data.name)) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[8,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Please select a block first!]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			-- for "node_is_air", there is no need to store node name and parameter
 | 
			
		||||
			if(v[ id_prefix.."value" ]
 | 
			
		||||
			  and (v[ id_prefix.."value" ] == "node_is_like"
 | 
			
		||||
			    or v[ id_prefix.."value" ] == "node_is_diffrent_from")
 | 
			
		||||
			    or v[ id_prefix.."value" ] == "place"
 | 
			
		||||
			    or v[ id_prefix.."value" ] == "dig"
 | 
			
		||||
			    or v[ id_prefix.."value" ] == "punch"
 | 
			
		||||
			    or v[ id_prefix.."value" ] == "right-click") then
 | 
			
		||||
				v[ id_prefix.."node" ]   = data.node_data.name
 | 
			
		||||
				v[ id_prefix.."param2" ] = data.node_data.param2
 | 
			
		||||
			end
 | 
			
		||||
			-- preconditions can be applied to all blocks; effects may be more limited
 | 
			
		||||
			if(id_prefix == "r_"
 | 
			
		||||
			  and yl_speak_up.check_blacklisted(v[id_prefix.."value"],
 | 
			
		||||
					-- we don't know yet which node will be there later on
 | 
			
		||||
					data.node_data.name, data.node_data.name)) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[8,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Blocks of type \""..
 | 
			
		||||
						tostring(data.node_data.name).."\" do not allow\n"..
 | 
			
		||||
						"interaction of type \""..tostring(v[id_prefix.."value"])..
 | 
			
		||||
						"\" for NPC.]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			-- we also need to store the position of the node
 | 
			
		||||
			v[ id_prefix.."pos" ] = {x = data.block_pos.x, y = data.block_pos.y, z = data.block_pos.z }
 | 
			
		||||
			-- "I can't punch it. The block is as the block *above* the one I punched.",
 | 
			
		||||
			if(id_prefix == "p_" and data.block == 5) then
 | 
			
		||||
				v.p_pos.y = v.p_pos.y + 1
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
		-- "a trade", -- 4
 | 
			
		||||
		-- (only for preconditions; not for effects)
 | 
			
		||||
		elseif(data.what == 4 and id_prefix == "p_") then
 | 
			
		||||
			-- this depends on the trade associated with that option; therefore,
 | 
			
		||||
			-- it does not need any more parameters (they come dynamicly from the
 | 
			
		||||
			-- trade)
 | 
			
		||||
			v.p_value = values_trade[ data.trade ]
 | 
			
		||||
 | 
			
		||||
		-- "the inventory of the player", -- 5
 | 
			
		||||
		-- "the inventory of the NPC", -- 6
 | 
			
		||||
		-- (only for preconditions; not for effects)
 | 
			
		||||
		elseif((data.what == 5 or data.what == 6) and id_prefix == "p_") then
 | 
			
		||||
			v.p_value = values_inv[ data.inv ]
 | 
			
		||||
			if(v.p_value and v.p_value ~= "inv_is_empty") then
 | 
			
		||||
				-- we have checked this value earlier on
 | 
			
		||||
				v[ "p_itemstack" ] = data.inv_stack_name
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
		-- "give item (created out of thin air) to player (requires npc_master priv)", -- 7
 | 
			
		||||
		-- "take item from player and destroy it (requires npc_master priv)", -- 8
 | 
			
		||||
		elseif(data.what and id_prefix == "r_" and (data.what == 7 or data.what == 8)) then
 | 
			
		||||
			if(not(data.inv_stack_name) or data.inv_stack_name == "") then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[8,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Please provide the name of the "..
 | 
			
		||||
							"\nitem you want to give or take!]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			if(not(minetest.check_player_privs(player, {npc_master=true}))) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: You need the \"npc_master\" priv "..
 | 
			
		||||
							" in order to set this effect.]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			v[ "r_value" ] = data.inv_stack_name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		-- "move the player to a given position (requires npc_master priv)", -- 9
 | 
			
		||||
		elseif(data.what and id_prefix == "r_" and data.what == 9) then
 | 
			
		||||
			if(not(data.move_to_x) or not(data.move_to_y) or not(data.move_to_z)) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Please provide valid coordinates "..
 | 
			
		||||
							" x, y and z!]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			if(not(minetest.check_player_privs(player, {npc_master=true}))) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: You need the \"npc_master\" priv "..
 | 
			
		||||
							" in order to set this effect.]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			v[ "r_value" ] = minetest.pos_to_string(
 | 
			
		||||
				{x = data.move_to_x, y = data.move_to_y, z = data.move_to_z})
 | 
			
		||||
 | 
			
		||||
		-- effect "execute Lua code (requires npc_master priv)", -- precondition: 7; effect: 10
 | 
			
		||||
		elseif((data.what and id_prefix == "p_" and data.what ==  7)
 | 
			
		||||
		    or (data.what and id_prefix == "r_" and data.what == 10)) then
 | 
			
		||||
			if(not(data.lua_code) or data.lua_code == "") then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Please enter the Lua code you want "..
 | 
			
		||||
							"to execute!]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			if(not(minetest.check_player_privs(player, {npc_master=true}))) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: You need the \"npc_master\" priv "..
 | 
			
		||||
							" in order to set this.]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			v[ id_prefix.."value" ] = data.lua_code
 | 
			
		||||
 | 
			
		||||
		-- "NPC crafts something", -- 4
 | 
			
		||||
		-- (only for effects; not for preconditions)
 | 
			
		||||
		elseif(data.what and id_prefix == "r_" and data.what == 4) then
 | 
			
		||||
			local player_inv = player:get_inventory()
 | 
			
		||||
			if(player_inv:get_stack("craftpreview", 1):is_empty()) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[8,2]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Please prepare your craft grid first!"..
 | 
			
		||||
							"\nYour NPC needs to know what to craft.]"..
 | 
			
		||||
						"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			-- store the craft result (Note: the craft result may change in the future
 | 
			
		||||
			-- if the server changes its craft result, making this craft invalid)
 | 
			
		||||
			v[ "r_value" ] = player_inv:get_stack("craftpreview", 1):to_string()
 | 
			
		||||
			v[ "r_craft_grid"] = {}
 | 
			
		||||
			for i = 1, 9 do
 | 
			
		||||
				-- store all the indigrents of the craft grid
 | 
			
		||||
				table.insert( v[ "r_craft_grid" ],
 | 
			
		||||
					player_inv:get_stack("craft", i):to_string())
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
		-- "go to other dialog if the *previous* effect failed", -- 5
 | 
			
		||||
		-- (only for effects; not for preconditions)
 | 
			
		||||
		elseif(data.what and id_prefix == "r_" and data.what == 5) then
 | 
			
		||||
			v[ "r_value" ] = data.on_failure
 | 
			
		||||
 | 
			
		||||
		-- "send a chat message to all players", -- 6
 | 
			
		||||
		-- (only for effects; not for preconditions)
 | 
			
		||||
		elseif(data.what and id_prefix == "r_" and data.what == 6) then
 | 
			
		||||
			data.chat_msg_text = fields.chat_msg_text
 | 
			
		||||
			-- allow saving only if the placeholders are all present
 | 
			
		||||
			-- (reason for requiring them: players and server owners ought to
 | 
			
		||||
			-- be able to see who is responsible for a message)
 | 
			
		||||
			if(not(string.find(data.chat_msg_text, "%$NPC_NAME%$"))
 | 
			
		||||
			  or not(string.find(data.chat_msg_text, "%$PLAYER_NAME%$"))
 | 
			
		||||
			  or not(string.find(data.chat_msg_text, "%$OWNER_NAME%$"))) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Your chat message needs to contain "..
 | 
			
		||||
							"the following\nplaceholders: $NPC_NAME$, "..
 | 
			
		||||
							"$PLAYER_NAME$ and $OWNER_NAME$.\nThat way, other "..
 | 
			
		||||
							"players will know who sent the message.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			v[ "r_value" ] = data.chat_msg_text
 | 
			
		||||
 | 
			
		||||
		-- "Normal trade - one item(stack) for another item(stack).", -- 3
 | 
			
		||||
		-- (only for actions)
 | 
			
		||||
		elseif(data.what and id_prefix == "a_" and data.what == 3) then
 | 
			
		||||
			-- remember which option was selected
 | 
			
		||||
			yl_speak_up.speak_to[pname].o_id = o_id
 | 
			
		||||
			-- do not switch target dialog (we are in edit mode)
 | 
			
		||||
			yl_speak_up.speak_to[pname].target_d_id = nil
 | 
			
		||||
			-- just to make sure that the trade_id is properly set...
 | 
			
		||||
			if(not(data.trade_id)) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Missing trade ID.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			-- the button is called store_trade_simple instead of save_element in
 | 
			
		||||
			-- the trade simple function(s); we want to store a trade
 | 
			
		||||
			fields.store_trade_simple = true
 | 
			
		||||
			local res = yl_speak_up.input_add_trade_simple(player, "", fields)
 | 
			
		||||
			-- the above function sets:
 | 
			
		||||
			--    dialog.trades[ trade_id ] = {pay={ps},buy={bs}, d_id = d_id, o_id = o_id}
 | 
			
		||||
			-- store the trade as an action:
 | 
			
		||||
			local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
			if(res and dialog.trades and dialog.trades[ data.trade_id ]) then
 | 
			
		||||
				v[ "a_value" ] = data.trade_id
 | 
			
		||||
				v[ "a_pay"   ] = dialog.trades[ data.trade_id ].pay
 | 
			
		||||
				v[ "a_buy"   ] = dialog.trades[ data.trade_id ].buy
 | 
			
		||||
				v[ "a_on_failure" ] = ""
 | 
			
		||||
				if(data.action_failure_dialog) then
 | 
			
		||||
					local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
					local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
					v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
		-- "The NPC gives something to the player (i.e. a quest item).", -- 4
 | 
			
		||||
		-- "The player is expected to give something to the NPC (i.e. a quest item).", -- 5
 | 
			
		||||
		-- (only for actions)
 | 
			
		||||
		elseif(data.what and id_prefix == "a_" and (data.what == 4 or data.what == 5)) then
 | 
			
		||||
			local trade_inv_list = "npc_gives"
 | 
			
		||||
			if(data.what == 5) then
 | 
			
		||||
				trade_inv_list = "npc_wants"
 | 
			
		||||
			end
 | 
			
		||||
			local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname})
 | 
			
		||||
			if(not(trade_inv) or trade_inv:is_empty( trade_inv_list )) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;Please insert an item first! Your NPC "..
 | 
			
		||||
							"needs\nto know what it shall give to the player.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			v[ "a_on_failure" ] = ""
 | 
			
		||||
			if(data.action_failure_dialog) then
 | 
			
		||||
				local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
				local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
				v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
			end
 | 
			
		||||
			-- change the node in the slot
 | 
			
		||||
			local stack = trade_inv:get_stack( trade_inv_list, 1)
 | 
			
		||||
			if(not(stack) or not(minetest.registered_items[ stack:get_name() ])) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;This item is unkown. Please use only known"..
 | 
			
		||||
							"items.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			-- is this particular item blacklisted on this server?
 | 
			
		||||
			if(yl_speak_up.blacklist_action_quest_item[ stack:get_name() ]) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;Sorry. This item is blacklisted on this "..
 | 
			
		||||
							"server.\nYou can't use it as a quest item.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			local meta = stack:get_meta()
 | 
			
		||||
			-- what does the NPC want to give?
 | 
			
		||||
			v[ "a_value" ] = stack:get_name().." "..stack:get_count()
 | 
			
		||||
			-- for displaying as a background image
 | 
			
		||||
			data.item_string = v[ "a_value" ]
 | 
			
		||||
			if(data.what == 5) then
 | 
			
		||||
				-- try to reconstruct $PLAYER_NAME$ (may not always work)
 | 
			
		||||
				local item_was_for = meta:get_string("yl_speak_up:quest_item_for")
 | 
			
		||||
				local new_desc = meta:get_string("description")
 | 
			
		||||
				if(item_was_for and item_was_for ~= "") then
 | 
			
		||||
					new_desc = string.gsub(new_desc, item_was_for, "$PLAYER_NAME$")
 | 
			
		||||
				end
 | 
			
		||||
				data.item_desc = new_desc
 | 
			
		||||
			end
 | 
			
		||||
			-- set new description if there is one set (optional)
 | 
			
		||||
			if(data.item_desc
 | 
			
		||||
			  and data.item_desc ~= ""
 | 
			
		||||
			  and data.item_desc ~= "- none set -") then
 | 
			
		||||
				if(data.what == 4) then
 | 
			
		||||
					meta:set_string("description", data.item_desc)
 | 
			
		||||
				end
 | 
			
		||||
				v[ "a_item_desc" ] = data.item_desc
 | 
			
		||||
			end
 | 
			
		||||
			if(data.what == 5) then
 | 
			
		||||
				data.item_quest_id = meta:get_string("yl_speak_up:quest_id")
 | 
			
		||||
			end
 | 
			
		||||
			-- set special ID (optional)
 | 
			
		||||
			if(data.item_quest_id
 | 
			
		||||
			  and data.item_quest_id ~= ""
 | 
			
		||||
			  and data.item_quest_id ~= "- no item set -") then
 | 
			
		||||
				if(data.what == 4) then
 | 
			
		||||
					-- which player got this quest item?
 | 
			
		||||
					meta:set_string("yl_speak_up:quest_item_for", pname)
 | 
			
		||||
					-- include the NPC id so that we know which NPC gave it
 | 
			
		||||
					meta:set_string("yl_speak_up:quest_item_from", tostring(n_id))
 | 
			
		||||
					-- extend quest_id by NPC id so that it becomes more uniq
 | 
			
		||||
					meta:set_string("yl_speak_up:quest_id",
 | 
			
		||||
						tostring(n_id).." "..tostring(data.item_quest_id))
 | 
			
		||||
				end
 | 
			
		||||
				v[ "a_item_quest_id" ] = data.item_quest_id
 | 
			
		||||
			end
 | 
			
		||||
			if( v["a_item_quest_id"] and not(v[ "a_item_desc"]) and data.what == 4) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;You can't set a special quest ID without "..
 | 
			
		||||
						"also changing\nthe description. The player would be "..
 | 
			
		||||
						"unable to tell\nthe quest item and normal items "..
 | 
			
		||||
						"apartapart.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			local player_inv = player:get_inventory()
 | 
			
		||||
			if(not(player_inv:room_for_item("main", stack))) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;You have no room in your inventory for "..
 | 
			
		||||
						"the example\nitem. Please make room so that it can be"..
 | 
			
		||||
						"given back to you!]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			player_inv:add_item("main", stack)
 | 
			
		||||
			trade_inv:remove_item(trade_inv_list, stack)
 | 
			
		||||
			-- just send a message that the save was successful and give the player time to
 | 
			
		||||
			-- take his items back
 | 
			
		||||
			show_save_msg = "size[9,2.5]"..
 | 
			
		||||
				"label[0.2,0.5;The information was saved successfully.\n"..
 | 
			
		||||
					"The item has been returned to your inventory.]"..
 | 
			
		||||
				"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"
 | 
			
		||||
			return
 | 
			
		||||
 | 
			
		||||
		-- "The player has to manually enter a password or passphrase or some other text.", -- 6
 | 
			
		||||
		elseif(data.what and id_prefix == "a_" and data.what == 6) then
 | 
			
		||||
			if(not(data.quest_question)) then
 | 
			
		||||
				data.quest_question = "Your answer:"
 | 
			
		||||
			end
 | 
			
		||||
			v[ "a_question" ] = data.quest_question
 | 
			
		||||
			-- the player setting this up needs to provide the correct answer
 | 
			
		||||
			if(not(data.quest_answer)) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Please provide the correct answer!\n"..
 | 
			
		||||
						"The answer the player gives is checked against this.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			v[ "a_value" ] = data.quest_answer
 | 
			
		||||
			if(not(data.action_failure_dialog)) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = "size[9,2.5]"..
 | 
			
		||||
						"label[0.2,0.5;Error: Please provide a target dialog if "..
 | 
			
		||||
						"the player gives the wrong answer.]"..
 | 
			
		||||
						"button[1.5,2.0;2,0.9;back_from_error_msg;Back]"})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			local dialog = yl_speak_up.speak_to[pname].dialog
 | 
			
		||||
			local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
			v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
 | 
			
		||||
		-- "Call custom functions that are supposed to be overridden by the server.", --
 | 
			
		||||
		-- precondition: 8; action: 7; effect: 11
 | 
			
		||||
		elseif(data.what
 | 
			
		||||
		  and ((id_prefix == "a_" and data.what == 7)
 | 
			
		||||
		    or (id_prefix == "p_" and data.what == 8)
 | 
			
		||||
		    or (id_prefix == "r_" and data.what == 11))) then
 | 
			
		||||
			v[ id_prefix.."value" ] = data.custom_param
 | 
			
		||||
			if(id_prefix == "a_") then
 | 
			
		||||
				local sorted_dialog_list = yl_speak_up.sort_keys(dialog.n_dialogs)
 | 
			
		||||
				v[ "a_on_failure" ] = sorted_dialog_list[ data.action_failure_dialog ]
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		v[ "alternate_text" ] = data.alternate_text
 | 
			
		||||
 | 
			
		||||
		-- only save if something was actually selected
 | 
			
		||||
		if(v[ id_prefix.."value"]) then
 | 
			
		||||
			if(not(dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ])) then
 | 
			
		||||
				dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ] = {}
 | 
			
		||||
			end
 | 
			
		||||
			-- store the change in the dialog
 | 
			
		||||
			dialog.n_dialogs[d_id].d_options[o_id][ element_list_name ][ x_id ] = v
 | 
			
		||||
			-- clear up data
 | 
			
		||||
			yl_speak_up.speak_to[pname][ id_prefix.."id" ] = nil
 | 
			
		||||
			yl_speak_up.speak_to[pname][ tmp_data_cache ] = nil
 | 
			
		||||
			-- record this as a change, but do not save do disk yet
 | 
			
		||||
			table.insert(yl_speak_up.npc_was_changed[ n_id ],
 | 
			
		||||
				"Dialog "..tostring(d_id)..": "..element_desc.." "..tostring(x_id)..
 | 
			
		||||
				" added/changed for option "..tostring(o_id)..".")
 | 
			
		||||
			if(show_save_msg) then
 | 
			
		||||
				yl_speak_up.show_fs(player, "msg", {
 | 
			
		||||
					input_to = "yl_speak_up:"..formspec_input_to,
 | 
			
		||||
					formspec = show_save_msg})
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
			-- TODO: when trying to save: save to disk as well?
 | 
			
		||||
			-- show the new/changed precondition
 | 
			
		||||
			yl_speak_up.show_fs(player, formspec_input_to, x_id)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local v = yl_speak_up.save_element_p_or_a_or_e(
 | 
			
		||||
			player, pname, n_id, d_id, o_id, x_id, id_prefix, tmp_data_cache,
 | 
			
		||||
			element_list_name, element_desc, max_entries_allowed,
 | 
			
		||||
			values_what, values_operator, values_block, values_trade, values_inv,
 | 
			
		||||
			formspec_input_to, data, fields)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	-- selections in a dropdown menu (they trigger sending the formspec)
 | 
			
		||||
 | 
			
		||||
	-- select a general direction/type first
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user