@@ -5,15 +5,18 @@ local GET_COMMAND = "GET"
5
5
-- The radius can be specified in mesecons/settings.lua
6
6
7
7
local 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]" ..
9
10
" field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]" ..
10
11
" field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]" ..
11
12
" button_exit[7,0.75;2,3;;Save]" )
12
13
end
13
14
14
- local function object_detector_on_receive_fields (pos , _ , fields )
15
+ local function object_detector_on_receive_fields (pos , formname , fields , sender )
15
16
if not fields .scanname or not fields .digiline_channel then return end
16
17
18
+ if minetest .is_protected (pos , sender :get_player_name ()) then return end
19
+
17
20
local meta = minetest .get_meta (pos )
18
21
meta :set_string (" scanname" , fields .scanname )
19
22
meta :set_string (" digiline_channel" , fields .digiline_channel )
@@ -28,14 +31,17 @@ local function object_detector_scan(pos)
28
31
if next (objs ) == nil then return false end
29
32
30
33
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
+
31
39
local every_player = scanname == " "
32
40
for _ , obj in pairs (objs ) do
33
41
-- "" is returned if it is not a player; "" ~= nil; so only handle objects with foundname ~= ""
34
42
local foundname = obj :get_player_name ()
35
-
36
43
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
39
45
return true
40
46
end
41
47
end
@@ -128,17 +134,23 @@ minetest.register_abm({
128
134
-- Detects the node in front of it
129
135
130
136
local 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]" ..
132
140
" 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}]" ..
134
143
" button_exit[7,0.75;2,3;;Save]" )
135
144
end
136
145
137
- local function node_detector_on_receive_fields (pos , _ , fields )
146
+ local function node_detector_on_receive_fields (pos , fieldname , fields , sender )
138
147
if not fields .scanname or not fields .digiline_channel then return end
139
148
149
+ if minetest .is_protected (pos , sender :get_player_name ()) then return end
150
+
140
151
local meta = minetest .get_meta (pos )
141
152
meta :set_string (" scanname" , fields .scanname )
153
+ meta :set_string (" distance" , fields .distance or " 0" )
142
154
meta :set_string (" digiline_channel" , fields .digiline_channel )
143
155
node_detector_make_formspec (pos )
144
156
end
@@ -148,10 +160,17 @@ local function node_detector_scan(pos)
148
160
local node = minetest .get_node_or_nil (pos )
149
161
if not node then return end
150
162
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
+
151
170
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 ))
153
172
).name
154
- local scanname = minetest . get_meta ( pos ) :get_string (" scanname" )
173
+ local scanname = meta :get_string (" scanname" )
155
174
156
175
return (frontname == scanname ) or
157
176
(frontname ~= " air" and frontname ~= " ignore" and scanname == " " )
@@ -162,11 +181,17 @@ local node_detector_digiline = {
162
181
effector = {
163
182
action = function (pos , node , channel , msg )
164
183
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
+
165
190
if channel ~= meta :get_string (" digiline_channel" ) then return end
166
191
167
192
if msg == GET_COMMAND then
168
193
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 ))
170
195
).name
171
196
172
197
digiline :receptor_send (pos , digiline .rules .default , channel , nodename )
@@ -208,7 +233,6 @@ minetest.register_node("mesecons_detector:node_detector_off", {
208
233
}},
209
234
on_construct = node_detector_make_formspec ,
210
235
on_receive_fields = node_detector_on_receive_fields ,
211
- after_place_node = after_place_node_detector ,
212
236
sounds = default .node_sound_stone_defaults (),
213
237
digiline = node_detector_digiline
214
238
})
@@ -225,7 +249,6 @@ minetest.register_node("mesecons_detector:node_detector_on", {
225
249
}},
226
250
on_construct = node_detector_make_formspec ,
227
251
on_receive_fields = node_detector_on_receive_fields ,
228
- after_place_node = after_place_node_detector ,
229
252
sounds = default .node_sound_stone_defaults (),
230
253
digiline = node_detector_digiline
231
254
})
0 commit comments