forked from Sokomine/yl_speak_up
		
	added formspecs for precondition setup
This commit is contained in:
		
							parent
							
								
									841581d4fd
								
							
						
					
					
						commit
						9ad63d1591
					
				@ -1,4 +1,82 @@
 | 
			
		||||
 | 
			
		||||
-- some helper lists for creating the formspecs and evaulating
 | 
			
		||||
-- the player's answers
 | 
			
		||||
 | 
			
		||||
-- general direction of what a prerequirement may be about
 | 
			
		||||
local check_what = {
 | 
			
		||||
	"- please select -",
 | 
			
		||||
	"an internal state (i.e. of a quest)", -- 2
 | 
			
		||||
	"a block somewhere", -- 3
 | 
			
		||||
	"a trade", -- 4
 | 
			
		||||
	"the inventory of the player", -- 5
 | 
			
		||||
	"the inventory of the NPC", -- 6
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- options for "a trade"
 | 
			
		||||
local check_trade = {
 | 
			
		||||
	"- please select -",
 | 
			
		||||
	"The NPC has the item(s) he wants to sell in his inventory.",
 | 
			
		||||
	"The player has the item(s) needed to pay the price.",
 | 
			
		||||
	"The NPC ran out of stock.",
 | 
			
		||||
	"The player cannot afford the price.",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- options for "the inventory of " (either player or NPC; perhaps blocks later on)
 | 
			
		||||
local check_inv = {
 | 
			
		||||
	"- please select -",
 | 
			
		||||
	"The inventory contains the following item:",
 | 
			
		||||
	"The inventory *does not* contain the following item:",
 | 
			
		||||
	"There is room for the following item in the inventory:",
 | 
			
		||||
	"The inventory is empty.",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local check_block = {
 | 
			
		||||
	"- please select -",
 | 
			
		||||
	"The block is as it is now.",
 | 
			
		||||
	"There shall be air instead of this block.",
 | 
			
		||||
	"The block is diffrent from how it is now.",
 | 
			
		||||
	"I can't punch it. The block is as the block *above* the one I punched.",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- comparison operators for variables
 | 
			
		||||
local check_operator = {
 | 
			
		||||
	"- please select -", -- 1
 | 
			
		||||
	"== (is equal)", -- 2
 | 
			
		||||
	"~= (is not equal)", -- 3
 | 
			
		||||
	">= (is greater or equal)", -- 4
 | 
			
		||||
	">  (is greater)", -- 5
 | 
			
		||||
	"<= (is smaller or equal)", -- 6
 | 
			
		||||
	"<  (is smaller)", -- 7
 | 
			
		||||
	"not (logically invert)", -- 8
 | 
			
		||||
	"is_set (has a value)", -- 9
 | 
			
		||||
	"is_unset (has no value)" -- 10
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- some internal ones...
 | 
			
		||||
local check_variable = {
 | 
			
		||||
	"- please select -",
 | 
			
		||||
	"(internal) hour of ingame day",
 | 
			
		||||
	"(internal) player's health points",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- TODO: check inscription of a sign?
 | 
			
		||||
-- TODO: invlist as dropdown of inventory lists at detected position
 | 
			
		||||
-- TODO: variable as dropdown of allowed variables
 | 
			
		||||
 | 
			
		||||
-- which diffrent types of preconditions are available?
 | 
			
		||||
-- possible variables:
 | 
			
		||||
-- 	item		an inventory item or block (check if it exists)
 | 
			
		||||
-- 		-> needs to be a minetest.registered_item[ item ]
 | 
			
		||||
-- 	text		some text
 | 
			
		||||
-- 	pos		a position in the world (not too far from the NPC)
 | 
			
		||||
-- 		-> determined by punching
 | 
			
		||||
-- 	variable	name of a variable
 | 
			
		||||
--
 | 
			
		||||
-- TODO: may all boil down to automaticly setting some lua code?
 | 
			
		||||
--       -> better write a function for each one that can be called when needed
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
yl_speak_up.input_fs_edit_preconditions = function(player, formname, fields)
 | 
			
		||||
	if(not(player)) then
 | 
			
		||||
		return
 | 
			
		||||
@ -8,12 +86,65 @@ yl_speak_up.input_fs_edit_preconditions = function(player, formname, fields)
 | 
			
		||||
	local n_id = yl_speak_up.speak_to[pname].n_id
 | 
			
		||||
	local d_id = yl_speak_up.speak_to[pname].d_id
 | 
			
		||||
	local o_id = yl_speak_up.speak_to[pname].o_id
 | 
			
		||||
	local p_id = yl_speak_up.speak_to[pname].p_id
 | 
			
		||||
 | 
			
		||||
	-- this only works in edit mode
 | 
			
		||||
	if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- TODO: make delete work
 | 
			
		||||
	-- TODO: make save work
 | 
			
		||||
	-- TODO: check parameters
 | 
			
		||||
 | 
			
		||||
	if(fields.select_block_pos) then
 | 
			
		||||
		minetest.chat_send_player(pname,
 | 
			
		||||
			"Please punch the block you want to check in your precondition!")
 | 
			
		||||
		-- this formspec expects the block punch:
 | 
			
		||||
		yl_speak_up.speak_to[pname].expect_block_punch = "edit_preconditions"
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- select a general direction/type first
 | 
			
		||||
	if(fields.select_what) then
 | 
			
		||||
		local nr = table.indexof(check_what, fields.select_what)
 | 
			
		||||
		yl_speak_up.speak_to[pname].tmp_prereq = { what = nr }
 | 
			
		||||
 | 
			
		||||
	-- select a subtype for the "a trade" selection
 | 
			
		||||
	elseif(fields.select_trade) then
 | 
			
		||||
		local nr = table.indexof(check_trade, fields.select_trade)
 | 
			
		||||
		yl_speak_up.speak_to[pname].tmp_prereq.trade = nr
 | 
			
		||||
 | 
			
		||||
	-- select a subtype for the inventory selection (player or NPC)
 | 
			
		||||
	elseif(fields.select_inv) then
 | 
			
		||||
		local nr = table.indexof(check_inv, fields.select_inv)
 | 
			
		||||
		yl_speak_up.speak_to[pname].tmp_prereq.inv = nr
 | 
			
		||||
 | 
			
		||||
	-- select data regarding a block
 | 
			
		||||
	elseif(fields.select_block) then
 | 
			
		||||
		local nr = table.indexof(check_block, fields.select_block)
 | 
			
		||||
		yl_speak_up.speak_to[pname].tmp_prereq.block = nr
 | 
			
		||||
 | 
			
		||||
	-- select data regarding a variable
 | 
			
		||||
	elseif(fields.select_variable) then
 | 
			
		||||
		-- TODO: this needs to include player-specific variables
 | 
			
		||||
		local nr = table.indexof(check_variable, fields.select_variable)
 | 
			
		||||
		yl_speak_up.speak_to[pname].tmp_prereq.variable = nr
 | 
			
		||||
 | 
			
		||||
	-- select data regarding an operator
 | 
			
		||||
	elseif(fields.select_operator) then
 | 
			
		||||
		local nr = table.indexof(check_operator, fields.select_operator)
 | 
			
		||||
		yl_speak_up.speak_to[pname].tmp_prereq.operator = nr
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- the player wants to change/edit a precondition
 | 
			
		||||
	if(fields.change_prereq or fields.select_what or fields.select_trade
 | 
			
		||||
	  or fields.select_inv or fields.select_block
 | 
			
		||||
	  or fields.select_variable or fields.select_operator) then
 | 
			
		||||
		yl_speak_up.show_fs(player, "edit_preconditions")
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- go back to the edit option dialog
 | 
			
		||||
	yl_speak_up.show_fs(player, "edit_option_dialog",
 | 
			
		||||
		{n_id = n_id, d_id = d_id, o_id = o_id, caller="edit_precondition"})
 | 
			
		||||
@ -21,7 +152,7 @@ end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
yl_speak_up.get_fs_edit_preconditions = function(player, table_click_result)
 | 
			
		||||
	if(not(player) or not(table_click_result)) then
 | 
			
		||||
	if(not(player)) then
 | 
			
		||||
		return ""
 | 
			
		||||
	end
 | 
			
		||||
	local pname = player:get_player_name()
 | 
			
		||||
@ -29,6 +160,7 @@ yl_speak_up.get_fs_edit_preconditions = function(player, table_click_result)
 | 
			
		||||
	local n_id = yl_speak_up.speak_to[pname].n_id
 | 
			
		||||
	local d_id = yl_speak_up.speak_to[pname].d_id
 | 
			
		||||
	local o_id = yl_speak_up.speak_to[pname].o_id
 | 
			
		||||
	local p_id = yl_speak_up.speak_to[pname].p_id
 | 
			
		||||
 | 
			
		||||
	-- this only works in edit mode
 | 
			
		||||
	if(not(n_id) or yl_speak_up.edit_mode[pname] ~= n_id) then
 | 
			
		||||
@ -47,17 +179,176 @@ yl_speak_up.get_fs_edit_preconditions = function(player, table_click_result)
 | 
			
		||||
	if(not(prereq)) then
 | 
			
		||||
		prereq = {}
 | 
			
		||||
	end
 | 
			
		||||
	-- which precondition has the player selected?
 | 
			
		||||
	local sorted_key_list = yl_speak_up.sort_keys(prereq)
 | 
			
		||||
	local selected = minetest.explode_table_event(table_click_result)
 | 
			
		||||
	-- use "new" if nothing fits
 | 
			
		||||
	local p_id = "new"
 | 
			
		||||
	if((selected.type == "CHG" or selected.type == "DLC")
 | 
			
		||||
	  and selected.row <= #sorted_key_list) then
 | 
			
		||||
		p_id = sorted_key_list[ selected.row ]
 | 
			
		||||
 | 
			
		||||
	-- did we arrive here through clicking on a prereq in the dialog edit options menu?
 | 
			
		||||
	if(table_click_result) then
 | 
			
		||||
		-- which precondition has the player selected?
 | 
			
		||||
		local sorted_key_list = yl_speak_up.sort_keys(prereq)
 | 
			
		||||
		local selected = minetest.explode_table_event(table_click_result)
 | 
			
		||||
		-- use "new" if nothing fits
 | 
			
		||||
		p_id = "new"
 | 
			
		||||
		if((selected.type == "CHG" or selected.type == "DLC")
 | 
			
		||||
		  and selected.row <= #sorted_key_list) then
 | 
			
		||||
			p_id = sorted_key_list[ selected.row ]
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		-- store which prereq we are talking about
 | 
			
		||||
		yl_speak_up.speak_to[pname].p_id = p_id
 | 
			
		||||
		-- display the selected prereq
 | 
			
		||||
		if(p_id ~= "new") then
 | 
			
		||||
			return "formspec_version[3]"..
 | 
			
		||||
				"size[20,3]"..
 | 
			
		||||
				"bgcolor[#00000000;false]"..
 | 
			
		||||
				"label[0.2,0.5;Selected pre(C)ondition:]"..
 | 
			
		||||
				"tablecolumns[text;color,span=1;text;text]"..
 | 
			
		||||
				"table[0.2,0.8;19.6,0.7;table_of_preconditions;"..
 | 
			
		||||
					minetest.formspec_escape(prereq[ p_id ].p_id)..",#FFFF00,"..
 | 
			
		||||
					minetest.formspec_escape(prereq[ p_id ].p_type)..","..
 | 
			
		||||
					minetest.formspec_escape(prereq[ p_id ].p_value)..";0]"..
 | 
			
		||||
				"button[2.0,1.8;1.5,0.9;delete_prereq;Delete]"..
 | 
			
		||||
				"button[4.0,1.8;1.5,0.9;change_prereq;Change]"..
 | 
			
		||||
				"button[6.0,1.8;1,0.9;back;Back]"
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	minetest.chat_send_player("singleplayer","input: "..minetest.serialize(table_click_result))
 | 
			
		||||
	return "size[4,1.5]label[0,0;Formspec: edit preconditions\n-> "..tostring(p_id).."]"..
 | 
			
		||||
		"button[1,1.0;1,1.0;back;Back]"
 | 
			
		||||
	-- did the player get here through punching a block in the meantime?
 | 
			
		||||
	local block_pos = yl_speak_up.speak_to[pname].block_punched
 | 
			
		||||
	yl_speak_up.speak_to[pname].block_punched = nil
 | 
			
		||||
 | 
			
		||||
	local data = yl_speak_up.speak_to[pname].tmp_prereq
 | 
			
		||||
	if(not(data) or not(data.what)) then
 | 
			
		||||
		data = { what = 1}
 | 
			
		||||
	end
 | 
			
		||||
	-- fallback
 | 
			
		||||
	if(not(p_id)) then
 | 
			
		||||
		p_id = "new"
 | 
			
		||||
	end
 | 
			
		||||
	local save_button = "button[5.0,9.0;1,0.7;save_prereq;Save]"
 | 
			
		||||
	local formspec =
 | 
			
		||||
		"formspec_version[3]"..
 | 
			
		||||
		"size[20,10]"..
 | 
			
		||||
		"label[5,0.5;Edit pre(C)ondition \""..minetest.formspec_escape(p_id).."\"]"..
 | 
			
		||||
		"label[0.2,1.5;What do you want to check in this precondition?]"..
 | 
			
		||||
		"label[0.2,2.0;Something regarding...]"..
 | 
			
		||||
		"dropdown[4.0,1.8;14.0,0.6;select_what;"..
 | 
			
		||||
			table.concat(check_what, ",")..";"..
 | 
			
		||||
			tostring(data.what)..";]"..
 | 
			
		||||
		"button[3.0,9.0;1,0.7;back;Abort]"
 | 
			
		||||
 | 
			
		||||
	-- "an internal state (i.e. of a quest)", -- 2
 | 
			
		||||
	if(data.what and data.what == 2) then
 | 
			
		||||
		if(not(data.variable) or data.variable == 1) then
 | 
			
		||||
			data.variable = 1
 | 
			
		||||
			-- not enough selected yet for saving
 | 
			
		||||
			save_button = ""
 | 
			
		||||
		elseif(not(data.operator) or data.operator == 1) then
 | 
			
		||||
			data.operator = 1
 | 
			
		||||
			save_button = ""
 | 
			
		||||
		end
 | 
			
		||||
		local field_for_value = "field[11.2,4.8;7.0,0.6;var_cmp_value;;]"
 | 
			
		||||
		-- do not show value input field for unary operators
 | 
			
		||||
		if(not(data.operator) or data.operator == 1 or data.operator >= 8) then
 | 
			
		||||
			field_for_value = "label[11.2,5.1;- not used for this operator -]"
 | 
			
		||||
		end
 | 
			
		||||
		-- TODO: the list of available variables needs to be extended
 | 
			
		||||
		--       with the ones the player has read access to
 | 
			
		||||
		formspec = formspec..
 | 
			
		||||
			"label[0.2,3.3;The following expression shall be true:]"..
 | 
			
		||||
			"label[0.2,4.3;Name of variable:]"..
 | 
			
		||||
			"dropdown[0.2,4.8;6.5,0.6;select_variable;"..
 | 
			
		||||
				table.concat(check_variable, ",")..";"..
 | 
			
		||||
				tostring(data.variable)..";]"..
 | 
			
		||||
			"label[7.0,4.3;Operator:]"..
 | 
			
		||||
			"dropdown[7.0,4.8;4.0,0.6;select_operator;"..
 | 
			
		||||
				table.concat(check_operator, ",")..";"..
 | 
			
		||||
				tostring(data.operator)..";]"..
 | 
			
		||||
			"label[11.2,4.3;Value to compare with:]"..
 | 
			
		||||
			field_for_value
 | 
			
		||||
 | 
			
		||||
	-- "a trade", -- 4
 | 
			
		||||
	elseif(data.what and data.what == 4) then
 | 
			
		||||
		if(not(data.trade) or data.trade == 1) then
 | 
			
		||||
			data.trade = 1
 | 
			
		||||
			-- not enough selected yet for saving
 | 
			
		||||
			save_button = ""
 | 
			
		||||
		end
 | 
			
		||||
		formspec = formspec..
 | 
			
		||||
			"label[0.2,3.3;If the action is a trade, the following shall be true:]"..
 | 
			
		||||
			"dropdown[4.0,3.5;16.0,0.6;select_trade;"..
 | 
			
		||||
				table.concat(check_trade, ",")..";"..
 | 
			
		||||
				tostring(data.trade)..";]"
 | 
			
		||||
 | 
			
		||||
	-- "the inventory of the player", -- 5
 | 
			
		||||
	-- "the inventory of the NPC", -- 6
 | 
			
		||||
	elseif(data.what and data.what >= 5 and data.what <= 6) then
 | 
			
		||||
		if(not(data.inv) or data.inv == 1) then
 | 
			
		||||
			data.inv = 1
 | 
			
		||||
			-- not enough selected yet for saving
 | 
			
		||||
			save_button = ""
 | 
			
		||||
		end
 | 
			
		||||
		formspec = formspec..
 | 
			
		||||
			"label[0.2,3.3;The following shall be true about the inventory:]"..
 | 
			
		||||
			"dropdown[4.0,3.5;16.0,0.6;select_inv;"..
 | 
			
		||||
				table.concat(check_inv, ",")..";"..
 | 
			
		||||
				tostring(data.inv)..";]"..
 | 
			
		||||
			"label[0.2,4.5;Name of the item(stack):]"..
 | 
			
		||||
			"field[4.0,4.3;16.0,0.6;inv_stack_name;;]"..
 | 
			
		||||
			"tooltip[inv_stack_name;Enter name of the block and amount.\n"..
 | 
			
		||||
				"Example: \"default:apple 3\" for three apples,\n"..
 | 
			
		||||
				"         \"farming:bread\" for a bread.]"
 | 
			
		||||
 | 
			
		||||
	-- "a block somewhere", -- 3
 | 
			
		||||
	elseif(data.what and data.what == 3) then
 | 
			
		||||
		local block_pos_str = "- none set -"
 | 
			
		||||
		local node = {name = "- unknown -", param2 = "- unkown -"}
 | 
			
		||||
		if(not(block_pos) and data and data.block_pos) then
 | 
			
		||||
			block_pos = data.block_pos
 | 
			
		||||
		end
 | 
			
		||||
		if(block_pos) then
 | 
			
		||||
			-- store for later usage
 | 
			
		||||
			data.block_pos = block_pos
 | 
			
		||||
			tmp_pos = {x=block_pos.x, y=block_pos.y, z=block_pos.z}
 | 
			
		||||
			-- "I can't punch it. The block is as the block *above* the one I punched.",
 | 
			
		||||
			if(data.block and data.block == 5) then
 | 
			
		||||
				tmp_pos.y = block_pos.y + 1
 | 
			
		||||
			end
 | 
			
		||||
			block_pos_str = minetest.pos_to_string(tmp_pos)
 | 
			
		||||
			node = minetest.get_node_or_nil(tmp_pos)
 | 
			
		||||
			if(not(node)) then
 | 
			
		||||
				node = {name = "- unknown -", param2 = "- unkown -"}
 | 
			
		||||
			end
 | 
			
		||||
			-- "There shall be air instead of this block.",
 | 
			
		||||
			if(data.block and data.block == 3) then
 | 
			
		||||
				node = {name = "air", param2 = 0}
 | 
			
		||||
			end
 | 
			
		||||
			-- cache that (in case a sapling grows or someone else changes it)
 | 
			
		||||
			data.node_data = node
 | 
			
		||||
		end
 | 
			
		||||
		if(node.name == "- unknown -") then
 | 
			
		||||
			save_button = ""
 | 
			
		||||
		end
 | 
			
		||||
		if(not(data.block) or data.block == 1) then
 | 
			
		||||
			data.block = 1
 | 
			
		||||
			-- not enough selected yet for saving
 | 
			
		||||
			save_button = ""
 | 
			
		||||
		end
 | 
			
		||||
		formspec = formspec..
 | 
			
		||||
			"label[0.2,3.3;The following shall be true about the block:]"..
 | 
			
		||||
			"dropdown[4.0,3.5;16.0,0.6;select_block;"..
 | 
			
		||||
				table.concat(check_block, ",")..";"..
 | 
			
		||||
				tostring(data.block)..";]"..
 | 
			
		||||
			"label[0.2,4.8;Position of the block:]"..
 | 
			
		||||
			"label[4.0,4.8;"..minetest.formspec_escape(block_pos_str).."]"..
 | 
			
		||||
			"label[0.2,5.8;Name of block:]"..
 | 
			
		||||
			"label[4.0,5.8;"..minetest.formspec_escape(node.name).."]"..
 | 
			
		||||
			"label[0.2,6.8;Orientation (param2):]"..
 | 
			
		||||
			"label[4.0,6.8;"..minetest.formspec_escape(node.param2).."]"..
 | 
			
		||||
			"button_exit[10.0,5.5;4.0,0.7;select_block_pos;Set position of block]"..
 | 
			
		||||
			"tooltip[select_block_pos;Click on this button to select a block.\n"..
 | 
			
		||||
				"This menu will close and you will be asked to punch\n"..
 | 
			
		||||
				"the block at the position you want to check.\n"..
 | 
			
		||||
				"After punching it, you will be returned to this menu.]"
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return formspec..save_button
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user