added formspecs for precondition setup

This commit is contained in:
Sokomine 2021-06-06 00:02:29 +02:00
parent 841581d4fd
commit 9ad63d1591

View File

@ -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