allow to store preconditions of type block_inv

This commit is contained in:
Sokomine 2021-12-26 02:35:18 +01:00
parent ad063f2e0a
commit a39d308ebc
2 changed files with 143 additions and 19 deletions

View File

@ -73,6 +73,31 @@ minetest.register_chatcommand( 'npc_talk_debug', {
});
-- helper function: get the names of the inventory lists of the node at position
-- pos on the map and return the index of search_for_list_name in that index
yl_speak_up.get_node_inv_lists = function(pos, search_for_list_name)
if(not(pos)) then
return {inv_lists = {"- no inventory -"}, index = "1"}
end
local meta = minetest.get_meta(pos)
if(not(meta)) then
return {inv_lists = {"- no inventory -"}, index = "1"}
end
local inv_lists = {}
local inex = -1
local inv = meta:get_inventory()
table.insert(inv_lists, minetest.formspec_escape("- please select -"))
for k,v in pairs(inv:get_lists()) do
table.insert(inv_lists, k)
if(search_for_list_name == k) then
index = #inv_lists
end
end
return {inv_lists = inv_lists, index = tostring(index)}
end
-- evaluate those preconditions of type "function" (set by the staff)
-- and execute those effects/results of type "function" (set by the staff)
-- WARNING: This is extremly powerful!
@ -300,6 +325,7 @@ yl_speak_up.save_element_p_or_a_or_e = function(
-- "the inventory of the player", -- 5
-- "the inventory of the NPC", -- 6
-- "the inventory of a block somewhere", -- 7
-- (only for preconditions; not for effects)
elseif((what_type == "player_inv" or what_type == "npc_inv" or what_type == "block_inv") and id_prefix == "p_") then
v.p_value = values_inv[ data.inv ]
@ -317,6 +343,32 @@ yl_speak_up.save_element_p_or_a_or_e = function(
v[ "p_itemstack" ] = data.inv_stack_name
end
if(not(data.inv_list_name) or data.inv_list_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 "..
"\ninventory you want to access!]"..
"button[1.5,1.5;2,0.9;back_from_error_msg;Back]"})
return
end
-- the name of the inventory list we want to access
v[ "p_inv_list_name" ] = data.inv_list_name
-- the inventory of a block
if(what_type == "block_inv") then
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
-- 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 }
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(id_prefix == "r_" and (what_type == "give_item" or what_type == "take_item")) then
@ -907,6 +959,16 @@ yl_speak_up.input_fs_edit_option_related = function(player, formname, fields,
local nr = table.indexof(check_block, fields.select_block)
yl_speak_up.speak_to[pname][ tmp_data_cache ].block = nr
end
-- select data regarding the inventory list of a block
if(fields.inv_list_name and fields.inv_list_name ~= "") then
local tmp = yl_speak_up.get_node_inv_lists(
yl_speak_up.speak_to[pname][ tmp_data_cache ].block_pos,
fields.inv_list_name)
-- if that inventory list really exists in that block: all ok
if(tmp and tmp.index ~= "" and tmp.index ~= "1") then
yl_speak_up.speak_to[pname][ tmp_data_cache ].inv_list_name = fields.inv_list_name
end
end
-- select data regarding a variable
if(fields.select_variable) then
-- get the list of available variables (with the same elements
@ -1042,6 +1104,7 @@ yl_speak_up.input_fs_edit_option_related = function(player, formname, fields,
if(not(fields.back)
and (fields.change_element or fields.select_what or fields.select_trade
or fields.select_inv or fields.select_block
or fields.inv_list_name
or fields.select_variable or fields.select_operator
or fields.select_on_failure
or fields.select_on_action_failure
@ -1272,11 +1335,15 @@ yl_speak_up.get_fs_edit_option_related = function(player, table_click_result,
-- "the inventory of the player", -- 5
-- "the inventory of the NPC", -- 6
-- "the inventory of a block somewhere", -- 7
-- (inventory - only for preconditions; effects have something else here)
elseif(data.what and id_prefix == "p_" and (what_type == "player_inv" or what_type == "npc_inv" or what_type == "block_inv")) then
elseif(data.what and id_prefix == "p_"
and (what_type == "player_inv" or what_type == "npc_inv" or what_type == "block_inv")) then
-- the inventory of a block needs more input options (in particular block selection)
data.what_type = what_type
return yl_speak_up.get_fs_edit_option_precondition_inv(
pname, dialog, formspec, data, id_prefix, save_button, e,
values_inv, check_inv)
values_inv, check_inv, values_block)
-- "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
@ -1421,17 +1488,18 @@ yl_speak_up.get_fs_edit_option_p_and_e_state = function(
end
-- "a block somewhere", -- 3
-- (block is the third offered option in both preconditions and effects list)
yl_speak_up.get_fs_edit_option_p_and_e_block = function(
pname, dialog, formspec, data, id_prefix, save_button, e,
text_block_position, values_block, check_block)
-- helper function for:
-- yl_speak_up.get_fs_edit_option_p_and_e_block
yl_speak_up.get_block_pos_info = function(pname, data, id_prefix, e, values_block, ignore_protection)
-- 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
if(e) then
data.block = math.max(1,table.indexof(values_block, e[ id_prefix.."value" ]))
-- if we are not looking for the inventory of a block (data.what == 7):
if(data.what ~= 7) then
data.block = math.max(1,table.indexof(values_block, e[ id_prefix.."value" ]))
end
data.node_data = {}
data.node_data.data = e[ id_prefix.."node" ]
data.node_data.param2 = e[ id_prefix.."param2" ]
@ -1461,7 +1529,7 @@ yl_speak_up.get_fs_edit_option_p_and_e_block = function(
end
-- effects (and, likewise, preconditions): the player at least has to be able to
-- build at that position - check that
if(minetest.is_protected(tmp_pos, pname)) then
if(not(ignore_protection) and minetest.is_protected(tmp_pos, pname)) then
error_is_protected = "label[0.2,7.8;Error: "..
"The position you punched is protected. It cannot be used by "..
"your NPC for checks or building. Please select a diffrent block!]"
@ -1482,12 +1550,32 @@ yl_speak_up.get_fs_edit_option_p_and_e_block = function(
data.node_data = node
end
end
local show_save_button = true
if(node.name == "- unknown -") then
save_button = ""
show_save_button = false
end
if(not(data.block) or data.block == 1) then
-- if we are dealing with the *inventory* of a block, the state of the block is of no intrest here
if(data.what ~= 7 and (not(data.block) or data.block == 1)) then
data.block = 1
-- not enough selected yet for saving
show_save_button = false
end
return {block_pos = block_pos, block_pos_str = block_pos_str, node = node,
error_is_protected = error_is_protected,
show_save_button = show_save_button}
end
-- "a block somewhere", -- 3
-- (block is the third offered option in both preconditions and effects list)
yl_speak_up.get_fs_edit_option_p_and_e_block = function(
pname, dialog, formspec, data, id_prefix, save_button, e,
text_block_position, values_block, check_block)
local res = yl_speak_up.get_block_pos_info(pname, data, id_prefix, e, values_block, false)
if(not(res.show_save_button)) then
save_button = ""
end
return formspec..
@ -1496,17 +1584,17 @@ yl_speak_up.get_fs_edit_option_p_and_e_block = function(
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[4.0,4.8;"..minetest.formspec_escape(res.block_pos_str).."]"..
"label[0.2,5.8;Name of block:]"..
"label[4.0,5.8;"..minetest.formspec_escape(node.name).."]"..
"label[4.0,5.8;"..minetest.formspec_escape(res.node.name).."]"..
"label[0.2,6.8;Orientation (param2):]"..
"label[4.0,6.8;"..minetest.formspec_escape(node.param2).."]"..
"label[4.0,6.8;"..minetest.formspec_escape(res.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 or change.\n"..
"After punching it, you will be returned to this menu.]"..
error_is_protected..
res.error_is_protected..
save_button
end
@ -1535,10 +1623,11 @@ end
-- "the inventory of the player", -- 5
-- "the inventory of the NPC", -- 6
-- "the inventory of a block somewhere", -- 7
-- (inventory - only for preconditions; effects have something else here)
yl_speak_up.get_fs_edit_option_precondition_inv = function(
pname, dialog, formspec, data, id_prefix, save_button, e,
values_inv, check_inv)
values_inv, check_inv, values_block)
if(e) then
data.inv = math.max(1,table.indexof(values_inv, e["p_value"]))
data.inv_stack_name = e[ "p_itemstack" ]
@ -1548,6 +1637,38 @@ yl_speak_up.get_fs_edit_option_precondition_inv = function(
-- not enough selected yet for saving
save_button = ""
end
local block_selection = ""
if(data and data.what_type and data.what_type == "block_inv") then
local inv_list_name = ""
if(e) then
-- not really relevant here but needed for getting the position
e[ id_prefix.."value" ] = "node_is_like"
inv_list_name = e[ id_prefix.."inv_list_name"]
end
-- positions of nodes in protected areas are allowed for inventory access
local res = yl_speak_up.get_block_pos_info(pname, data, id_prefix, e, values_block, true)
if(not(res.show_save_button)) then
save_button = ""
end
-- which inventory lists are available?
local tmp = yl_speak_up.get_node_inv_lists(res.block_pos, inv_list_name)
block_selection = ""..
"label[0.2,7.0;Position of the block:]"..
"label[4.0,7.0;"..minetest.formspec_escape(res.block_pos_str).."]"..
"label[0.2,7.5;Name of block:]"..
"label[4.0,7.5;"..minetest.formspec_escape(res.node.name).."]"..
"label[0.2,8.0;Orientation (param2):]"..
"label[4.0,8.0;"..minetest.formspec_escape(res.node.param2).."]"..
"label[0.2,8.5;Inventory list name:]"..
"dropdown[4.0,8.2;3.8,0.6;inv_list_name;"..
table.concat(tmp.inv_lists, ",")..";"..
tostring(tmp.index)..";]"..
"button_exit[0.2,9.0;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 or change.\n"..
"After punching it, you will be returned to this menu.]"
end
return formspec..
"label[0.2,3.0;The following shall be true about the inventory:]"..
"dropdown[4.0,3.2;16.0,0.6;select_inv;"..
@ -1563,6 +1684,7 @@ yl_speak_up.get_fs_edit_option_precondition_inv = function(
"list[detached:yl_speak_up_player_"..pname..";npc_wants;4.0,5.5;1,1;]"..
"label[8,4.9;Your inventory:]"..
"list[current_player;main;8,5.3;8,4;]"..
block_selection..
save_button
end

View File

@ -39,13 +39,15 @@ local check_what = {
"a trade", -- 4
"the inventory of the player", -- 5
"the inventory of the NPC", -- 6
"execute Lua code (requires npc_master priv)", -- 7
"Call custom functions that are supposed to be overridden by the server.", -- 8
"The preconditions of another dialog option are fulfilled/not fulfilled.", -- 9
"the inventory of a block somewhere", -- 7
"execute Lua code (requires npc_master priv)", -- 7 -> 8
"Call custom functions that are supposed to be overridden by the server.", -- 8 -> 9
"The preconditions of another dialog option are fulfilled/not fulfilled.", -- 9 -> 10
}
-- how to store these as p_type in the precondition:
local values_what = {"", "state", "block", "trade", "player_inv", "npc_inv",
"block_inv",
-- requires npc_master priv
"function",
-- custom function (does not require npc_master priv)