123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- local GET_COMMAND = "GET"
- -- Object detector
- -- Detects players in a certain radius
- -- The radius can be specified in mesecons/settings.lua
- local function object_detector_make_formspec(pos)
- local meta = minetest.get_meta(pos)
- meta:set_string("formspec", "size[9,2.5]" ..
- "field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]"..
- "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
- "button_exit[7,0.75;2,3;;Save]")
- end
- local function object_detector_on_receive_fields(pos, formname, fields, sender)
- if not fields.scanname or not fields.digiline_channel then return end
- if minetest.is_protected(pos, sender:get_player_name()) then return end
- local meta = minetest.get_meta(pos)
- meta:set_string("scanname", fields.scanname)
- meta:set_string("digiline_channel", fields.digiline_channel)
- object_detector_make_formspec(pos)
- end
- -- returns true if player was found, false if not
- local function object_detector_scan(pos)
- local objs = minetest.get_objects_inside_radius(pos, mesecon.setting("detector_radius", 6))
- -- abort if no scan results were found
- if next(objs) == nil then return false end
- local scanname = minetest.get_meta(pos):get_string("scanname")
- local scan_for = {}
- for _, str in pairs(string.split(scanname:gsub(" ", ""), ",")) do
- scan_for[str] = true
- end
- local every_player = scanname == ""
- for _, obj in pairs(objs) do
- -- "" is returned if it is not a player; "" ~= nil; so only handle objects with foundname ~= ""
- local foundname = obj:get_player_name()
- if foundname ~= "" then
- if every_player or scan_for[foundname] then
- return true
- end
- end
- end
- return false
- end
- -- set player name when receiving a digiline signal on a specific channel
- local object_detector_digiline = {
- effector = {
- action = function(pos, node, channel, msg)
- local meta = minetest.get_meta(pos)
- if channel == meta:get_string("digiline_channel") then
- meta:set_string("scanname", msg)
- object_detector_make_formspec(pos)
- end
- end,
- }
- }
- minetest.register_node("mesecons_detector:object_detector_off", {
- tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png"},
- paramtype = "light",
- is_ground_content = false,
- walkable = true,
- groups = {cracky=3},
- description="Player Detector",
- mesecons = {receptor = {
- state = mesecon.state.off,
- rules = mesecon.rules.pplate
- }},
- on_construct = object_detector_make_formspec,
- on_receive_fields = object_detector_on_receive_fields,
- sounds = default.node_sound_stone_defaults(),
- digiline = object_detector_digiline,
- on_blast = mesecon.on_blastnode,
- })
- minetest.register_node("mesecons_detector:object_detector_on", {
- tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png"},
- paramtype = "light",
- is_ground_content = false,
- walkable = true,
- groups = {cracky=3,not_in_creative_inventory=1},
- drop = 'mesecons_detector:object_detector_off',
- mesecons = {receptor = {
- state = mesecon.state.on,
- rules = mesecon.rules.pplate
- }},
- on_construct = object_detector_make_formspec,
- on_receive_fields = object_detector_on_receive_fields,
- sounds = default.node_sound_stone_defaults(),
- digiline = object_detector_digiline,
- on_blast = mesecon.on_blastnode,
- })
- minetest.register_craft({
- output = 'mesecons_detector:object_detector_off',
- recipe = {
- {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
- {"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"},
- {"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
- }
- })
- minetest.register_craft({
- output = 'mesecons_detector:object_detector_off',
- recipe = {
- {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
- {"default:steel_ingot", "mesecons_microcontroller:microcontroller0000", "default:steel_ingot"},
- {"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
- }
- })
- minetest.register_abm({
- nodenames = {"mesecons_detector:object_detector_off"},
- interval = 1,
- chance = 1,
- action = function(pos, node)
- if not object_detector_scan(pos) then return end
- node.name = "mesecons_detector:object_detector_on"
- minetest.swap_node(pos, node)
- mesecon.receptor_on(pos, mesecon.rules.pplate)
- end,
- })
- minetest.register_abm({
- nodenames = {"mesecons_detector:object_detector_on"},
- interval = 1,
- chance = 1,
- action = function(pos, node)
- if object_detector_scan(pos) then return end
- node.name = "mesecons_detector:object_detector_off"
- minetest.swap_node(pos, node)
- mesecon.receptor_off(pos, mesecon.rules.pplate)
- end,
- })
- -- Node detector
- -- Detects the node in front of it
- local function node_detector_make_formspec(pos)
- local meta = minetest.get_meta(pos)
- if meta:get_string("distance") == "" then meta:set_string("distance", "0") end
- meta:set_string("formspec", "size[9,2.5]" ..
- "field[0.3, 0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]"..
- "field[0.3,1.5;2.5,2;distance;Distance (0-"..mesecon.setting("node_detector_distance_max", 10).."):;${distance}]"..
- "field[3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
- "button_exit[7,0.75;2,3;;Save]")
- end
- local function node_detector_on_receive_fields(pos, fieldname, fields, sender)
- if not fields.scanname or not fields.digiline_channel then return end
- if minetest.is_protected(pos, sender:get_player_name()) then return end
- local meta = minetest.get_meta(pos)
- meta:set_string("scanname", fields.scanname)
- meta:set_string("distance", fields.distance or "0")
- meta:set_string("digiline_channel", fields.digiline_channel)
- node_detector_make_formspec(pos)
- end
- -- returns true if node was found, false if not
- local function node_detector_scan(pos)
- local node = minetest.get_node_or_nil(pos)
- if not node then return end
- local meta = minetest.get_meta(pos)
- local distance = meta:get_int("distance")
- local distance_max = mesecon.setting("node_detector_distance_max", 10)
- if distance < 0 then distance = 0 end
- if distance > distance_max then distance = distance_max end
- local frontname = minetest.get_node(
- vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1))
- ).name
- local scanname = meta:get_string("scanname")
- return (frontname == scanname) or
- (frontname ~= "air" and frontname ~= "ignore" and scanname == "")
- end
- -- set player name when receiving a digiline signal on a specific channel
- local node_detector_digiline = {
- effector = {
- action = function(pos, node, channel, msg)
- local meta = minetest.get_meta(pos)
- local distance = meta:get_int("distance")
- local distance_max = mesecon.setting("node_detector_distance_max", 10)
- if distance < 0 then distance = 0 end
- if distance > distance_max then distance = distance_max end
- if channel ~= meta:get_string("digiline_channel") then return end
- if msg == GET_COMMAND then
- local nodename = minetest.get_node(
- vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1))
- ).name
- digiline:receptor_send(pos, digiline.rules.default, channel, nodename)
- else
- meta:set_string("scanname", msg)
- node_detector_make_formspec(pos)
- end
- end,
- },
- receptor = {}
- }
- local function after_place_node_detector(pos, placer)
- local placer_pos = placer:getpos()
- if not placer_pos then
- return
- end
- --correct for the player's height
- if placer:is_player() then
- placer_pos.y = placer_pos.y + 1.625
- end
- --correct for 6d facedir
- local node = minetest.get_node(pos)
- node.param2 = minetest.dir_to_facedir(vector.subtract(pos, placer_pos), true)
- minetest.set_node(pos, node)
- end
- minetest.register_node("mesecons_detector:node_detector_off", {
- 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"},
- paramtype = "light",
- paramtype2 = "facedir",
- is_ground_content = false,
- walkable = true,
- groups = {cracky=3},
- description="Node Detector",
- mesecons = {receptor = {
- state = mesecon.state.off
- }},
- on_construct = node_detector_make_formspec,
- on_receive_fields = node_detector_on_receive_fields,
- sounds = default.node_sound_stone_defaults(),
- digiline = node_detector_digiline,
- on_blast = mesecon.on_blastnode,
- })
- minetest.register_node("mesecons_detector:node_detector_on", {
- 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"},
- paramtype = "light",
- paramtype2 = "facedir",
- is_ground_content = false,
- walkable = true,
- groups = {cracky=3,not_in_creative_inventory=1},
- drop = 'mesecons_detector:node_detector_off',
- mesecons = {receptor = {
- state = mesecon.state.on
- }},
- on_construct = node_detector_make_formspec,
- on_receive_fields = node_detector_on_receive_fields,
- sounds = default.node_sound_stone_defaults(),
- digiline = node_detector_digiline,
- on_blast = mesecon.on_blastnode,
- })
- minetest.register_craft({
- output = 'mesecons_detector:node_detector_off',
- recipe = {
- {"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
- {"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"},
- {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
- }
- })
- minetest.register_craft({
- output = 'mesecons_detector:node_detector_off',
- recipe = {
- {"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
- {"default:steel_ingot", "mesecons_microcontroller:microcontroller0000", "default:steel_ingot"},
- {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
- }
- })
- minetest.register_abm({
- nodenames = {"mesecons_detector:node_detector_off"},
- interval = 1,
- chance = 1,
- action = function(pos, node)
- if not node_detector_scan(pos) then return end
- node.name = "mesecons_detector:node_detector_on"
- minetest.swap_node(pos, node)
- mesecon.receptor_on(pos)
- end,
- })
- minetest.register_abm({
- nodenames = {"mesecons_detector:node_detector_on"},
- interval = 1,
- chance = 1,
- action = function(pos, node)
- if node_detector_scan(pos) then return end
- node.name = "mesecons_detector:node_detector_off"
- minetest.swap_node(pos, node)
- mesecon.receptor_off(pos)
- end,
- })
|