Skip to content

Commit 99cb021

Browse files
committedJun 8, 2014
Add node detector, which works like the player detector but detects a specific nodename (or any node except air) in front of it.
1 parent e589607 commit 99cb021

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed
 

‎mesecons_detector/init.lua

+147
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,150 @@ minetest.register_abm(
108108
end
109109
end,
110110
})
111+
112+
-- Node detector
113+
-- Detects the node in front of it
114+
115+
local node_detector_make_formspec = function (pos)
116+
local meta = minetest.get_meta(pos)
117+
meta:set_string("formspec", "size[9,2.5]" ..
118+
"field[0.3, 0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]"..
119+
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
120+
"button_exit[7,0.75;2,3;;Save]")
121+
end
122+
123+
local node_detector_on_receive_fields = function(pos, formname, fields)
124+
if not fields.scanname or not fields.digiline_channel then return end;
125+
126+
local meta = minetest.get_meta(pos)
127+
meta:set_string("scanname", fields.scanname)
128+
meta:set_string("digiline_channel", fields.digiline_channel)
129+
node_detector_make_formspec(pos)
130+
end
131+
132+
-- returns true if player was found, false if not
133+
local node_detector_scan = function (pos)
134+
local node = minetest.get_node(pos)
135+
local frontpos = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
136+
local frontnode = minetest.get_node(frontpos)
137+
local meta = minetest.get_meta(pos)
138+
return (frontnode.name == meta:get_string("scanname")) or
139+
(frontnode.name ~= "air" and frontnode.name ~= "ignore" and meta:get_string("scanname") == "")
140+
end
141+
142+
-- set player name when receiving a digiline signal on a specific channel
143+
node_detector_digiline = {
144+
effector = {
145+
action = function (pos, node, channel, msg)
146+
local meta = minetest.get_meta(pos)
147+
local active_channel = meta:get_string("digiline_channel")
148+
if channel == active_channel then
149+
meta:set_string("scanname", msg)
150+
node_detector_make_formspec(pos)
151+
end
152+
end,
153+
}
154+
}
155+
156+
minetest.register_node("mesecons_detector:node_detector_off", {
157+
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"},
158+
paramtype = "light",
159+
paramtype2 = "facedir",
160+
walkable = true,
161+
groups = {cracky=3},
162+
description="Node Detector",
163+
mesecons = {receptor = {
164+
state = mesecon.state.off
165+
}},
166+
on_construct = node_detector_make_formspec,
167+
on_receive_fields = node_detector_on_receive_fields,
168+
after_place_node = function (pos, placer)
169+
local placer_pos = placer:getpos()
170+
171+
--correct for the player's height
172+
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
173+
174+
--correct for 6d facedir
175+
if placer_pos then
176+
local dir = {
177+
x = pos.x - placer_pos.x,
178+
y = pos.y - placer_pos.y,
179+
z = pos.z - placer_pos.z
180+
}
181+
local node = minetest.get_node(pos)
182+
node.param2 = minetest.dir_to_facedir(dir, true)
183+
minetest.set_node(pos, node)
184+
minetest.log("action", "real (6d) facedir: " .. node.param2)
185+
end
186+
end,
187+
sounds = default.node_sound_stone_defaults(),
188+
digiline = node_detector_digiline
189+
})
190+
191+
minetest.register_node("mesecons_detector:node_detector_on", {
192+
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"},
193+
paramtype = "light",
194+
paramtype2 = "facedir",
195+
walkable = true,
196+
groups = {cracky=3,not_in_creative_inventory=1},
197+
drop = 'mesecons_detector:node_detector_off',
198+
mesecons = {receptor = {
199+
state = mesecon.state.on
200+
}},
201+
on_construct = node_detector_make_formspec,
202+
on_receive_fields = node_detector_on_receive_fields,
203+
after_place_node = function (pos, placer)
204+
local placer_pos = placer:getpos()
205+
206+
--correct for the player's height
207+
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
208+
209+
--correct for 6d facedir
210+
if placer_pos then
211+
local dir = {
212+
x = pos.x - placer_pos.x,
213+
y = pos.y - placer_pos.y,
214+
z = pos.z - placer_pos.z
215+
}
216+
local node = minetest.get_node(pos)
217+
node.param2 = minetest.dir_to_facedir(dir, true)
218+
minetest.set_node(pos, node)
219+
minetest.log("action", "real (6d) facedir: " .. node.param2)
220+
end
221+
end,
222+
sounds = default.node_sound_stone_defaults(),
223+
digiline = node_detector_digiline
224+
})
225+
226+
minetest.register_craft({
227+
output = 'mesecons_detector:node_detector_off',
228+
recipe = {
229+
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
230+
{"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"},
231+
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
232+
}
233+
})
234+
235+
minetest.register_abm(
236+
{nodenames = {"mesecons_detector:node_detector_off"},
237+
interval = 1.0,
238+
chance = 1,
239+
action = function(pos, node)
240+
if node_detector_scan(pos) then
241+
minetest.swap_node(pos, {name = "mesecons_detector:node_detector_on", param2 = node.param2})
242+
mesecon:receptor_on(pos)
243+
end
244+
end,
245+
})
246+
247+
minetest.register_abm(
248+
{nodenames = {"mesecons_detector:node_detector_on"},
249+
interval = 1.0,
250+
chance = 1,
251+
action = function(pos, node)
252+
if not node_detector_scan(pos) then
253+
minetest.swap_node(pos, {name = "mesecons_detector:node_detector_off", param2 = node.param2})
254+
mesecon:receptor_off(pos)
255+
end
256+
end,
257+
})
Loading
Loading

1 commit comments

Comments
 (1)

Jeija commented on Jun 8, 2014

@Jeija
Collaborator

Looks nice! Does it work if you make node_detector_digiline local? Also, it would be great if you could make it so that one could send a digiline "GET" and the detector responds with the nodename in front of it. Unfortunately, I can't test this now and won't be able to for the next two weeks.

Please sign in to comment.