From 4da5084daf488431d54686bcd8dd6658ae1aca77 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Mon, 24 Jan 2022 03:32:43 +0100 Subject: [PATCH 1/2] Make daylight detector ignore artificial light The daylight detector code used get_node_light(), which detects both natural and artificial light. This patch improves the code to use get_natural_light(), which was introduced with Minetest 5.4.0. --- mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua index ed0e4c6085..7d8cc5bcb0 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua @@ -95,9 +95,9 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) + local light = minetest.get_natural_light(pos, nil) - if light >= 12 and minetest.get_timeofday() > 0.2 and minetest.get_timeofday() < 0.8 then + if light >= 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -110,7 +110,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) + local light = minetest.get_natural_light(pos, nil) if light < 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) @@ -202,7 +202,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) + local light = minetest.get_natural_light(pos, nil) if light < 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2}) @@ -217,9 +217,9 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) + local light = minetest.get_natural_light(pos, nil) - if light >= 12 and minetest.get_timeofday() > 0.8 and minetest.get_timeofday() < 0.2 then + if light >= 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end From 77f8ecd6e84da75c25f778701ac9c1f671af9706 Mon Sep 17 00:00:00 2001 From: Nils Dagsson Moskopp Date: Mon, 7 Feb 2022 15:52:15 +0100 Subject: [PATCH 2/2] Make daylight detector work in Minetest 5.3.0 This patch contains a function that searches for a path to a node with light level 15, which is guaranteed to be sunlight. --- .../REDSTONE/mesecons_solarpanel/init.lua | 80 ++++++++++++++++--- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua index 7d8cc5bcb0..129c28eea9 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua @@ -1,5 +1,69 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local function path_to_sunlight_exists(position, light_level) + local neighbours = { + { x = 0, y = 0, z =-1 }, + { x = 0, y = 0, z = 1 }, + { x = 0, y =-1, z = 0 }, + { x = 0, y = 1, z = 0 }, + { x =-1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + } + for i=1, #neighbours do + local offset = neighbours[i] + local position_new = vector.add( + position, + offset + ) + local light_level_new = minetest.get_node_light( + position_new, + nil + ) + if 15 == light_level_new then + -- found the sunlight + return true + elseif light_level_new > light_level then + -- search where light is brighter + if path_to_sunlight_exists( + position_new, + light_level_new + ) then + return true + end + end + end +end + +local function sunlight_visible(position) + local light_level + -- Minetest 5.4.0+ can measure the daylight level at a position + if nil ~= minetest.get_natural_light then + light_level = minetest.get_natural_light( + position, + nil + ) + if light_level >= 12 then + return true + end + else -- Minetest 5.3.0 or less can only measure the light level + local time = minetest.get_timeofday() * 24000 + -- only check light level during day + if time > 6000 and time < 18000 then + light_level = minetest.get_node_light( + position, + nil + ) + if light_level >= 12 then + return path_to_sunlight_exists( + position, + 12 + ) + end + end + end + return false +end + local boxes = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 } -- Daylight Sensor @@ -95,9 +159,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_natural_light(pos, nil) - - if light >= 12 then + if sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -110,9 +172,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_natural_light(pos, nil) - - if light < 12 then + if not sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end @@ -202,9 +262,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_natural_light(pos, nil) - - if light < 12 then + if not sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -217,9 +275,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_natural_light(pos, nil) - - if light >= 12 then + if sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end