2019-03-08 00:07:41 +00:00
local S = minetest.get_translator ( " mcl_observers " )
2018-01-10 17:12:27 +00:00
local rules_flat = {
2018-01-13 02:37:41 +00:00
{ x = 0 , y = 0 , z = - 1 , spread = true } ,
2018-01-10 17:12:27 +00:00
}
local get_rules_flat = function ( node )
local rules = rules_flat
for i = 1 , node.param2 do
rules = mesecon.rotate_rules_left ( rules )
end
return rules
end
2018-01-13 02:37:41 +00:00
local rules_down = { { x = 0 , y = 1 , z = 0 , spread = true } }
local rules_up = { { x = 0 , y = - 1 , z = 0 , spread = true } }
2018-01-10 20:11:07 +00:00
2018-01-10 18:30:30 +00:00
-- Scan the node in front of the observer
-- and update the observer state if needed.
-- TODO: Also scan metadata changes.
-- TODO: Ignore some node changes.
2018-01-10 20:11:07 +00:00
local observer_scan = function ( pos , initialize )
2018-01-10 18:30:30 +00:00
local node = minetest.get_node ( pos )
2018-01-10 20:11:07 +00:00
local front
if node.name == " mcl_observers:observer_up_off " or node.name == " mcl_observers:observer_up_on " then
front = vector.add ( pos , { x = 0 , y = 1 , z = 0 } )
elseif node.name == " mcl_observers:observer_down_off " or node.name == " mcl_observers:observer_down_on " then
front = vector.add ( pos , { x = 0 , y =- 1 , z = 0 } )
else
front = vector.add ( pos , minetest.facedir_to_dir ( node.param2 ) )
end
2018-01-10 18:30:30 +00:00
local frontnode = minetest.get_node ( front )
local meta = minetest.get_meta ( pos )
local oldnode = meta : get_string ( " node_name " )
local oldparam2 = meta : get_string ( " node_param2 " )
local meta_needs_updating = false
2018-01-10 20:11:07 +00:00
if oldnode ~= " " and not initialize then
2018-01-10 18:30:30 +00:00
if not ( frontnode.name == oldnode and frontnode.param2 ) then
-- Node state changed! Activate observer
2018-01-10 20:11:07 +00:00
if node.name == " mcl_observers:observer_off " then
minetest.set_node ( pos , { name = " mcl_observers:observer_on " , param2 = node.param2 } )
2018-01-13 02:37:41 +00:00
mesecon.receptor_on ( pos , get_rules_flat ( node ) )
2018-01-10 20:11:07 +00:00
elseif node.name == " mcl_observers:observer_down_off " then
minetest.set_node ( pos , { name = " mcl_observers:observer_down_on " } )
2018-01-13 02:37:41 +00:00
mesecon.receptor_on ( pos , rules_down )
2018-01-10 20:11:07 +00:00
elseif node.name == " mcl_observers:observer_up_off " then
minetest.set_node ( pos , { name = " mcl_observers:observer_up_on " } )
2018-01-13 02:37:41 +00:00
mesecon.receptor_on ( pos , rules_up )
2018-01-10 20:11:07 +00:00
end
2018-01-10 18:30:30 +00:00
meta_needs_updating = true
end
else
meta_needs_updating = true
end
if meta_needs_updating then
meta : set_string ( " node_name " , frontnode.name )
meta : set_string ( " node_param2 " , frontnode.param2 )
end
return frontnode
end
2018-01-10 20:11:07 +00:00
-- Vertical orientation (CURRENTLY DISABLED)
local observer_orientate = function ( pos , placer )
-- Not placed by player
if not placer then return end
-- Placer pitch in degrees
local pitch = placer : get_look_vertical ( ) * ( 180 / math.pi )
local node = minetest.get_node ( pos )
if pitch > 55 then -- player looking upwards
-- Observer looking downwards
minetest.set_node ( pos , { name = " mcl_observers:observer_down_off " } )
elseif pitch < - 55 then -- player looking downwards
-- Observer looking upwards
minetest.set_node ( pos , { name = " mcl_observers:observer_up_off " } )
end
end
2018-01-10 17:27:47 +00:00
mesecon.register_node ( " mcl_observers:observer " ,
{
2017-02-15 02:06:01 +00:00
is_ground_content = false ,
sounds = mcl_sounds.node_sound_stone_defaults ( ) ,
paramtype2 = " facedir " ,
2018-01-10 17:27:47 +00:00
on_rotate = false ,
_mcl_blast_resistance = 17.5 ,
_mcl_hardness = 3.5 ,
} ,
{
2019-03-08 00:07:41 +00:00
description = S ( " Observer " ) ,
_doc_items_longdesc = S ( " An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes. " ) ,
_doc_items_usagehelp = S ( " Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow shows you the side of the output, which is at the opposite side of the “face”. The arrow points to it. You need to place your redstone wire or any other component you want to power here. " ) ,
2018-01-30 04:56:30 +00:00
groups = { pickaxey = 1 , material_stone = 1 , not_opaque = 1 , } ,
2017-02-15 02:06:01 +00:00
tiles = {
2018-01-10 18:44:24 +00:00
" mcl_observers_observer_top.png^[transformR180 " , " default_furnace_bottom.png " ,
2017-02-15 02:06:01 +00:00
" mcl_observers_observer_side.png " , " mcl_observers_observer_side.png " ,
" mcl_observers_observer_front.png " , " mcl_observers_observer_back.png " ,
} ,
2018-01-10 17:27:47 +00:00
mesecons = { receptor = {
state = mesecon.state . off ,
2018-01-10 17:12:27 +00:00
rules = get_rules_flat ,
} } ,
2018-01-10 18:30:30 +00:00
on_construct = function ( pos )
2018-01-10 20:11:07 +00:00
observer_scan ( pos , true )
2018-01-10 17:46:35 +00:00
end ,
2018-01-10 20:11:07 +00:00
after_place_node = observer_orientate ,
2018-01-10 17:27:47 +00:00
} ,
{
_doc_items_create_entry = false ,
2018-01-30 04:56:30 +00:00
groups = { pickaxey = 1 , material_stone = 1 , not_opaque = 1 , not_in_creative_inventory = 1 } ,
2018-01-10 17:27:47 +00:00
tiles = {
2018-01-10 18:44:24 +00:00
" mcl_observers_observer_top.png^[transformR180 " , " default_furnace_bottom.png " ,
2018-01-10 17:27:47 +00:00
" mcl_observers_observer_side.png " , " mcl_observers_observer_side.png " ,
" mcl_observers_observer_front.png " , " mcl_observers_observer_back_lit.png " ,
} ,
mesecons = { receptor = {
state = mesecon.state . on ,
rules = get_rules_flat ,
} } ,
2018-01-10 17:46:35 +00:00
-- VERY quickly disable observer after construction
on_construct = function ( pos )
local timer = minetest.get_node_timer ( pos )
-- 1 redstone tick = 0.1 seconds
timer : start ( 0.1 )
end ,
on_timer = function ( pos , elapsed )
local node = minetest.get_node ( pos )
minetest.set_node ( pos , { name = " mcl_observers:observer_off " , param2 = node.param2 } )
2018-01-13 02:37:41 +00:00
mesecon.receptor_off ( pos , get_rules_flat ( node ) )
2018-01-10 17:46:35 +00:00
end ,
2018-01-10 17:27:47 +00:00
}
)
2018-01-10 20:11:07 +00:00
mesecon.register_node ( " mcl_observers:observer_down " ,
{
is_ground_content = false ,
sounds = mcl_sounds.node_sound_stone_defaults ( ) ,
2018-01-28 18:25:05 +00:00
groups = { pickaxey = 1 , material_stone = 1 , not_opaque = 1 , not_in_creative_inventory = 1 } ,
2018-01-10 20:11:07 +00:00
on_rotate = false ,
_mcl_blast_resistance = 17.5 ,
_mcl_hardness = 3.5 ,
2018-06-05 17:27:18 +00:00
drop = " mcl_observers:observer_off " ,
2018-01-10 20:11:07 +00:00
} ,
{
tiles = {
" mcl_observers_observer_back.png " , " mcl_observers_observer_front.png " ,
" mcl_observers_observer_side.png^[transformR90 " , " mcl_observers_observer_side.png^[transformR90 " ,
" mcl_observers_observer_top.png " , " mcl_observers_observer_top.png " ,
} ,
mesecons = { receptor = {
state = mesecon.state . off ,
rules = rules_down ,
} } ,
on_construct = function ( pos )
observer_scan ( pos , true )
end ,
} ,
{
_doc_items_create_entry = false ,
tiles = {
" mcl_observers_observer_back_lit.png " , " mcl_observers_observer_front.png " ,
" mcl_observers_observer_side.png^[transformR90 " , " mcl_observers_observer_side.png^[transformR90 " ,
" mcl_observers_observer_top.png " , " mcl_observers_observer_top.png " ,
} ,
mesecons = { receptor = {
state = mesecon.state . on ,
rules = rules_down ,
} } ,
-- VERY quickly disable observer after construction
on_construct = function ( pos )
local timer = minetest.get_node_timer ( pos )
-- 1 redstone tick = 0.1 seconds
timer : start ( 0.1 )
end ,
on_timer = function ( pos , elapsed )
local node = minetest.get_node ( pos )
minetest.set_node ( pos , { name = " mcl_observers:observer_down_off " , param2 = node.param2 } )
2018-01-13 02:37:41 +00:00
mesecon.receptor_off ( pos , rules_down )
2018-01-10 20:11:07 +00:00
end ,
} )
mesecon.register_node ( " mcl_observers:observer_up " ,
{
is_ground_content = false ,
sounds = mcl_sounds.node_sound_stone_defaults ( ) ,
2018-01-28 18:25:05 +00:00
groups = { pickaxey = 1 , material_stone = 1 , not_opaque = 1 , not_in_creative_inventory = 1 } ,
2018-01-10 20:11:07 +00:00
on_rotate = false ,
_mcl_blast_resistance = 17.5 ,
_mcl_hardness = 3.5 ,
2018-06-05 17:27:18 +00:00
drop = " mcl_observers:observer_off " ,
2018-01-10 20:11:07 +00:00
} ,
{
tiles = {
" mcl_observers_observer_front.png " , " mcl_observers_observer_back.png " ,
" mcl_observers_observer_side.png^[transformR270 " , " mcl_observers_observer_side.png^[transformR270 " ,
" mcl_observers_observer_top.png^[transformR180 " , " mcl_observers_observer_top.png^[transformR180 " ,
} ,
mesecons = { receptor = {
state = mesecon.state . off ,
rules = rules_up ,
} } ,
on_construct = function ( pos )
observer_scan ( pos , true )
end ,
} ,
{
_doc_items_create_entry = false ,
tiles = {
" mcl_observers_observer_front.png " , " mcl_observers_observer_back_lit.png " ,
" mcl_observers_observer_side.png^[transformR270 " , " mcl_observers_observer_side.png^[transformR270 " ,
" mcl_observers_observer_top.png^[transformR180 " , " mcl_observers_observer_top.png^[transformR180 " ,
} ,
mesecons = { receptor = {
state = mesecon.state . on ,
rules = rules_up ,
} } ,
-- VERY quickly disable observer after construction
on_construct = function ( pos )
local timer = minetest.get_node_timer ( pos )
-- 1 redstone tick = 0.1 seconds
timer : start ( 0.1 )
end ,
on_timer = function ( pos , elapsed )
minetest.set_node ( pos , { name = " mcl_observers:observer_up_off " } )
2018-01-13 02:37:41 +00:00
mesecon.receptor_off ( pos , rules_up )
2018-01-10 20:11:07 +00:00
end ,
} )
2018-01-10 18:30:30 +00:00
-- Regularily check the observer nodes.
-- TODO: This is rather slow and clunky. Find a more efficient way to do this.
minetest.register_abm ( {
2018-01-10 20:11:07 +00:00
nodenames = { " mcl_observers:observer_off " , " mcl_observers:observer_down_off " , " mcl_observers:observer_up_off " } ,
2018-01-10 18:30:30 +00:00
interval = 1 ,
chance = 1 ,
action = function ( pos , node )
observer_scan ( pos )
end ,
} )
2017-02-15 02:06:01 +00:00
minetest.register_craft ( {
2018-01-10 17:27:47 +00:00
output = " mcl_observers:observer_off " ,
2017-02-15 02:06:01 +00:00
recipe = {
{ " mcl_core:cobble " , " mcl_core:cobble " , " mcl_core:cobble " } ,
{ " mcl_nether:quartz " , " mesecons:redstone " , " mesecons:redstone " } ,
{ " mcl_core:cobble " , " mcl_core:cobble " , " mcl_core:cobble " } ,
}
} )
minetest.register_craft ( {
2018-01-10 17:27:47 +00:00
output = " mcl_observers:observer_off " ,
2017-02-15 02:06:01 +00:00
recipe = {
{ " mcl_core:cobble " , " mcl_core:cobble " , " mcl_core:cobble " } ,
{ " mesecons:redstone " , " mesecons:redstone " , " mcl_nether:quartz " } ,
{ " mcl_core:cobble " , " mcl_core:cobble " , " mcl_core:cobble " } ,
}
} )