123 lines
5.2 KiB
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,
|
|
})
|