diff --git a/fs_edit_general.lua b/fs_edit_general.lua index e3c3c2f..94e613e 100644 --- a/fs_edit_general.lua +++ b/fs_edit_general.lua @@ -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 diff --git a/fs_edit_preconditions.lua b/fs_edit_preconditions.lua index b136136..a5927f2 100644 --- a/fs_edit_preconditions.lua +++ b/fs_edit_preconditions.lua @@ -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)