diff --git a/config.lua b/config.lua index 5de63b2..403dcac 100644 --- a/config.lua +++ b/config.lua @@ -34,3 +34,15 @@ yl_speak_up.trade_max_cols = 4 yl_speak_up.max_prerequirements = 12 -- how many effects can the player define per dialog option? yl_speak_up.max_result_effects = 6 + +-- these blacklists forbid NPC to use effects on blocks; format: +-- yl_speak_up.blacklist_effect_on_block_interact[ node_name ] = true +-- forbids all interactions; +-- use this if a node isn't prepared for a type of interaction with +-- an NPC and cannot be changed easily; +-- Example: yl_speak_up.blacklist_effect_on_block_right_click["default:chest"] = true +yl_speak_up.blacklist_effect_on_block_interact = {} +yl_speak_up.blacklist_effect_on_block_place = {} +yl_speak_up.blacklist_effect_on_block_dig = {} +yl_speak_up.blacklist_effect_on_block_punch = {} +yl_speak_up.blacklist_effect_on_block_right_click = {} diff --git a/fs_edit_effects.lua b/fs_edit_effects.lua index 8fbaabe..7c4d27b 100644 --- a/fs_edit_effects.lua +++ b/fs_edit_effects.lua @@ -91,6 +91,22 @@ yl_speak_up.get_sorted_player_var_list_write_access = function(pname) end +-- check if a block of type node_name is blacklisted for a certain interaction +-- (this is needed if a block is not prepared for interaction with NPC and +-- expects to always be dealing with a player) +-- Parameters: +-- how how to interact with the node +-- node_name the node to place +-- node_there the node that can currently be found at that position +yl_speak_up.check_blacklisted = function(how, node_name, node_there) + return yl_speak_up.blacklist_effect_on_block_interact[ node_name ] + or yl_speak_up.blacklist_effect_on_block_interact[ node_there ] + or (how == "place" and yl_speak_up.blacklist_effect_on_block_place[ node_name ]) + or (how == "dig" and yl_speak_up.blacklist_effect_on_block_dig[ node_there ]) + or (how == "punch" and yl_speak_up.blacklist_effect_on_block_punch[ node_there ]) + or (how == "right-click" and yl_speak_up.blacklist_effect_on_block_right_click[ node_there]) +end + -- returns a human-readable text as description of the effects -- (as shown in the edit options dialog and in the edit effect formspec) yl_speak_up.show_effect = function(r) @@ -124,6 +140,10 @@ yl_speak_up.show_effect = function(r) if(not(r.r_pos) or type(r.r_pos) ~= "table" or not(r.r_pos.x) or not(r.r_pos.y) or not(r.r_pos.z)) then return "ERROR: r.r_pos is "..minetest.serialize(r.r_pos) + -- we don't check here yet which node is actually there - that will be done upon execution + elseif(yl_speak_up.check_blacklisted(r.r_value, r.r_node, r.r_node)) then + return "ERROR: Blocks of type \""..tostring(r.r_node).."\" do not allow ".. + "interaction of type \""..tostring(r.r_value).."\" for NPC." elseif(r.r_value == "place") then return "Place \""..tostring(r.r_node).."\" with param2: "..tostring(r.r_param2).. " at "..minetest.pos_to_string(r.r_pos).."." @@ -403,7 +423,18 @@ yl_speak_up.execute_effect = function(player, n_id, o_id, r) "block: Not loaded (nil) at pos "..pos_str..".") return false end - -- TODO: add a blacklist of nodes that shall not be used this way + -- do not interact with nodes on the blacklist + if(yl_speak_up.check_blacklisted(r.r_value, r.r_node, node.name)) then + -- construct the right text for the error message + local nname = node.name + if(r.r_value == "place") then + nname = r.r_node + end + yl_speak_up.debug_msg(player, n_id, o_id, tostring(r.r_id).." ".. + "block: Blocks of type \""..tostring(nname).."\" do not allow ".. + "interaction of type \""..tostring(r.r_value).."\" for NPC.") + return false + end -- TODO: if node has owner set: check if owner == npc owner -- "If there is air: Place a block so that it looks like now.", -- 2 if(r.r_value and r.r_value == "place") then diff --git a/fs_edit_general.lua b/fs_edit_general.lua index 0344b93..5dab35a 100644 --- a/fs_edit_general.lua +++ b/fs_edit_general.lua @@ -317,6 +317,21 @@ yl_speak_up.input_fs_edit_option_related = function(player, formname, fields, 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.",