smart_light/motion_sensor.lua

123 lines
5.2 KiB
Lua

local sensor_box = { type = "fixed", fixed = { { -6/32, -6/32, 14/32, 6/32, 6/32, 16/32} } }
minetest.register_node("smart_light:motion_sensor", {
description = "Smart Light Bewegungsmelder",
tiles = {
"smart_light_case.png", "smart_light_case.png",
"smart_light_case.png", "smart_light_case.png",
"smart_light_case.png", "smart_light_case.png^smart_light_sensor_front.png",
},
drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir",
sunlight_propagates = true, groups = {cracky=2, crumbly=2},
node_box = sensor_box,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_int("range", 8)
meta:set_int("duration", 30)
meta:set_string("infotext", "Bewegungsmelder (nicht konfiguriert)")
end,
on_punch = function(pos, node, puncher)
if not puncher:get_player_control().sneak then return end
local meta = minetest.get_meta(pos)
local area = meta:get_string("sl_area")
local chan = meta:get_string("sl_chan")
if area == "" or chan == "" then
minetest.chat_send_player(puncher:get_player_name(), "Bitte zuerst mit dem Programmer verknüpfen!")
return
end
local range = meta:get_int("range")
local duration = meta:get_int("duration")
local fs = "size[5,5]label[0.5,0.2;Sensor Setup: " .. area .. ":" .. chan .. "]" ..
"field[0.8,1.5;4,1;range;Erfassungs-Radius (Blöcke);" .. range .. "]" ..
"field[0.8,3;4,1;duration;Leuchtdauer (Sekunden);" .. duration .. "]" ..
"button_exit[1,4.2;3,1;save_sensor;Einstellungen speichern]"
minetest.show_formspec(puncher:get_player_name(), "smart_light:sensor_" .. minetest.pos_to_string(pos), fs)
end,
on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local area_id = meta:get_string("sl_area")
local chan_id = meta:get_string("sl_chan")
if area_id == "" or chan_id == "" then return false end
-- Zugriff auf die Registry für diesen Channel
local chan_data = smart_light.registry.areas[area_id] and smart_light.registry.areas[area_id].channels[chan_id]
if not chan_data then return false end
local range = meta:get_int("range")
local duration = meta:get_int("duration")
local now = minetest.get_gametime()
-- 1. Lokale Erfassung
local found = false
local objs = minetest.get_objects_inside_radius(pos, range)
for _, obj in pairs(objs) do
if obj:is_player() then found = true break end
end
-- 2. Visuelles Feedback am Sensor (unabhängig vom Licht)
if found then
if node.name ~= "smart_light:motion_sensor_active" then
minetest.swap_node(pos, {name = "smart_light:motion_sensor_active", param2 = node.param2})
end
-- GLOBAL: Deadline in der Registry setzen/verlängern
chan_data.ms_deadline = now + duration
-- Licht einschalten, falls aus
if smart_light.get_status_text(area_id, chan_id) == "AUS" then
smart_light.switch_channel(area_id, chan_id, "on")
end
else
if node.name ~= "smart_light:motion_sensor" then
minetest.swap_node(pos, {name = "smart_light:motion_sensor", param2 = node.param2})
end
end
-- 3. Globale Licht-Logik (Prüfung durch jeden Sensor)
if smart_light.get_status_text(area_id, chan_id) == "AN" then
local deadline = chan_data.ms_deadline or 0
-- Nur wenn die globale Deadline abgelaufen ist, schalten wir aus
if now >= deadline then
smart_light.switch_channel(area_id, chan_id, "off")
end
end
return true
end,
after_dig_node = function(pos, oldnode, oldmetadata)
local area, chan = oldmetadata.fields.sl_area, oldmetadata.fields.sl_chan
if area and chan and smart_light.registry.areas[area] and smart_light.registry.areas[area].channels[chan] then
if smart_light.registry.areas[area].channels[chan].switches then
smart_light.registry.areas[area].channels[chan].switches[minetest.pos_to_string(pos)] = nil
smart_light.save()
end
end
end,
})
minetest.register_node("smart_light:motion_sensor_active", {
description = "Smart Light Bewegungsmelder (Aktiv)",
tiles = {
"smart_light_case.png", "smart_light_case.png",
"smart_light_case.png", "smart_light_case.png",
"smart_light_case.png", "smart_light_case.png^smart_light_sensor_front_active.png",
},
drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir",
groups = {cracky=2, crumbly=2, not_in_creative_inventory=1},
node_box = sensor_box,
drop = "smart_light:motion_sensor",
on_timer = minetest.registered_nodes["smart_light:motion_sensor"].on_timer,
on_punch = minetest.registered_nodes["smart_light:motion_sensor"].on_punch,
after_dig_node = minetest.registered_nodes["smart_light:motion_sensor"].after_dig_node,
})