2012-03-05 19:21:26 +01:00
-- |\ /| ____ ____ ____ _____ ____ _____
-- | \ / | | | | | | | |\ | |
-- | \/ | |___ ____ |___ | | | | \ | |____
-- | | | | | | | | | \ | |
-- | | |___ ____| |___ |____ |____| | \| ____|
-- by Jeija and Minerd247
--
--
--
-- This mod adds mesecons[=minecraft redstone] and different receptors/effectors to minetest.
--
-- See the documentation on the forum for additional information, especially about crafting
--
--Quick Developer documentation for the mesecon API
--=================================================
--
--RECEPTORS
--
--A receptor is a node that emits power, e.g. a solar panel, a switch or a power plant.
--Usually you create two blocks per receptor that have to be switched when switching the on/off state:
-- # An off-state node (e.g. mesecons:mesecon_switch_off"
-- # An on-state node (e.g. mesecons:mesecon_switch_on"
--The on-state and off-state nodes should be registered in the mesecon api,
--so that the Mesecon circuit can be recalculated. This can be done using
--
--mesecon:add_receptor_node(nodename) -- for on-state node
--mesecon:add_receptor_node_off(nodename) -- for off-state node
--example: mesecon:add_receptor_node("mesecons:mesecon_switch_on")
--
--Turning receptors on and off
--Usually the receptor has to turn on and off. For this, you have to
-- # Remove the node and replace it with the node in the other state (e.g. replace on by off)
-- # Send the event to the mesecon circuit by using the api functions
-- mesecon:receptor_on (pos, rules) } These functions take the position of your receptor
-- mesecon:receptor_off(pos, rules) } as their parameter.
--
--You can specify the rules using the rules parameter. If you don't want special rules, just leave it out
2012-03-29 11:53:11 +02:00
--e.g. if you want to use the "pressureplate" rules, you use this command:
--mesecon:receptor_on (pos, mesecon:get_rules("pressureplate"))
--The rules can be manipulated by several rotate functions:
--rules=mesecon:rotate_rules_right/left/up/down(rules)
--
2012-03-05 19:21:26 +01:00
--
--!! If a receptor node is removed, the circuit should be recalculated. This means you have to
--send an mesecon:receptor_off signal to the api when the function in minetest.register_on_dignode
--is called.
--
--EFFECTORS
--
--A receptor is a node that uses power and transfers the signal to a mechanical, optical whatever
--event. e.g. the meselamp, the movestone or the removestone.
--
--There are two callback functions for receptors.
-- # function mesecon:register_on_signal_on (action)
-- # function mesecon:register_on_signal_off(action)
--
--These functions will be called for each block next to a mesecon conductor.
--
--Example: The removestone
--The removestone only uses one callback: The mesecon:register_on_signal_on function
--
--mesecon:register_on_signal_on(function(pos, node) -- As the action prameter you have to use a function
-- if node.name=="mesecons:removestone" then -- Check if it really is removestone. If you wouldn't use this, every node next to mesecons would be removed
-- minetest.env:remove_node(pos) -- The action: The removestone is removed
-- end -- end of if
--end) -- end of the function, )=end of the parameters of mesecon:register_on_signal_on
-- INCLUDE SETTINGS
dofile ( minetest.get_modpath ( " mesecons " ) .. " /settings.lua " )
-- PUBLIC VARIABLES
mesecon = { } -- contains all functions and all global variables
mesecon.actions_on = { } -- Saves registered function callbacks for mesecon on
mesecon.actions_off = { } -- Saves registered function callbacks for mesecon off
2012-03-29 11:35:23 +02:00
mesecon.pwr_srcs = { }
mesecon.pwr_srcs_off = { }
mesecon.rules = { }
2012-03-05 19:21:26 +01:00
-- MESECONS
minetest.register_node ( " mesecons:mesecon_off " , {
drawtype = " raillike " ,
tile_images = { " jeija_mesecon_off.png " , " jeija_mesecon_curved_off.png " , " jeija_mesecon_t_junction_off.png " , " jeija_mesecon_crossing_off.png " } ,
inventory_image = " jeija_mesecon_off.png " ,
wield_image = " jeija_mesecon_off.png " ,
paramtype = " light " ,
is_ground_content = true ,
walkable = false ,
selection_box = {
type = " fixed " ,
} ,
2012-03-22 17:52:11 -04:00
groups = { dig_immediate = 3 } ,
2012-03-05 19:21:26 +01:00
description = " Mesecons " ,
} )
minetest.register_node ( " mesecons:mesecon_on " , {
drawtype = " raillike " ,
tile_images = { " jeija_mesecon_on.png " , " jeija_mesecon_curved_on.png " , " jeija_mesecon_t_junction_on.png " , " jeija_mesecon_crossing_on.png " } ,
paramtype = " light " ,
is_ground_content = true ,
walkable = false ,
selection_box = {
type = " fixed " ,
} ,
2012-03-22 17:52:11 -04:00
groups = { dig_immediate = 3 } ,
2012-03-05 19:21:26 +01:00
drop = ' "mesecons:mesecon_off" 1 ' ,
light_source = LIGHT_MAX - 11 ,
} )
minetest.register_craft ( {
output = ' "mesecons:mesecon_off" 16 ' ,
recipe = {
{ ' "default:mese" ' } ,
}
} )
function mesecon : is_power_on ( p , x , y , z )
local lpos = { }
lpos.x = p.x + x
lpos.y = p.y + y
lpos.z = p.z + z
local node = minetest.env : get_node ( lpos )
if node.name == " mesecons:mesecon_on " or mesecon : is_receptor_node ( node.name ) then
return 1
end
return 0
end
function mesecon : is_power_off ( p , x , y , z )
local lpos = { }
lpos.x = p.x + x
lpos.y = p.y + y
lpos.z = p.z + z
local node = minetest.env : get_node ( lpos )
if node.name == " mesecons:mesecon_off " or mesecon : is_receptor_node_off ( node.name ) then
return 1
end
return 0
end
function mesecon : turnon ( p , x , y , z , firstcall , rules )
if rules == nil then
2012-03-29 11:35:23 +02:00
rules = mesecon : get_rules ( " default " )
2012-03-05 19:21:26 +01:00
end
local lpos = { }
lpos.x = p.x + x
lpos.y = p.y + y
lpos.z = p.z + z
mesecon : activate ( lpos )
local node = minetest.env : get_node ( lpos )
if node.name == " mesecons:mesecon_off " then
--minetest.env:remove_node(lpos)
minetest.env : add_node ( lpos , { name = " mesecons:mesecon_on " } )
nodeupdate ( lpos )
end
if node.name == " mesecons:mesecon_off " or firstcall then
local i = 1
while rules [ i ] ~= nil do
2012-03-29 11:35:23 +02:00
mesecon : turnon ( lpos , rules [ i ] . x , rules [ i ] . y , rules [ i ] . z , false )
2012-03-05 19:21:26 +01:00
i = i + 1
end
end
end
function mesecon : turnoff ( pos , x , y , z , firstcall , rules )
if rules == nil then
2012-03-29 11:35:23 +02:00
rules = mesecon : get_rules ( " default " )
2012-03-05 19:21:26 +01:00
end
local lpos = { }
lpos.x = pos.x + x
lpos.y = pos.y + y
lpos.z = pos.z + z
local node = minetest.env : get_node ( lpos )
local connected = 0
local checked = { }
if not mesecon : check_if_turnon ( lpos ) then
mesecon : deactivate ( lpos )
end
if not ( firstcall ) and connected == 0 then
connected = mesecon : connected_to_pw_src ( lpos , 0 , 0 , 0 , checked )
end
if connected == 0 and node.name == " mesecons:mesecon_on " then
--minetest.env:remove_node(lpos)
minetest.env : add_node ( lpos , { name = " mesecons:mesecon_off " } )
nodeupdate ( lpos )
end
if node.name == " mesecons:mesecon_on " or firstcall then
if connected == 0 then
local i = 1
while rules [ i ] ~= nil do
2012-03-29 11:35:23 +02:00
mesecon : turnoff ( lpos , rules [ i ] . x , rules [ i ] . y , rules [ i ] . z , false )
2012-03-05 19:21:26 +01:00
i = i + 1
end
end
end
end
function mesecon : connected_to_pw_src ( pos , x , y , z , checked , firstcall )
local i = 1
local lpos = { }
lpos.x = pos.x + x
lpos.y = pos.y + y
lpos.z = pos.z + z
local node = minetest.env : get_node_or_nil ( lpos )
if not ( node == nil ) then
repeat
i = i + 1
if checked [ i ] == nil then checked [ i ] = { } break end
if checked [ i ] . x == lpos.x and checked [ i ] . y == lpos.y and checked [ i ] . z == lpos.z then
return 0
end
until false
checked [ i ] . x = lpos.x
checked [ i ] . y = lpos.y
checked [ i ] . z = lpos.z
if mesecon : is_receptor_node ( node.name ) == true then -- receptor nodes (power sources) can be added using mesecon:add_receptor_node
return 1
end
if node.name == " mesecons:mesecon_on " or firstcall then -- add other conductors here
local pw_source_found = 0
local rules = mesecon : get_rules ( " default " )
local i = 1
while rules [ i ] ~= nil do
pw_source_found = pw_source_found + mesecon : connected_to_pw_src ( lpos , rules [ i ] . x , rules [ i ] . y , rules [ i ] . z , checked , false )
i = i + 1
end
if pw_source_found > 0 then
return 1
end
end
end
return 0
end
function mesecon : check_if_turnon ( pos )
local getactivated = 0
local rules = mesecon : get_rules ( " default " )
local i = 1
2012-03-29 11:35:23 +02:00
while rules [ i ] ~= nil do
2012-03-05 19:21:26 +01:00
getactivated = getactivated + mesecon : is_power_on ( pos , rules [ i ] . x , rules [ i ] . y , rules [ i ] . z )
i = i + 1
end
if getactivated > 0 then
return true
end
return false
end
minetest.register_on_placenode ( function ( pos , newnode , placer )
if mesecon : check_if_turnon ( pos ) then
if newnode.name == " mesecons:mesecon_off " then
mesecon : turnon ( pos , 0 , 0 , 0 )
else
mesecon : activate ( pos )
end
end
end )
minetest.register_on_dignode (
function ( pos , oldnode , digger )
if oldnode.name == " mesecons:mesecon_on " then
mesecon : turnoff ( pos , 0 , 0 , 0 , true )
end
end
)
-- API API API API API API API API API API API API API API API API API API
function mesecon : add_receptor_node ( nodename )
local i = 1
repeat
i = i + 1
if mesecon.pwr_srcs [ i ] == nil then break end
until false
mesecon.pwr_srcs [ i ] = nodename
end
function mesecon : add_receptor_node_off ( nodename )
local i = 1
repeat
i = i + 1
if mesecon.pwr_srcs_off [ i ] == nil then break end
until false
mesecon.pwr_srcs_off [ i ] = nodename
end
function mesecon : receptor_on ( pos , rules )
mesecon : turnon ( pos , 0 , 0 , 0 , true , rules )
end
function mesecon : receptor_off ( pos , rules )
mesecon : turnoff ( pos , 0 , 0 , 0 , true , rules )
end
function mesecon : register_on_signal_on ( action )
local i = 1
repeat
i = i + 1
if mesecon.actions_on [ i ] == nil then break end
until false
mesecon.actions_on [ i ] = action
end
function mesecon : register_on_signal_off ( action )
local i = 1
repeat
i = i + 1
if mesecon.actions_off [ i ] == nil then break end
until false
mesecon.actions_off [ i ] = action
end
-- INTERNAL API
function mesecon : is_receptor_node ( nodename )
local i = 1
repeat
i = i + 1
if mesecon.pwr_srcs [ i ] == nodename then return true end
until mesecon.pwr_srcs [ i ] == nil
return false
end
function mesecon : is_receptor_node_off ( nodename )
local i = 1
repeat
i = i + 1
if mesecon.pwr_srcs_off [ i ] == nodename then return true end
until mesecon.pwr_srcs_off [ i ] == nil
return false
end
function mesecon : activate ( pos )
local node = minetest.env : get_node ( pos )
local i = 1
repeat
i = i + 1
if mesecon.actions_on [ i ] ~= nil then mesecon.actions_on [ i ] ( pos , node )
else break
end
until false
end
function mesecon : deactivate ( pos )
local node = minetest.env : get_node ( pos )
local i = 1
local checked = { }
repeat
i = i + 1
if mesecon.actions_off [ i ] ~= nil then mesecon.actions_off [ i ] ( pos , node )
else break
end
until false
end
mesecon : register_on_signal_on ( function ( pos , node )
if node.name == " mesecons:meselamp_off " then
--minetest.env:remove_node(pos)
minetest.env : add_node ( pos , { name = " mesecons:meselamp_on " } )
nodeupdate ( pos )
end
end )
mesecon : register_on_signal_off ( function ( pos , node )
if node.name == " mesecons:meselamp_on " then
--minetest.env:remove_node(pos)
minetest.env : add_node ( pos , { name = " mesecons:meselamp_off " } )
nodeupdate ( pos )
end
end )
2012-03-29 11:35:23 +02:00
function mesecon : add_rules ( name , rules )
local i = 0
while mesecon.rules [ i ] ~= nil do
i = i + 1
2012-03-05 19:21:26 +01:00
end
2012-03-29 11:35:23 +02:00
mesecon.rules [ i ] = { }
mesecon.rules [ i ] . name = name
mesecon.rules [ i ] . rules = rules
end
2012-03-05 19:21:26 +01:00
2012-03-29 11:35:23 +02:00
function mesecon : get_rules ( name )
local i = 0
while mesecon.rules [ i ] ~= nil do
if mesecon.rules [ i ] . name == name then
return mesecon.rules [ i ] . rules
end
i = i + 1
2012-03-05 19:21:26 +01:00
end
2012-03-29 11:35:23 +02:00
end
mesecon : add_rules ( " default " ,
{ { x = 0 , y = 0 , z =- 1 } ,
{ x = 1 , y = 0 , z = 0 } ,
{ x =- 1 , y = 0 , z = 0 } ,
{ x = 0 , y = 0 , z = 1 } ,
{ x = 1 , y = 1 , z = 0 } ,
{ x = 1 , y =- 1 , z = 0 } ,
{ x =- 1 , y = 1 , z = 0 } ,
{ x =- 1 , y =- 1 , z = 0 } ,
{ x = 0 , y = 1 , z = 1 } ,
{ x = 0 , y =- 1 , z = 1 } ,
{ x = 0 , y = 1 , z =- 1 } ,
{ x = 0 , y =- 1 , z =- 1 } } )
--Rules rotation Functions:
function mesecon : rotate_rules_right ( rules )
local i = 1
local nr = { } ;
while rules [ i ] ~= nil do
nr [ i ] = { }
nr [ i ] . z = rules [ i ] . x
nr [ i ] . x =- rules [ i ] . z
nr [ i ] . y = rules [ i ] . y
i = i + 1
2012-03-05 19:21:26 +01:00
end
2012-03-29 11:35:23 +02:00
return nr
end
function mesecon : rotate_rules_left ( rules )
local i = 1
local nr = { } ;
while rules [ i ] ~= nil do
nr [ i ] = { }
nr [ i ] . z =- rules [ i ] . x
nr [ i ] . x = rules [ i ] . z
nr [ i ] . y = rules [ i ] . y
i = i + 1
2012-03-05 19:21:26 +01:00
end
2012-03-29 11:35:23 +02:00
return nr
2012-03-05 19:21:26 +01:00
end
2012-03-29 11:35:23 +02:00
function mesecon : rotate_rules_down ( rules )
local i = 1
local nr = { } ;
while rules [ i ] ~= nil do
nr [ i ] = { }
nr [ i ] . y = rules [ i ] . x
nr [ i ] . x =- rules [ i ] . y
nr [ i ] . z = rules [ i ] . z
i = i + 1
end
return nr
end
2012-03-05 19:21:26 +01:00
2012-03-29 11:35:23 +02:00
function mesecon : rotate_rules_up ( rules )
local i = 1
local nr = { } ;
while rules [ i ] ~= nil do
nr [ i ] = { }
nr [ i ] . y =- rules [ i ] . x
nr [ i ] . x = rules [ i ] . y
nr [ i ] . z = rules [ i ] . z
i = i + 1
end
return nr
end
2012-03-05 19:21:26 +01:00
print ( " [MESEcons] Loaded! " )
--minetest.register_on_newplayer(function(player)
--local i=1
--while mesecon.wireless_receivers[i]~=nil do
-- pos=mesecon.wireless_receivers[i].pos
-- request=mesecon.wireless_receivers[i].requested_state
-- inverting=mesecon.wireless_receivers[i].inverting
-- if request==inverting then
-- mesecon:receptor_off(pos)
-- end
-- if request~=inverting then
-- mesecon:receptor_on(pos)
-- end
--end
--end)