@@ -5,15 +5,18 @@ local GET_COMMAND = "GET"
55-- The radius can be specified in mesecons/settings.lua
66
77local function object_detector_make_formspec (pos )
8- minetest .get_meta (pos ):set_string (" formspec" , " size[9,2.5]" ..
8+ local meta = minetest .get_meta (pos )
9+ meta :set_string (" formspec" , " size[9,2.5]" ..
910 " field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]" ..
1011 " field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]" ..
1112 " button_exit[7,0.75;2,3;;Save]" )
1213end
1314
14- local function object_detector_on_receive_fields (pos , _ , fields )
15+ local function object_detector_on_receive_fields (pos , formname , fields , sender )
1516 if not fields .scanname or not fields .digiline_channel then return end
1617
18+ if minetest .is_protected (pos , sender :get_player_name ()) then return end
19+
1720 local meta = minetest .get_meta (pos )
1821 meta :set_string (" scanname" , fields .scanname )
1922 meta :set_string (" digiline_channel" , fields .digiline_channel )
@@ -28,14 +31,17 @@ local function object_detector_scan(pos)
2831 if next (objs ) == nil then return false end
2932
3033 local scanname = minetest .get_meta (pos ):get_string (" scanname" )
34+ local scan_for = {}
35+ for _ , str in pairs (string .split (scanname :gsub (" " , " " ), " ," )) do
36+ scan_for [str ] = true
37+ end
38+
3139 local every_player = scanname == " "
3240 for _ , obj in pairs (objs ) do
3341 -- "" is returned if it is not a player; "" ~= nil; so only handle objects with foundname ~= ""
3442 local foundname = obj :get_player_name ()
35-
3643 if foundname ~= " " then
37- -- return true if scanning for any player or if specific playername was detected
38- if scanname == " " or foundname == scanname then
44+ if every_player or scan_for [foundname ] then
3945 return true
4046 end
4147 end
@@ -128,17 +134,23 @@ minetest.register_abm({
128134-- Detects the node in front of it
129135
130136local function node_detector_make_formspec (pos )
131- minetest .get_meta (pos ):set_string (" formspec" , " size[9,2.5]" ..
137+ local meta = minetest .get_meta (pos )
138+ if meta :get_string (" distance" ) == " " then meta :set_string (" distance" , " 0" ) end
139+ meta :set_string (" formspec" , " size[9,2.5]" ..
132140 " field[0.3, 0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]" ..
133- " field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]" ..
141+ " field[0.3,1.5;2.5,2;distance;Distance (0-" .. mesecon .setting (" node_detector_distance_max" , 10 ).. " ):;${distance}]" ..
142+ " field[3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]" ..
134143 " button_exit[7,0.75;2,3;;Save]" )
135144end
136145
137- local function node_detector_on_receive_fields (pos , _ , fields )
146+ local function node_detector_on_receive_fields (pos , fieldname , fields , sender )
138147 if not fields .scanname or not fields .digiline_channel then return end
139148
149+ if minetest .is_protected (pos , sender :get_player_name ()) then return end
150+
140151 local meta = minetest .get_meta (pos )
141152 meta :set_string (" scanname" , fields .scanname )
153+ meta :set_string (" distance" , fields .distance or " 0" )
142154 meta :set_string (" digiline_channel" , fields .digiline_channel )
143155 node_detector_make_formspec (pos )
144156end
@@ -148,10 +160,17 @@ local function node_detector_scan(pos)
148160 local node = minetest .get_node_or_nil (pos )
149161 if not node then return end
150162
163+ local meta = minetest .get_meta (pos )
164+
165+ local distance = meta :get_int (" distance" )
166+ local distance_max = mesecon .setting (" node_detector_distance_max" , 10 )
167+ if distance < 0 then distance = 0 end
168+ if distance > distance_max then distance = distance_max end
169+
151170 local frontname = minetest .get_node (
152- vector .subtract (pos , minetest .facedir_to_dir (node .param2 ))
171+ vector .subtract (pos , vector . multiply ( minetest .facedir_to_dir (node .param2 ), distance + 1 ))
153172 ).name
154- local scanname = minetest . get_meta ( pos ) :get_string (" scanname" )
173+ local scanname = meta :get_string (" scanname" )
155174
156175 return (frontname == scanname ) or
157176 (frontname ~= " air" and frontname ~= " ignore" and scanname == " " )
@@ -162,11 +181,17 @@ local node_detector_digiline = {
162181 effector = {
163182 action = function (pos , node , channel , msg )
164183 local meta = minetest .get_meta (pos )
184+
185+ local distance = meta :get_int (" distance" )
186+ local distance_max = mesecon .setting (" node_detector_distance_max" , 10 )
187+ if distance < 0 then distance = 0 end
188+ if distance > distance_max then distance = distance_max end
189+
165190 if channel ~= meta :get_string (" digiline_channel" ) then return end
166191
167192 if msg == GET_COMMAND then
168193 local nodename = minetest .get_node (
169- vector .subtract (pos , minetest .facedir_to_dir (node .param2 ))
194+ vector .subtract (pos , vector . multiply ( minetest .facedir_to_dir (node .param2 ), distance + 1 ))
170195 ).name
171196
172197 digiline :receptor_send (pos , digiline .rules .default , channel , nodename )
@@ -208,7 +233,6 @@ minetest.register_node("mesecons_detector:node_detector_off", {
208233 }},
209234 on_construct = node_detector_make_formspec ,
210235 on_receive_fields = node_detector_on_receive_fields ,
211- after_place_node = after_place_node_detector ,
212236 sounds = default .node_sound_stone_defaults (),
213237 digiline = node_detector_digiline
214238})
@@ -225,7 +249,6 @@ minetest.register_node("mesecons_detector:node_detector_on", {
225249 }},
226250 on_construct = node_detector_make_formspec ,
227251 on_receive_fields = node_detector_on_receive_fields ,
228- after_place_node = after_place_node_detector ,
229252 sounds = default .node_sound_stone_defaults (),
230253 digiline = node_detector_digiline
231254})
0 commit comments