Compare commits
	
		
			1 Commits
		
	
	
		
			2016.07.09
			...
			zefram_doo
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 77b8f6514a | 
							
								
								
									
										30
									
								
								COPYING.txt
									
									
									
									
									
								
							
							
						
						| @@ -1,30 +0,0 @@ | |||||||
| The Mesecons Mod for Minetest is |  | ||||||
| 	Copyright (C) 2011-2016 Mesecons Mod Developer Team and contributors |  | ||||||
|  |  | ||||||
| See the version control system log for information about other authors. |  | ||||||
|  |  | ||||||
| License of source code |  | ||||||
| ---------------------- |  | ||||||
| Copyright (C) 2011-2016 Mesecons Mod Developer Team and contributors |  | ||||||
|  |  | ||||||
| This program is free software; you can redistribute the Mesecons Mod and/or |  | ||||||
| modify it under the terms of the GNU Lesser General Public License version 3 |  | ||||||
| published by the Free Software Foundation. |  | ||||||
|  |  | ||||||
| This library is distributed in the hope that it will be useful, |  | ||||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of |  | ||||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU |  | ||||||
| Library General Public License for more details. |  | ||||||
|  |  | ||||||
| You should have received a copy of the GNU Library General Public |  | ||||||
| License along with this library; if not, write to the |  | ||||||
| Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |  | ||||||
| Boston, MA  02110-1301, USA. |  | ||||||
|  |  | ||||||
| License of media (textures, sounds and documentation) |  | ||||||
| ----------------------------------------------------- |  | ||||||
| Copyright (C) 2011-2016 Mesecons Mod Developer Team and contributors |  | ||||||
|  |  | ||||||
| All textures, sounds and documentation files are licensed under the |  | ||||||
| Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) |  | ||||||
| http://creativecommons.org/licenses/by-sa/3.0/ |  | ||||||
| @@ -22,7 +22,7 @@ OK, I want in. | |||||||
| -------------- | -------------- | ||||||
| Go get it! | Go get it! | ||||||
|  |  | ||||||
| [DOWNLOAD IT NOW](https://github.com/Jeija/minetest-mod-mesecons/archive/master.zip) | [DOWNLOADS PAGE](http://mesecons.net/downloads.php) | ||||||
|  |  | ||||||
| Now go ahead and install it like any other Minetest mod. Don't know how? Check out [the wonderful page about it](http://wiki.minetest.com/wiki/Mods) over at the Minetest Wiki. For your convenience, here's a quick summary: | Now go ahead and install it like any other Minetest mod. Don't know how? Check out [the wonderful page about it](http://wiki.minetest.com/wiki/Mods) over at the Minetest Wiki. For your convenience, here's a quick summary: | ||||||
|  |  | ||||||
| @@ -39,7 +39,7 @@ How do I use this thing? | |||||||
| ------------------------ | ------------------------ | ||||||
| How about a [quick overview video](https://www.youtube.com/watch?v=6kmeQj6iW5k)? | How about a [quick overview video](https://www.youtube.com/watch?v=6kmeQj6iW5k)? | ||||||
|  |  | ||||||
| Or maybe a [comprehensive reference](http://mesecons.net/items.html) is your style? | Or maybe a [comprehensive reference](http://mesecons.net/items.php) is your style? | ||||||
|  |  | ||||||
| An overview for the very newest of new beginners? How does [this one](http://uberi.mesecons.net/projects/MeseconsBasics/index.html) look? | An overview for the very newest of new beginners? How does [this one](http://uberi.mesecons.net/projects/MeseconsBasics/index.html) look? | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,62 +0,0 @@ | |||||||
| { |  | ||||||
| 	"Conductors" : { |  | ||||||
| 		"Mesecon" : "mesecons/doc/mesecon", |  | ||||||
| 		"Insulated Wire" : "mesecons_insulated/doc/insulated", |  | ||||||
| 		"T-Junction" : "mesecons_extrawires/doc/tjunction", |  | ||||||
| 		"Crossing" : "mesecons_extrawires/doc/crossing", |  | ||||||
| 		"Corner" : "mesecons_extrawires/doc/corner", |  | ||||||
| 		"Vertical Wire" : "mesecons_extrawires/doc/vertical", |  | ||||||
| 		"Mese" : "mesecons_extrawires/doc/mese" |  | ||||||
| 	}, |  | ||||||
| 	"Receptors" : { |  | ||||||
| 		"Power Plant" : "mesecons_powerplant/doc/powerplant", |  | ||||||
| 		"Blinky Plant" : "mesecons_blinkyplant/doc/blinkyplant", |  | ||||||
| 		"Switch" : "mesecons_switch/doc/switch", |  | ||||||
| 		"Object Detector" : "mesecons_detector/doc/objectdetector", |  | ||||||
| 		"Node Detector" : "mesecons_detector/doc/nodedetector", |  | ||||||
| 		"Wall Lever" : "mesecons_walllever/doc/walllever", |  | ||||||
| 		"Pressure Plate" : "mesecons_pressureplates/doc/pressureplate_wood", |  | ||||||
| 		"Pressure Plate" : "mesecons_pressureplates/doc/pressureplate_stone", |  | ||||||
| 		"Water Turbine" : "mesecons_hydroturbine/doc/waterturbine", |  | ||||||
| 		"Solar Panel" : "mesecons_solarpanel/doc/solarpanel", |  | ||||||
| 		"Wall Button" : "mesecons_button/doc/button" |  | ||||||
| 	}, |  | ||||||
| 	"Effectors" : { |  | ||||||
| 		"Noteblock" : "mesecons_noteblock/doc/noteblock", |  | ||||||
| 		"Lamp" : "mesecons_lamp/doc/lamp", |  | ||||||
| 		"Piston" : "mesecons_pistons/doc/piston", |  | ||||||
| 		"Sticky Piston" : "mesecons_pistons/doc/piston_sticky", |  | ||||||
| 		"Movestone" : "mesecons_movestones/doc/movestone", |  | ||||||
| 		"Sticky Movestone" : "mesecons_movestones/doc/movestone_sticky", |  | ||||||
| 		"Removestone" : "mesecons_random/doc/removestone", |  | ||||||
| 		"Ghoststone" : "mesecons_random/doc/ghoststone", |  | ||||||
| 		"Command Block" : "mesecons_commandblock/doc/commandblock", |  | ||||||
| 		"Lightstones" : { |  | ||||||
| 			"Dark Grey" : "mesecons_lightstone/doc/lightstone_darkgrey", |  | ||||||
| 			"Light Grey" : "mesecons_lightstone/doc/lightstone_lightgrey", |  | ||||||
| 			"Green" : "mesecons_lightstone/doc/lightstone_green", |  | ||||||
| 			"Red" : "mesecons_lightstone/doc/lightstone_red", |  | ||||||
| 			"Blue" : "mesecons_lightstone/doc/lightstone_blue", |  | ||||||
| 			"Yellow" : "mesecons_lightstone/doc/lightstone_yellow" |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"Logic" : { |  | ||||||
| 		"Luacontroller" : "mesecons_luacontroller/doc/luacontroller", |  | ||||||
| 		"Torch" : "mesecons_torch/doc/torch", |  | ||||||
| 		"Delayer" : "mesecons_delayer/doc/delayer", |  | ||||||
| 		"Gates" : { |  | ||||||
| 			"Diode" : "mesecons_gates/doc/diode", |  | ||||||
| 			"NOT Gate" : "mesecons_gates/doc/not", |  | ||||||
| 			"AND Gate" : "mesecons_gates/doc/and", |  | ||||||
| 			"NAND Gate" : "mesecons_gates/doc/nand", |  | ||||||
| 			"OR Gate" : "mesecons_gates/doc/or", |  | ||||||
| 			"NOR Gate" : "mesecons_gates/doc/nor", |  | ||||||
| 			"XOR Gate" : "mesecons_gates/doc/xor" |  | ||||||
| 		} |  | ||||||
| 	}, |  | ||||||
| 	"Crafts" : { |  | ||||||
| 		"Silicon" : "mesecons_materials/doc/silicon", |  | ||||||
| 		"Glue" : "mesecons_materials/doc/glue", |  | ||||||
| 		"Fiber" : "mesecons_materials/doc/fiber" |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
							
								
								
									
										1
									
								
								mesecons/VERSION
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | 0.41 DEV | ||||||
| @@ -12,19 +12,19 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior | |||||||
| 	-- Create Action Table: | 	-- Create Action Table: | ||||||
| 	time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution | 	time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution | ||||||
| 	priority = priority or 1 | 	priority = priority or 1 | ||||||
| 	local action = {	pos=mesecon.tablecopy(pos), | 	local action = {	pos=mesecon:tablecopy(pos), | ||||||
| 				func=func, | 				func=func, | ||||||
| 				params=mesecon.tablecopy(params or {}), | 				params=mesecon:tablecopy(params), | ||||||
| 				time=time, | 				time=time, | ||||||
| 				owcheck=(overwritecheck and mesecon.tablecopy(overwritecheck)) or nil, | 				owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil, | ||||||
| 				priority=priority} | 				priority=priority} | ||||||
|  |  | ||||||
| 	local toremove = nil | 	local toremove = nil | ||||||
| 	-- Otherwise, add the action to the queue | 	-- Otherwise, add the action to the queue | ||||||
| 	if overwritecheck then -- check if old action has to be overwritten / removed: | 	if overwritecheck then -- check if old action has to be overwritten / removed: | ||||||
| 		for i, ac in ipairs(mesecon.queue.actions) do | 		for i, ac in ipairs(mesecon.queue.actions) do | ||||||
| 			if(vector.equals(pos, ac.pos) | 			if(mesecon:cmpPos(pos, ac.pos) | ||||||
| 			and mesecon.cmpAny(overwritecheck, ac.owcheck)) then | 			and mesecon:cmpAny(overwritecheck, ac.owcheck)) then | ||||||
| 				toremove = i | 				toremove = i | ||||||
| 				break | 				break | ||||||
| 			end | 			end | ||||||
| @@ -44,8 +44,7 @@ end | |||||||
| -- However, even that does not work in some cases, that's why we delay the time the globalsteps | -- However, even that does not work in some cases, that's why we delay the time the globalsteps | ||||||
| -- start to be execute by 5 seconds | -- start to be execute by 5 seconds | ||||||
| local get_highest_priority = function (actions) | local get_highest_priority = function (actions) | ||||||
| 	local highestp = -1 | 	local highestp = -1, highesti | ||||||
| 	local highesti |  | ||||||
| 	for i, ac in ipairs(actions) do | 	for i, ac in ipairs(actions) do | ||||||
| 		if ac.priority > highestp then | 		if ac.priority > highestp then | ||||||
| 			highestp = ac.priority | 			highestp = ac.priority | ||||||
| @@ -57,13 +56,10 @@ local get_highest_priority = function (actions) | |||||||
| end | end | ||||||
|  |  | ||||||
| local m_time = 0 | local m_time = 0 | ||||||
| local resumetime = mesecon.setting("resumetime", 4) |  | ||||||
| minetest.register_globalstep(function (dtime) | minetest.register_globalstep(function (dtime) | ||||||
| 	m_time = m_time + dtime | 	m_time = m_time + dtime | ||||||
| 	-- don't even try if server has not been running for XY seconds; resumetime = time to wait | 	if (m_time < MESECONS_RESUMETIME) then return end -- don't even try if server has not been running for XY seconds | ||||||
| 	-- after starting the server before processing the ActionQueue, don't set this too low | 	local actions = mesecon:tablecopy(mesecon.queue.actions) | ||||||
| 	if (m_time < resumetime) then return end |  | ||||||
| 	local actions = mesecon.tablecopy(mesecon.queue.actions) |  | ||||||
| 	local actions_now={} | 	local actions_now={} | ||||||
|  |  | ||||||
| 	mesecon.queue.actions = {} | 	mesecon.queue.actions = {} | ||||||
| @@ -94,8 +90,25 @@ end | |||||||
| -- Store and read the ActionQueue to / from a file | -- Store and read the ActionQueue to / from a file | ||||||
| -- so that upcoming actions are remembered when the game | -- so that upcoming actions are remembered when the game | ||||||
| -- is restarted | -- is restarted | ||||||
| mesecon.queue.actions = mesecon.file2table("mesecon_actionqueue") |  | ||||||
|  | local wpath = minetest.get_worldpath() | ||||||
|  | local function file2table(filename) | ||||||
|  | 	local f = io.open(filename, "r") | ||||||
|  | 	if f==nil then return {} end | ||||||
|  | 	local t = f:read("*all") | ||||||
|  | 	f:close() | ||||||
|  | 	if t=="" or t==nil then return {} end | ||||||
|  | 	return minetest.deserialize(t) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local function table2file(filename, table) | ||||||
|  | 	local f = io.open(filename, "w") | ||||||
|  | 	f:write(minetest.serialize(table)) | ||||||
|  | 	f:close() | ||||||
|  | end | ||||||
|  |  | ||||||
|  | mesecon.queue.actions = file2table(wpath.."/mesecon_actionqueue") | ||||||
|  |  | ||||||
| minetest.register_on_shutdown(function() | minetest.register_on_shutdown(function() | ||||||
| 	mesecon.table2file("mesecon_actionqueue", mesecon.queue.actions) | 	mesecon.queue.actions = table2file(wpath.."/mesecon_actionqueue", mesecon.queue.actions) | ||||||
| end) | end) | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
|  Mesecons are the wires, use them to connect effectors with receptors. |  | ||||||
| Before Width: | Height: | Size: 29 KiB | 
| Before Width: | Height: | Size: 3.8 KiB | 
| @@ -47,14 +47,15 @@ mesecon.queue.funcs={} -- contains all ActionQueue functions | |||||||
| -- Settings | -- Settings | ||||||
| dofile(minetest.get_modpath("mesecons").."/settings.lua") | dofile(minetest.get_modpath("mesecons").."/settings.lua") | ||||||
|  |  | ||||||
|  | -- Presets (eg default rules) | ||||||
|  | dofile(minetest.get_modpath("mesecons").."/presets.lua"); | ||||||
|  |  | ||||||
|  |  | ||||||
| -- Utilities like comparing positions, | -- Utilities like comparing positions, | ||||||
| -- adding positions and rules, | -- adding positions and rules, | ||||||
| -- mostly things that make the source look cleaner | -- mostly things that make the source look cleaner | ||||||
| dofile(minetest.get_modpath("mesecons").."/util.lua"); | dofile(minetest.get_modpath("mesecons").."/util.lua"); | ||||||
|  |  | ||||||
| -- Presets (eg default rules) |  | ||||||
| dofile(minetest.get_modpath("mesecons").."/presets.lua"); |  | ||||||
|  |  | ||||||
| -- The ActionQueue | -- The ActionQueue | ||||||
| -- Saves all the actions that have to be execute in the future | -- Saves all the actions that have to be execute in the future | ||||||
| dofile(minetest.get_modpath("mesecons").."/actionqueue.lua"); | dofile(minetest.get_modpath("mesecons").."/actionqueue.lua"); | ||||||
| @@ -66,6 +67,11 @@ dofile(minetest.get_modpath("mesecons").."/actionqueue.lua"); | |||||||
| -- like calling action_on/off/change | -- like calling action_on/off/change | ||||||
| dofile(minetest.get_modpath("mesecons").."/internal.lua"); | dofile(minetest.get_modpath("mesecons").."/internal.lua"); | ||||||
|  |  | ||||||
|  | -- Deprecated stuff | ||||||
|  | -- To be removed in future releases | ||||||
|  | -- Currently there is nothing here | ||||||
|  | dofile(minetest.get_modpath("mesecons").."/legacy.lua"); | ||||||
|  |  | ||||||
| -- API | -- API | ||||||
| -- these are the only functions you need to remember | -- these are the only functions you need to remember | ||||||
|  |  | ||||||
| @@ -73,8 +79,8 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) | |||||||
| 	rules = rules or mesecon.rules.default | 	rules = rules or mesecon.rules.default | ||||||
|  |  | ||||||
| 	-- if area (any of the rule targets) is not loaded, keep trying and call this again later | 	-- if area (any of the rule targets) is not loaded, keep trying and call this again later | ||||||
| 	for _, rule in ipairs(mesecon.flattenrules(rules)) do | 	for _, rule in ipairs(mesecon:flattenrules(rules)) do | ||||||
| 		local np = vector.add(pos, rule) | 		local np = mesecon:addPosRule(pos, rule) | ||||||
| 		-- if area is not loaded, keep trying | 		-- if area is not loaded, keep trying | ||||||
| 		if minetest.get_node_or_nil(np) == nil then | 		if minetest.get_node_or_nil(np) == nil then | ||||||
| 			mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) | 			mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) | ||||||
| @@ -83,16 +89,16 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) | |||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	-- execute action | 	-- execute action | ||||||
| 	for _, rule in ipairs(mesecon.flattenrules(rules)) do | 	for _, rule in ipairs(mesecon:flattenrules(rules)) do | ||||||
| 		local np = vector.add(pos, rule) | 		local np = mesecon:addPosRule(pos, rule) | ||||||
| 		local rulenames = mesecon.rules_link_rule_all(pos, rule) | 		local rulenames = mesecon:rules_link_rule_all(pos, rule) | ||||||
| 		for _, rulename in ipairs(rulenames) do | 		for _, rulename in ipairs(rulenames) do | ||||||
| 			mesecon.turnon(np, rulename) | 			mesecon:turnon(np, rulename) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
|  |  | ||||||
| function mesecon.receptor_on(pos, rules) | function mesecon:receptor_on(pos, rules) | ||||||
| 	mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) | 	mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -100,38 +106,34 @@ mesecon.queue:add_function("receptor_off", function (pos, rules) | |||||||
| 	rules = rules or mesecon.rules.default | 	rules = rules or mesecon.rules.default | ||||||
|  |  | ||||||
| 	-- if area (any of the rule targets) is not loaded, keep trying and call this again later | 	-- if area (any of the rule targets) is not loaded, keep trying and call this again later | ||||||
| 	for _, rule in ipairs(mesecon.flattenrules(rules)) do | 	for _, rule in ipairs(mesecon:flattenrules(rules)) do | ||||||
| 		local np = vector.add(pos, rule) | 		local np = mesecon:addPosRule(pos, rule) | ||||||
| 		if minetest.get_node_or_nil(np) == nil then | 		if minetest.get_node_or_nil(np) == nil then | ||||||
| 			mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) | 			mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) | ||||||
| 			return | 			return | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	for _, rule in ipairs(mesecon.flattenrules(rules)) do | 	for _, rule in ipairs(mesecon:flattenrules(rules)) do | ||||||
| 		local np = vector.add(pos, rule) | 		local np = mesecon:addPosRule(pos, rule) | ||||||
| 		local rulenames = mesecon.rules_link_rule_all(pos, rule) | 		local rulenames = mesecon:rules_link_rule_all(pos, rule) | ||||||
| 		for _, rulename in ipairs(rulenames) do | 		for _, rulename in ipairs(rulenames) do | ||||||
| 			if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then | 			if not mesecon:connected_to_receptor(np, mesecon:invertRule(rule)) then | ||||||
| 				mesecon.turnoff(np, rulename) | 				mesecon:turnoff(np, rulename) | ||||||
| 			else | 			else | ||||||
| 				mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2) | 				mesecon:changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2) | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
|  |  | ||||||
| function mesecon.receptor_off(pos, rules) | function mesecon:receptor_off(pos, rules) | ||||||
| 	mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) | 	mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) | ||||||
| end | end | ||||||
|  |  | ||||||
|  |  | ||||||
| print("[OK] Mesecons") | print("[OK] Mesecons") | ||||||
|  |  | ||||||
| -- Deprecated stuff |  | ||||||
| -- To be removed in future releases |  | ||||||
| dofile(minetest.get_modpath("mesecons").."/legacy.lua"); |  | ||||||
|  |  | ||||||
| --The actual wires | --The actual wires | ||||||
| dofile(minetest.get_modpath("mesecons").."/wires.lua"); | dofile(minetest.get_modpath("mesecons").."/wires.lua"); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,58 +1,62 @@ | |||||||
| -- Internal.lua - The core of mesecons | -- Internal.lua - The core of mesecons | ||||||
| -- | -- | ||||||
| -- For more practical developer resources see http://mesecons.net/developers.php | -- For more practical developer resources see mesecons.tk | ||||||
| -- | -- | ||||||
| -- Function overview | -- Function overview | ||||||
| -- mesecon.get_effector(nodename)	--> Returns the mesecons.effector -specifictation in the nodedef by the nodename | -- mesecon:get_effector(nodename)     --> Returns the mesecons.effector -specifictation in the nodedef by the nodename | ||||||
| -- mesecon.get_receptor(nodename)	--> Returns the mesecons.receptor -specifictation in the nodedef by the nodename | -- mesecon:get_receptor(nodename)     --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename | ||||||
| -- mesecon.get_conductor(nodename)	--> Returns the mesecons.conductor-specifictation in the nodedef by the nodename | -- mesecon:get_conductor(nodename)    --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename | ||||||
| -- mesecon.get_any_inputrules (node)	--> Returns the rules of a node if it is a conductor or an effector | -- mesecon:get_any_inputrules (node)  --> Returns the rules of a node if it is a conductor or an effector | ||||||
| -- mesecon.get_any_outputrules (node)	--> Returns the rules of a node if it is a conductor or a receptor | -- mesecon:get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor | ||||||
|  |  | ||||||
| -- RECEPTORS | -- RECEPTORS | ||||||
| -- mesecon.is_receptor(nodename)	--> Returns true if nodename is a receptor | -- mesecon:is_receptor(nodename)     --> Returns true if nodename is a receptor | ||||||
| -- mesecon.is_receptor_on(nodename	--> Returns true if nodename is an receptor with state = mesecon.state.on | -- mesecon:is_receptor_on(nodename)  --> Returns true if nodename is an receptor with state = mesecon.state.on | ||||||
| -- mesecon.is_receptor_off(nodename)	--> Returns true if nodename is an receptor with state = mesecon.state.off | -- mesecon:is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off | ||||||
| -- mesecon.receptor_get_rules(node)	--> Returns the rules of the receptor (mesecon.rules.default if none specified) | -- mesecon:receptor_get_rules(node)  --> Returns the rules of the receptor (mesecon.rules.default if none specified) | ||||||
|  |  | ||||||
| -- EFFECTORS | -- EFFECTORS | ||||||
| -- mesecon.is_effector(nodename)	--> Returns true if nodename is an effector | -- mesecon:is_effector(nodename)     --> Returns true if nodename is an effector | ||||||
| -- mesecon.is_effector_on(nodename)	--> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off | -- mesecon:is_effector_on(nodename)  --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off | ||||||
| -- mesecon.is_effector_off(nodename)	--> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on | -- mesecon:is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on | ||||||
| -- mesecon.effector_get_rules(node)	--> Returns the input rules of the effector (mesecon.rules.default if none specified) | -- mesecon:effector_get_rules(node)  --> Returns the input rules of the effector (mesecon.rules.default if none specified) | ||||||
|  |  | ||||||
| -- SIGNALS | -- SIGNALS | ||||||
| -- mesecon.activate(pos, node, depth)				--> Activates   the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher depths are executed later | -- mesecon:activate(pos, node, recdepth)		--> Activates   the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher recdepths are executed later | ||||||
| -- mesecon.deactivate(pos, node, depth)				--> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), higher depths are executed later | -- mesecon:deactivate(pos, node, recdepth)		--> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), " | ||||||
| -- mesecon.changesignal(pos, node, rulename, newstate, depth)	--> Changes     the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), higher depths are executed later | -- mesecon:changesignal(pos, node, rulename, newstate)	--> Changes     the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), " | ||||||
|  |  | ||||||
|  | -- RULES | ||||||
|  | -- mesecon:add_rules(name, rules) | deprecated? --> Saves rules table by name | ||||||
|  | -- mesecon:get_rules(name, rules) | deprecated? --> Loads rules table with name | ||||||
|  |  | ||||||
| -- CONDUCTORS | -- CONDUCTORS | ||||||
| -- mesecon.is_conductor(nodename)	--> Returns true if nodename is a conductor | -- mesecon:is_conductor(nodename)     --> Returns true if nodename is a conductor | ||||||
| -- mesecon.is_conductor_on(node		--> Returns true if node is a conductor with state = mesecon.state.on | -- mesecon:is_conductor_on(node)  --> Returns true if node is a conductor with state = mesecon.state.on | ||||||
| -- mesecon.is_conductor_off(node)	--> Returns true if node is a conductor with state = mesecon.state.off | -- mesecon:is_conductor_off(node) --> Returns true if node is a conductor with state = mesecon.state.off | ||||||
| -- mesecon.get_conductor_on(node_off)	--> Returns the onstate  nodename of the conductor | -- mesecon:get_conductor_on(node_off) --> Returns the onstate  nodename of the conductor | ||||||
| -- mesecon.get_conductor_off(node_on)	--> Returns the offstate nodename of the conductor | -- mesecon:get_conductor_off(node_on) --> Returns the offstate nodename of the conductor | ||||||
| -- mesecon.conductor_get_rules(node)	--> Returns the input+output rules of a conductor (mesecon.rules.default if none specified) | -- mesecon:conductor_get_rules(node)  --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified) | ||||||
|  |  | ||||||
| -- HIGH-LEVEL Internals | -- HIGH-LEVEL Internals | ||||||
| -- mesecon.is_power_on(pos)				--> Returns true if pos emits power in any way | -- mesecon:is_power_on(pos)             --> Returns true if pos emits power in any way | ||||||
| -- mesecon.is_power_off(pos)				--> Returns true if pos does not emit power in any way | -- mesecon:is_power_off(pos)            --> Returns true if pos does not emit power in any way | ||||||
| -- mesecon.turnon(pos, link) 				--> link is the input rule that caused calling turnon, turns on every connected node, iterative | -- mesecon:turnon(pos, rulename)        --> Returns true  whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnon; Uses third parameter recdepth internally to determine how far away the current node is from the initial pos as it uses recursion | ||||||
| -- mesecon.turnoff(pos, link)				--> link is the input rule that caused calling turnoff, turns off every connected node, iterative | -- mesecon:turnoff(pos, rulename)       --> Turns off whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnoff; Uses third parameter recdepth internally to determine how far away the current node is from the initial pos as it uses recursion | ||||||
| -- mesecon.connected_to_receptor(pos, link)		--> Returns true if pos is connected to a receptor directly or via conductors, iterative | -- mesecon:connected_to_receptor(pos)   --> Returns true if pos is connected to a receptor directly or via conductors; calls itself if pos is a conductor --> recursive | ||||||
| -- mesecon.rules_link(output, input, dug_outputrules)	--> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect) | -- mesecon:rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect) | ||||||
| -- mesecon.rules_link_anydir(outp., inp., d_outpr.)	--> Same as rules mesecon.rules_link but also returns true if output and input are swapped | -- mesecon:rules_link_anydir(outp., inp., d_outpr.)   --> Same as rules mesecon:rules_link but also returns true if output and input are swapped | ||||||
| -- mesecon.is_powered(pos)				--> Returns true if pos is powered by a receptor or a conductor | -- mesecon:is_powered(pos)              --> Returns true if pos is powered by a receptor or a conductor | ||||||
|  |  | ||||||
| -- RULES ROTATION helpers | -- RULES ROTATION helpsers | ||||||
| -- mesecon.rotate_rules_right(rules) | -- mesecon:rotate_rules_right(rules) | ||||||
| -- mesecon.rotate_rules_left(rules) | -- mesecon:rotate_rules_left(rules) | ||||||
| -- mesecon.rotate_rules_up(rules) | -- mesecon:rotate_rules_up(rules) | ||||||
| -- mesecon.rotate_rules_down(rules) | -- mesecon:rotate_rules_down(rules) | ||||||
| -- These functions return rules that have been rotated in the specific direction | -- These functions return rules that have been rotated in the specific direction | ||||||
|  |  | ||||||
| -- General | -- General | ||||||
| function mesecon.get_effector(nodename) | function mesecon:get_effector(nodename) | ||||||
| 	if  minetest.registered_nodes[nodename] | 	if  minetest.registered_nodes[nodename] | ||||||
| 	and minetest.registered_nodes[nodename].mesecons | 	and minetest.registered_nodes[nodename].mesecons | ||||||
| 	and minetest.registered_nodes[nodename].mesecons.effector then | 	and minetest.registered_nodes[nodename].mesecons.effector then | ||||||
| @@ -60,7 +64,7 @@ function mesecon.get_effector(nodename) | |||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.get_receptor(nodename) | function mesecon:get_receptor(nodename) | ||||||
| 	if  minetest.registered_nodes[nodename] | 	if  minetest.registered_nodes[nodename] | ||||||
| 	and minetest.registered_nodes[nodename].mesecons | 	and minetest.registered_nodes[nodename].mesecons | ||||||
| 	and minetest.registered_nodes[nodename].mesecons.receptor then | 	and minetest.registered_nodes[nodename].mesecons.receptor then | ||||||
| @@ -68,7 +72,7 @@ function mesecon.get_receptor(nodename) | |||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.get_conductor(nodename) | function mesecon:get_conductor(nodename) | ||||||
| 	if  minetest.registered_nodes[nodename] | 	if  minetest.registered_nodes[nodename] | ||||||
| 	and minetest.registered_nodes[nodename].mesecons | 	and minetest.registered_nodes[nodename].mesecons | ||||||
| 	and minetest.registered_nodes[nodename].mesecons.conductor then | 	and minetest.registered_nodes[nodename].mesecons.conductor then | ||||||
| @@ -76,59 +80,52 @@ function mesecon.get_conductor(nodename) | |||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.get_any_outputrules (node) | function mesecon:get_any_outputrules (node) | ||||||
| 	if not node then return nil end | 	if mesecon:is_conductor(node.name) then | ||||||
|  | 		return mesecon:conductor_get_rules(node) | ||||||
| 	if mesecon.is_conductor(node.name) then | 	elseif mesecon:is_receptor(node.name) then | ||||||
| 		return mesecon.conductor_get_rules(node) | 		return mesecon:receptor_get_rules(node) | ||||||
| 	elseif mesecon.is_receptor(node.name) then |  | ||||||
| 		return mesecon.receptor_get_rules(node) |  | ||||||
| 	end | 	end | ||||||
|  | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.get_any_inputrules (node) | function mesecon:get_any_inputrules (node) | ||||||
| 	if not node then return nil end | 	if mesecon:is_conductor(node.name) then | ||||||
|  | 		return mesecon:conductor_get_rules(node) | ||||||
| 	if mesecon.is_conductor(node.name) then | 	elseif mesecon:is_effector(node.name) then | ||||||
| 		return mesecon.conductor_get_rules(node) | 		return mesecon:effector_get_rules(node) | ||||||
| 	elseif mesecon.is_effector(node.name) then |  | ||||||
| 		return mesecon.effector_get_rules(node) |  | ||||||
| 	end | 	end | ||||||
| end | 	return false | ||||||
|  |  | ||||||
| function mesecon.get_any_rules (node) |  | ||||||
| 	return mesecon.mergetable(mesecon.get_any_inputrules(node) or {}, |  | ||||||
| 		mesecon.get_any_outputrules(node) or {}) |  | ||||||
| end | end | ||||||
|  |  | ||||||
| -- Receptors | -- Receptors | ||||||
| -- Nodes that can power mesecons | -- Nodes that can power mesecons | ||||||
| function mesecon.is_receptor_on(nodename) | function mesecon:is_receptor_on(nodename) | ||||||
| 	local receptor = mesecon.get_receptor(nodename) | 	local receptor = mesecon:get_receptor(nodename) | ||||||
| 	if receptor and receptor.state == mesecon.state.on then | 	if receptor and receptor.state == mesecon.state.on then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_receptor_off(nodename) | function mesecon:is_receptor_off(nodename) | ||||||
| 	local receptor = mesecon.get_receptor(nodename) | 	local receptor = mesecon:get_receptor(nodename) | ||||||
| 	if receptor and receptor.state == mesecon.state.off then | 	if receptor and receptor.state == mesecon.state.off then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_receptor(nodename) | function mesecon:is_receptor(nodename) | ||||||
| 	local receptor = mesecon.get_receptor(nodename) | 	local receptor = mesecon:get_receptor(nodename) | ||||||
| 	if receptor then | 	if receptor then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.receptor_get_rules(node) | function mesecon:receptor_get_rules(node) | ||||||
| 	local receptor = mesecon.get_receptor(node.name) | 	local receptor = mesecon:get_receptor(node.name) | ||||||
| 	if receptor then | 	if receptor then | ||||||
| 		local rules = receptor.rules | 		local rules = receptor.rules | ||||||
| 		if type(rules) == 'function' then | 		if type(rules) == 'function' then | ||||||
| @@ -143,32 +140,32 @@ end | |||||||
|  |  | ||||||
| -- Effectors | -- Effectors | ||||||
| -- Nodes that can be powered by mesecons | -- Nodes that can be powered by mesecons | ||||||
| function mesecon.is_effector_on(nodename) | function mesecon:is_effector_on(nodename) | ||||||
| 	local effector = mesecon.get_effector(nodename) | 	local effector = mesecon:get_effector(nodename) | ||||||
| 	if effector and effector.action_off then | 	if effector and effector.action_off then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_effector_off(nodename) | function mesecon:is_effector_off(nodename) | ||||||
| 	local effector = mesecon.get_effector(nodename) | 	local effector = mesecon:get_effector(nodename) | ||||||
| 	if effector and effector.action_on then | 	if effector and effector.action_on then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_effector(nodename) | function mesecon:is_effector(nodename) | ||||||
| 	local effector = mesecon.get_effector(nodename) | 	local effector = mesecon:get_effector(nodename) | ||||||
| 	if effector then | 	if effector then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.effector_get_rules(node) | function mesecon:effector_get_rules(node) | ||||||
| 	local effector = mesecon.get_effector(node.name) | 	local effector = mesecon:get_effector(node.name) | ||||||
| 	if effector then | 	if effector then | ||||||
| 		local rules = effector.rules | 		local rules = effector.rules | ||||||
| 		if type(rules) == 'function' then | 		if type(rules) == 'function' then | ||||||
| @@ -186,162 +183,159 @@ end | |||||||
|  |  | ||||||
| -- Activation: | -- Activation: | ||||||
| mesecon.queue:add_function("activate", function (pos, rulename) | mesecon.queue:add_function("activate", function (pos, rulename) | ||||||
| 	local node = mesecon.get_node_force(pos) | 	node = minetest.get_node(pos) | ||||||
| 	if not node then return end | 	effector = mesecon:get_effector(node.name) | ||||||
|  |  | ||||||
| 	local effector = mesecon.get_effector(node.name) |  | ||||||
|  |  | ||||||
| 	if effector and effector.action_on then | 	if effector and effector.action_on then | ||||||
| 		effector.action_on(pos, node, rulename) | 		effector.action_on(pos, node, rulename) | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
|  |  | ||||||
| function mesecon.activate(pos, node, rulename, depth) | function mesecon:activate(pos, node, rulename, recdepth) | ||||||
| 	if rulename == nil then | 	if rulename == nil then | ||||||
| 		for _,rule in ipairs(mesecon.effector_get_rules(node)) do | 		for _,rule in ipairs(mesecon:effector_get_rules(node)) do | ||||||
| 			mesecon.activate(pos, node, rule, depth + 1) | 			mesecon:activate(pos, node, rule, recdepth + 1) | ||||||
| 		end | 		end | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
| 	mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth) | 	mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / recdepth) | ||||||
| end | end | ||||||
|  |  | ||||||
|  |  | ||||||
| -- Deactivation | -- Deactivation | ||||||
| mesecon.queue:add_function("deactivate", function (pos, rulename) | mesecon.queue:add_function("deactivate", function (pos, rulename) | ||||||
| 	local node = mesecon.get_node_force(pos) | 	node = minetest.get_node(pos) | ||||||
| 	if not node then return end | 	effector = mesecon:get_effector(node.name) | ||||||
|  |  | ||||||
| 	local effector = mesecon.get_effector(node.name) |  | ||||||
|  |  | ||||||
| 	if effector and effector.action_off then | 	if effector and effector.action_off then | ||||||
| 		effector.action_off(pos, node, rulename) | 		effector.action_off(pos, node, rulename) | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
|  |  | ||||||
| function mesecon.deactivate(pos, node, rulename, depth) | function mesecon:deactivate(pos, node, rulename, recdepth) | ||||||
| 	if rulename == nil then | 	if rulename == nil then | ||||||
| 		for _,rule in ipairs(mesecon.effector_get_rules(node)) do | 		for _,rule in ipairs(mesecon:effector_get_rules(node)) do | ||||||
| 			mesecon.deactivate(pos, node, rule, depth + 1) | 			mesecon:deactivate(pos, node, rule, recdepth + 1) | ||||||
| 		end | 		end | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
| 	mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth) | 	mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / recdepth) | ||||||
| end | end | ||||||
|  |  | ||||||
|  |  | ||||||
| -- Change | -- Change | ||||||
| mesecon.queue:add_function("change", function (pos, rulename, changetype) | mesecon.queue:add_function("change", function (pos, rulename, changetype) | ||||||
| 	local node = mesecon.get_node_force(pos) | 	node = minetest.get_node(pos) | ||||||
| 	if not node then return end | 	effector = mesecon:get_effector(node.name) | ||||||
|  |  | ||||||
| 	local effector = mesecon.get_effector(node.name) |  | ||||||
|  |  | ||||||
| 	if effector and effector.action_change then | 	if effector and effector.action_change then | ||||||
| 		effector.action_change(pos, node, rulename, changetype) | 		effector.action_change(pos, node, rulename, changetype) | ||||||
| 	end | 	end | ||||||
| end) | end) | ||||||
|  |  | ||||||
| function mesecon.changesignal(pos, node, rulename, newstate, depth) | function mesecon:changesignal(pos, node, rulename, newstate, recdepth) | ||||||
| 	if rulename == nil then | 	if rulename == nil then | ||||||
| 		for _,rule in ipairs(mesecon.effector_get_rules(node)) do | 		for _,rule in ipairs(mesecon:effector_get_rules(node)) do | ||||||
| 			mesecon.changesignal(pos, node, rule, newstate, depth + 1) | 			mesecon:changesignal(pos, node, rule, newstate, recdepth + 1) | ||||||
| 		end | 		end | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	-- Include "change" in overwritecheck so that it cannot be overwritten | 	mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, rulename, 1 / recdepth) | ||||||
| 	-- by "active" / "deactivate" that will be called upon the node at the same time. | end | ||||||
| 	local overwritecheck = {"change", rulename} |  | ||||||
| 	mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth) | -- ######### | ||||||
|  | -- # Rules # "Database" for rulenames | ||||||
|  | -- ######### | ||||||
|  |  | ||||||
|  | function mesecon:add_rules(name, rules) | ||||||
|  | 	mesecon.rules[name] = rules | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function mesecon:get_rules(name) | ||||||
|  | 	return mesecon.rules[name] | ||||||
| end | end | ||||||
|  |  | ||||||
| -- Conductors | -- Conductors | ||||||
|  |  | ||||||
| function mesecon.is_conductor_on(node, rulename) | function mesecon:is_conductor_on(node, rulename) | ||||||
| 	if not node then return false end | 	local conductor = mesecon:get_conductor(node.name) | ||||||
|  |  | ||||||
| 	local conductor = mesecon.get_conductor(node.name) |  | ||||||
| 	if conductor then | 	if conductor then | ||||||
| 		if conductor.state then | 		if conductor.state then | ||||||
| 			return conductor.state == mesecon.state.on | 			return conductor.state == mesecon.state.on | ||||||
| 		end | 		end | ||||||
| 		if conductor.states then | 		if conductor.states then | ||||||
| 			if not rulename then | 			if not rulename then | ||||||
| 				return mesecon.getstate(node.name, conductor.states) ~= 1 | 				return mesecon:getstate(node.name, conductor.states) ~= 1 | ||||||
| 			end | 			end | ||||||
| 			local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node)) | 			local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node)) | ||||||
| 			local binstate = mesecon.getbinstate(node.name, conductor.states) | 			local binstate = mesecon:getbinstate(node.name, conductor.states) | ||||||
| 			return mesecon.get_bit(binstate, bit) | 			return mesecon:get_bit(binstate, bit) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_conductor_off(node, rulename) | function mesecon:is_conductor_off(node, rulename) | ||||||
| 	if not node then return false end | 	local conductor = mesecon:get_conductor(node.name) | ||||||
|  |  | ||||||
| 	local conductor = mesecon.get_conductor(node.name) |  | ||||||
| 	if conductor then | 	if conductor then | ||||||
| 		if conductor.state then | 		if conductor.state then | ||||||
| 			return conductor.state == mesecon.state.off | 			return conductor.state == mesecon.state.off | ||||||
| 		end | 		end | ||||||
| 		if conductor.states then | 		if conductor.states then | ||||||
| 			if not rulename then | 			if not rulename then | ||||||
| 				return mesecon.getstate(node.name, conductor.states) == 1 | 				return mesecon:getstate(node.name, conductor.states) == 1 | ||||||
| 			end | 			end | ||||||
| 			local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node)) | 			local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node)) | ||||||
| 			local binstate = mesecon.getbinstate(node.name, conductor.states) | 			local binstate = mesecon:getbinstate(node.name, conductor.states) | ||||||
| 			return not mesecon.get_bit(binstate, bit) | 			return not mesecon:get_bit(binstate, bit) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_conductor(nodename) | function mesecon:is_conductor(nodename) | ||||||
| 	local conductor = mesecon.get_conductor(nodename) | 	local conductor = mesecon:get_conductor(nodename) | ||||||
| 	if conductor then | 	if conductor then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.get_conductor_on(node_off, rulename) | function mesecon:get_conductor_on(node_off, rulename) | ||||||
| 	local conductor = mesecon.get_conductor(node_off.name) | 	local conductor = mesecon:get_conductor(node_off.name) | ||||||
| 	if conductor then | 	if conductor then | ||||||
| 		if conductor.onstate then | 		if conductor.onstate then | ||||||
| 			return conductor.onstate | 			return conductor.onstate | ||||||
| 		end | 		end | ||||||
| 		if conductor.states then | 		if conductor.states then | ||||||
| 			local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_off)) | 			local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_off)) | ||||||
| 			local binstate = mesecon.getbinstate(node_off.name, conductor.states) | 			local binstate = mesecon:getbinstate(node_off.name, conductor.states) | ||||||
| 			binstate = mesecon.set_bit(binstate, bit, "1") | 			binstate = mesecon:set_bit(binstate, bit, "1") | ||||||
| 			return conductor.states[tonumber(binstate,2)+1] | 			return conductor.states[tonumber(binstate,2)+1] | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	return offstate | 	return offstate | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.get_conductor_off(node_on, rulename) | function mesecon:get_conductor_off(node_on, rulename) | ||||||
| 	local conductor = mesecon.get_conductor(node_on.name) | 	local conductor = mesecon:get_conductor(node_on.name) | ||||||
| 	if conductor then | 	if conductor then | ||||||
| 		if conductor.offstate then | 		if conductor.offstate then | ||||||
| 			return conductor.offstate | 			return conductor.offstate | ||||||
| 		end | 		end | ||||||
| 		if conductor.states then | 		if conductor.states then | ||||||
| 			local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_on)) | 			local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_on)) | ||||||
| 			local binstate = mesecon.getbinstate(node_on.name, conductor.states) | 			local binstate = mesecon:getbinstate(node_on.name, conductor.states) | ||||||
| 			binstate = mesecon.set_bit(binstate, bit, "0") | 			binstate = mesecon:set_bit(binstate, bit, "0") | ||||||
| 			return conductor.states[tonumber(binstate,2)+1] | 			return conductor.states[tonumber(binstate,2)+1] | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	return onstate | 	return onstate | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.conductor_get_rules(node) | function mesecon:conductor_get_rules(node) | ||||||
| 	local conductor = mesecon.get_conductor(node.name) | 	local conductor = mesecon:get_conductor(node.name) | ||||||
| 	if conductor then | 	if conductor then | ||||||
| 		local rules = conductor.rules | 		local rules = conductor.rules | ||||||
| 		if type(rules) == 'function' then | 		if type(rules) == 'function' then | ||||||
| @@ -355,128 +349,126 @@ end | |||||||
|  |  | ||||||
| -- some more general high-level stuff | -- some more general high-level stuff | ||||||
|  |  | ||||||
| function mesecon.is_power_on(pos, rulename) | function mesecon:is_power_on(pos, rulename) | ||||||
| 	local node = mesecon.get_node_force(pos) | 	local node = minetest.get_node(pos) | ||||||
| 	if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then | 	if mesecon:is_conductor_on(node, rulename) or mesecon:is_receptor_on(node.name) then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_power_off(pos, rulename) | function mesecon:is_power_off(pos, rulename) | ||||||
| 	local node = mesecon.get_node_force(pos) | 	local node = minetest.get_node(pos) | ||||||
| 	if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then | 	if mesecon:is_conductor_off(node, rulename) or mesecon:is_receptor_off(node.name) then | ||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.turnon(pos, link) | function mesecon:turnon(pos, rulename, recdepth) | ||||||
| 	local frontiers = {{pos = pos, link = link}} | 	recdepth = recdepth or 2 | ||||||
|  | 	local node = minetest.get_node(pos) | ||||||
|  |  | ||||||
| 	local depth = 1 | 	if(node.name == "ignore") then | ||||||
| 	while frontiers[depth] do | 		-- try turning on later again | ||||||
| 		local f = frontiers[depth] | 		mesecon.queue:add_action( | ||||||
| 		local node = mesecon.get_node_force(f.pos) | 			pos, "turnon", {rulename, recdepth + 1}, nil, true) | ||||||
|  | 	end | ||||||
| 	 | 	 | ||||||
| 		-- area not loaded, postpone action | 	if mesecon:is_conductor_off(node, rulename) then | ||||||
| 		if not node then | 		local rules = mesecon:conductor_get_rules(node) | ||||||
| 			mesecon.queue:add_action(f.pos, "turnon", {link}, nil, true) |  | ||||||
| 		elseif mesecon.is_conductor_off(node, f.link) then |  | ||||||
| 			local rules = mesecon.conductor_get_rules(node) |  | ||||||
|  |  | ||||||
| 			minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link), | 		if not rulename then | ||||||
| 				param2 = node.param2}) | 			for _, rule in ipairs(mesecon:flattenrules(rules)) do | ||||||
|  | 				if mesecon:connected_to_receptor(pos, rule) then | ||||||
|  | 					mesecon:turnon(pos, rule, recdepth + 1) | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  | 			return | ||||||
|  | 		end | ||||||
|  |  | ||||||
| 			-- call turnon on neighbors: normal rules | 		minetest.swap_node(pos, {name = mesecon:get_conductor_on(node, rulename), param2 = node.param2}) | ||||||
| 			for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do |  | ||||||
| 				local np = vector.add(f.pos, r) |  | ||||||
|  |  | ||||||
| 				-- area not loaded, postpone action | 		for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do | ||||||
| 				if not mesecon.get_node_force(np) then | 			local np = mesecon:addPosRule(pos, rule) | ||||||
| 					mesecon.queue:add_action(np, "turnon", {rulename}, | 			if(minetest.get_node(np).name == "ignore") then | ||||||
| 						nil, true) | 				-- try turning on later again | ||||||
|  | 				mesecon.queue:add_action( | ||||||
|  | 					np, "turnon", {rulename, recdepth + 1}, nil, true) | ||||||
| 			else | 			else | ||||||
| 					local links = mesecon.rules_link_rule_all(f.pos, r) | 				local rulenames = mesecon:rules_link_rule_all(pos, rule) | ||||||
| 					for _, l in ipairs(links) do |  | ||||||
| 						table.insert(frontiers, {pos = np, link = l}) | 				for _, rulename in ipairs(rulenames) do | ||||||
|  | 					mesecon:turnon(np, rulename, recdepth + 1) | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 		elseif mesecon.is_effector(node.name) then | 	elseif mesecon:is_effector(node.name) then | ||||||
| 			mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth) | 		mesecon:changesignal(pos, node, rulename, mesecon.state.on, recdepth) | ||||||
| 			if mesecon.is_effector_off(node.name) then | 		if mesecon:is_effector_off(node.name) then | ||||||
| 				mesecon.activate(f.pos, node, f.link, depth) | 			mesecon:activate(pos, node, rulename, recdepth) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 		depth = depth + 1 |  | ||||||
| 	end |  | ||||||
| end | end | ||||||
|  |  | ||||||
| mesecon.queue:add_function("turnon", function (pos, rulename, recdepth) | mesecon.queue:add_function("turnon", function (pos, rulename, recdepth) | ||||||
| 	mesecon.turnon(pos, rulename, recdepth) | 	mesecon:turnon(pos, rulename, recdepth) | ||||||
| end) | end) | ||||||
|  |  | ||||||
| function mesecon.turnoff(pos, link) | function mesecon:turnoff(pos, rulename, recdepth) | ||||||
| 	local frontiers = {{pos = pos, link = link}} | 	recdepth = recdepth or 2 | ||||||
|  | 	local node = minetest.get_node(pos) | ||||||
|  |  | ||||||
| 	local depth = 1 | 	if(node.name == "ignore") then | ||||||
| 	while frontiers[depth] do | 		-- try turning on later again | ||||||
| 		local f = frontiers[depth] | 		mesecon.queue:add_action( | ||||||
| 		local node = mesecon.get_node_force(f.pos) | 			pos, "turnoff", {rulename, recdepth + 1}, nil, true) | ||||||
|  | 	end | ||||||
|  |  | ||||||
| 		-- area not loaded, postpone action | 	if mesecon:is_conductor_on(node, rulename) then | ||||||
| 		if not node then | 		local rules = mesecon:conductor_get_rules(node) | ||||||
| 			mesecon.queue:add_action(f.pos, "turnoff", {link}, nil, true) | 		minetest.swap_node(pos, {name = mesecon:get_conductor_off(node, rulename), param2 = node.param2}) | ||||||
| 		elseif mesecon.is_conductor_on(node, f.link) then |  | ||||||
| 			local rules = mesecon.conductor_get_rules(node) |  | ||||||
|  |  | ||||||
| 			minetest.swap_node(f.pos, {name = mesecon.get_conductor_off(node, f.link), | 		for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do | ||||||
| 				param2 = node.param2}) | 			local np = mesecon:addPosRule(pos, rule) | ||||||
|  | 			if(minetest.get_node(np).name == "ignore") then | ||||||
| 			-- call turnoff on neighbors: normal rules | 				-- try turning on later again | ||||||
| 			for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do | 				mesecon.queue:add_action( | ||||||
| 				local np = vector.add(f.pos, r) | 					np, "turnoff", {rulename, recdepth + 1}, nil, true) | ||||||
|  |  | ||||||
| 				-- area not loaded, postpone action |  | ||||||
| 				if not mesecon.get_node_force(np) then |  | ||||||
| 					mesecon.queue:add_action(np, "turnoff", {rulename}, |  | ||||||
| 						nil, true) |  | ||||||
| 			else | 			else | ||||||
| 					local links = mesecon.rules_link_rule_all(f.pos, r) | 				local rulenames = mesecon:rules_link_rule_all(pos, rule) | ||||||
| 					for _, l in ipairs(links) do |  | ||||||
| 						table.insert(frontiers, {pos = np, link = l}) | 				for _, rulename in ipairs(rulenames) do | ||||||
|  | 					mesecon:turnoff(np, rulename, recdepth + 1) | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 		elseif mesecon.is_effector(node.name) then | 	elseif mesecon:is_effector(node.name) then | ||||||
| 			mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth) | 		mesecon:changesignal(pos, node, rulename, mesecon.state.off, recdepth) | ||||||
| 			if mesecon.is_effector_on(node.name) and not mesecon.is_powered(f.pos) then | 		if mesecon:is_effector_on(node.name) | ||||||
| 				mesecon.deactivate(f.pos, node, f.link, depth) | 		and not mesecon:is_powered(pos) then | ||||||
|  | 			mesecon:deactivate(pos, node, rulename, recdepth + 1) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 		depth = depth + 1 |  | ||||||
| 	end |  | ||||||
| end | end | ||||||
|  |  | ||||||
| mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth) | mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth) | ||||||
| 	mesecon.turnoff(pos, rulename, recdepth) | 	mesecon:turnoff(pos, rulename, recdepth) | ||||||
| end) | end) | ||||||
|  |  | ||||||
|  |  | ||||||
| function mesecon.connected_to_receptor(pos, link) | function mesecon:connected_to_receptor(pos, rulename) | ||||||
| 	local node = mesecon.get_node_force(pos) | 	local node = minetest.get_node(pos) | ||||||
| 	if not node then return false end |  | ||||||
|  |  | ||||||
| 	-- Check if conductors around are connected | 	-- Check if conductors around are connected | ||||||
| 	local rules = mesecon.get_any_inputrules(node) | 	local rules = mesecon:get_any_inputrules(node) | ||||||
| 	if not rules then return false end | 	if not rules then return false end | ||||||
|  |  | ||||||
| 	for _, rule in ipairs(mesecon.rule2meta(link, rules)) do | 	for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do | ||||||
| 		local links = mesecon.rules_link_rule_all_inverted(pos, rule) | 		local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) | ||||||
| 		for _, l in ipairs(links) do | 		for _, rname in ipairs(rulenames) do | ||||||
| 			local np = vector.add(pos, l) | 			local np = mesecon:addPosRule(pos, rname) | ||||||
| 			if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then | 			if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rname)) then | ||||||
| 				return true | 				return true | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| @@ -485,189 +477,228 @@ function mesecon.connected_to_receptor(pos, link) | |||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.find_receptor_on(pos, link) | function mesecon:find_receptor_on(pos, checked, rulename) | ||||||
| 	local frontiers = {{pos = pos, link = link}} | 	local node = minetest.get_node(pos) | ||||||
| 	local checked = {} |  | ||||||
|  |  | ||||||
| 	-- List of positions that have been searched for onstate receptors | 	if mesecon:is_receptor_on(node.name) then | ||||||
| 	local depth = 1 | 		-- add current position to checked | ||||||
| 	while frontiers[depth] do | 		table.insert(checked, {x=pos.x, y=pos.y, z=pos.z}) | ||||||
| 		local f = frontiers[depth] | 		return true | ||||||
| 		local node = mesecon.get_node_force(f.pos) | 	end | ||||||
|  |  | ||||||
| 		if not node then return false end | 	if mesecon:is_conductor(node.name) then | ||||||
| 		if mesecon.is_receptor_on(node.name) then return true end | 		local rules = mesecon:conductor_get_rules(node) | ||||||
| 		if mesecon.is_conductor_on(node, f.link) then | 		local metaindex = mesecon:rule2metaindex(rulename, rules) | ||||||
| 			local rules = mesecon.conductor_get_rules(node) | 		-- find out if node has already been checked (to prevent from endless loop) | ||||||
|  | 		for _, cp in ipairs(checked) do | ||||||
| 			-- call turnoff on neighbors: normal rules | 			if mesecon:cmpPos(cp, pos) and cp.metaindex == metaindex then | ||||||
| 			for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do | 				return false, checked | ||||||
| 				local np = vector.add(f.pos, r) | 			end | ||||||
|  | 		end | ||||||
| 				local links = mesecon.rules_link_rule_all_inverted(f.pos, r) | 		-- add current position to checked | ||||||
| 				for _, l in ipairs(links) do | 		table.insert(checked, {x=pos.x, y=pos.y, z=pos.z, metaindex = metaindex}) | ||||||
| 					local checkedstring = np.x..np.y..np.z..l.x..l.y..l.z | 		for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do | ||||||
| 					if not checked[checkedstring] then | 			local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) | ||||||
| 						table.insert(frontiers, {pos = np, link = l}) | 			for _, rname in ipairs(rulenames) do | ||||||
| 						checked[checkedstring] = true | 				local np = mesecon:addPosRule(pos, rname) | ||||||
|  | 				if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rname)) then | ||||||
|  | 					return true | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
|  | 	else | ||||||
|  | 		-- find out if node has already been checked (to prevent from endless loop) | ||||||
|  | 		for _, cp in ipairs(checked) do | ||||||
|  | 			if mesecon:cmpPos(cp, pos) then | ||||||
|  | 				return false, checked | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 		table.insert(checked, {x=pos.x, y=pos.y, z=pos.z}) | ||||||
|  | 	end | ||||||
|  |  | ||||||
| 		end | 	return false | ||||||
| 		depth = depth + 1 |  | ||||||
| 	end |  | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule | function mesecon:rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule | ||||||
| 	local outputnode = mesecon.get_node_force(output) | 	local outputnode = minetest.get_node(output) | ||||||
| 	local inputnode = mesecon.get_node_force(input) | 	local inputnode = minetest.get_node(input) | ||||||
|  | 	local outputrules = dug_outputrules or mesecon:get_any_outputrules (outputnode) | ||||||
| 	local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode) | 	local inputrules = mesecon:get_any_inputrules (inputnode) | ||||||
| 	local inputrules = mesecon.get_any_inputrules (inputnode) |  | ||||||
| 	if not outputrules or not inputrules then | 	if not outputrules or not inputrules then | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do | 	for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do | ||||||
| 		-- Check if output sends to input | 		-- Check if output sends to input | ||||||
| 		if vector.equals(vector.add(output, outputrule), input) then | 		if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then | ||||||
| 			for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do | 			for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do | ||||||
| 				-- Check if input accepts from output | 				-- Check if input accepts from output | ||||||
| 				if  vector.equals(vector.add(input, inputrule), output) then | 				if  mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then | ||||||
|  | 					if inputrule.sx == nil or outputrule.sx == nil or mesecon:cmpSpecial(inputrule, outputrule) then | ||||||
| 						return true, inputrule | 						return true, inputrule | ||||||
| 					end | 					end | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
|  | 	end | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rules_link_rule_all(output, rule) | function mesecon:rules_link_rule_all(output, rule) --output/input are positions (outputrules optional, used if node has been dug), second return value: affected input rules | ||||||
| 	local input = vector.add(output, rule) | 	local input = mesecon:addPosRule(output, rule) | ||||||
| 	local inputnode = mesecon.get_node_force(input) | 	local inputnode = minetest.get_node(input) | ||||||
| 	local inputrules = mesecon.get_any_inputrules (inputnode) | 	local inputrules = mesecon:get_any_inputrules (inputnode) | ||||||
| 	if not inputrules then | 	if not inputrules then | ||||||
| 		return {} | 		return {} | ||||||
| 	end | 	end | ||||||
| 	local rules = {} | 	local rules = {} | ||||||
| 	 | 	 | ||||||
| 	for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do | 	for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do | ||||||
| 		-- Check if input accepts from output | 		-- Check if input accepts from output | ||||||
| 		if  vector.equals(vector.add(input, inputrule), output) then | 		if  mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then | ||||||
| 			table.insert(rules, inputrule) | 			if inputrule.sx == nil or rule.sx == nil or mesecon:cmpSpecial(inputrule, rule) then | ||||||
|  | 				rules[#rules+1] = inputrule | ||||||
|  | 			end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	return rules | 	return rules | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rules_link_rule_all_inverted(input, rule) | function mesecon:rules_link_rule_all_inverted(input, rule) | ||||||
| 	--local irule = mesecon.invertRule(rule) | 	--local irule = mesecon:invertRule(rule) | ||||||
| 	local output = vector.add(input, rule) | 	local output = mesecon:addPosRule(input, rule) | ||||||
| 	local outputnode = mesecon.get_node_force(output) | 	local outputnode = minetest.get_node(output) | ||||||
| 	local outputrules = mesecon.get_any_outputrules (outputnode) | 	local outputrules = mesecon:get_any_outputrules (outputnode) | ||||||
| 	if not outputrules then | 	if not outputrules then | ||||||
| 		return {} | 		return {} | ||||||
| 	end | 	end | ||||||
| 	local rules = {} | 	local rules = {} | ||||||
| 	 | 	 | ||||||
| 	for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do | 	for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do | ||||||
| 		if  vector.equals(vector.add(output, outputrule), input) then | 		if  mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then | ||||||
| 			table.insert(rules, mesecon.invertRule(outputrule)) | 			if outputrule.sx == nil or rule.sx == nil or mesecon:cmpSpecial(outputrule, rule) then | ||||||
|  | 				rules[#rules+1] = mesecon:invertRule(outputrule) | ||||||
|  | 			end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	return rules | 	return rules | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rules_link_anydir(pos1, pos2) | function mesecon:rules_link_anydir(pos1, pos2) | ||||||
| 	return mesecon.rules_link(pos1, pos2) or mesecon.rules_link(pos2, pos1) | 	return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1) | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.is_powered(pos, rule) | function mesecon:is_powered(pos, rule) | ||||||
| 	local node = mesecon.get_node_force(pos) | 	local node = minetest.get_node(pos) | ||||||
| 	local rules = mesecon.get_any_inputrules(node) | 	local rules = mesecon:get_any_inputrules(node) | ||||||
| 	if not rules then return false end | 	if not rules then return false end | ||||||
|  |  | ||||||
| 	-- List of nodes that send out power to pos |  | ||||||
| 	local sourcepos = {} |  | ||||||
|  |  | ||||||
| 	if not rule then | 	if not rule then | ||||||
| 		for _, rule in ipairs(mesecon.flattenrules(rules)) do | 		for _, rule in ipairs(mesecon:flattenrules(rules)) do | ||||||
| 			local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) | 			local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) | ||||||
| 			for _, rname in ipairs(rulenames) do | 			for _, rname in ipairs(rulenames) do | ||||||
| 				local np = vector.add(pos, rname) | 				local np = mesecon:addPosRule(pos, rname) | ||||||
| 				local nn = mesecon.get_node_force(np) | 				local nn = minetest.get_node(np) | ||||||
|  | 				if (mesecon:is_conductor_on (nn, mesecon:invertRule(rname)) or mesecon:is_receptor_on (nn.name)) then | ||||||
| 				if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname)) | 					return true | ||||||
| 				or mesecon.is_receptor_on(nn.name)) then |  | ||||||
| 					table.insert(sourcepos, np) |  | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 	else | 	else | ||||||
| 		local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) | 		local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) | ||||||
| 		for _, rname in ipairs(rulenames) do | 		for _, rname in ipairs(rulenames) do | ||||||
| 			local np = vector.add(pos, rname) | 			local np = mesecon:addPosRule(pos, rname) | ||||||
| 			local nn = mesecon.get_node_force(np) | 			local nn = minetest.get_node(np) | ||||||
| 			if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) | 			if (mesecon:is_conductor_on (nn, mesecon:invertRule(rname)) or mesecon:is_receptor_on (nn.name)) then | ||||||
| 			or mesecon.is_receptor_on (nn.name)) then | 				return true | ||||||
| 				table.insert(sourcepos, np) |  | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	 | 	 | ||||||
| 	-- Return FALSE if not powered, return list of sources if is powered | 	return false | ||||||
| 	if (#sourcepos == 0) then return false |  | ||||||
| 	else return sourcepos end |  | ||||||
| end | end | ||||||
|  |  | ||||||
| --Rules rotation Functions: | --Rules rotation Functions: | ||||||
| function mesecon.rotate_rules_right(rules) | function mesecon:rotate_rules_right(rules) | ||||||
| 	local nr = {} | 	local nr = {} | ||||||
| 	for i, rule in ipairs(rules) do | 	for i, rule in ipairs(rules) do | ||||||
|  | 		if rule.sx then | ||||||
| 			table.insert(nr, { | 			table.insert(nr, { | ||||||
| 				x = -rule.z,  | 				x = -rule.z,  | ||||||
| 				y =  rule.y,  | 				y =  rule.y,  | ||||||
| 				z =  rule.x, | 				z =  rule.x, | ||||||
| 			name = rule.name}) | 				sx = -rule.sz,  | ||||||
|  | 				sy =  rule.sy,  | ||||||
|  | 				sz =  rule.sx}) | ||||||
|  | 		else | ||||||
|  | 			table.insert(nr, { | ||||||
|  | 				x = -rule.z,  | ||||||
|  | 				y =  rule.y,  | ||||||
|  | 				z =  rule.x}) | ||||||
|  | 		end | ||||||
| 	end | 	end | ||||||
| 	return nr | 	return nr | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rotate_rules_left(rules) | function mesecon:rotate_rules_left(rules) | ||||||
| 	local nr = {} | 	local nr = {} | ||||||
| 	for i, rule in ipairs(rules) do | 	for i, rule in ipairs(rules) do | ||||||
|  | 		if rule.sx then | ||||||
| 			table.insert(nr, { | 			table.insert(nr, { | ||||||
| 				x =  rule.z,  | 				x =  rule.z,  | ||||||
| 				y =  rule.y,  | 				y =  rule.y,  | ||||||
| 				z = -rule.x, | 				z = -rule.x, | ||||||
| 			name = rule.name}) | 				sx =  rule.sz,  | ||||||
|  | 				sy =  rule.sy,  | ||||||
|  | 				sz = -rule.sx}) | ||||||
|  | 		else | ||||||
|  | 			table.insert(nr, { | ||||||
|  | 				x =  rule.z,  | ||||||
|  | 				y =  rule.y,  | ||||||
|  | 				z = -rule.x}) | ||||||
|  | 		end | ||||||
| 	end | 	end | ||||||
| 	return nr | 	return nr | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rotate_rules_down(rules) | function mesecon:rotate_rules_down(rules) | ||||||
| 	local nr = {} | 	local nr = {} | ||||||
| 	for i, rule in ipairs(rules) do | 	for i, rule in ipairs(rules) do | ||||||
|  | 		if rule.sx then | ||||||
| 			table.insert(nr, { | 			table.insert(nr, { | ||||||
| 				x = -rule.y,  | 				x = -rule.y,  | ||||||
| 				y =  rule.x,  | 				y =  rule.x,  | ||||||
| 				z =  rule.z, | 				z =  rule.z, | ||||||
| 			name = rule.name}) | 				sx = -rule.sy,  | ||||||
|  | 				sy =  rule.sx,  | ||||||
|  | 				sz =  rule.sz}) | ||||||
|  | 		else | ||||||
|  | 			table.insert(nr, { | ||||||
|  | 				x = -rule.y,  | ||||||
|  | 				y =  rule.x,  | ||||||
|  | 				z =  rule.z}) | ||||||
|  | 		end | ||||||
| 	end | 	end | ||||||
| 	return nr | 	return nr | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rotate_rules_up(rules) | function mesecon:rotate_rules_up(rules) | ||||||
| 	local nr = {} | 	local nr = {} | ||||||
| 	for i, rule in ipairs(rules) do | 	for i, rule in ipairs(rules) do | ||||||
|  | 		if rule.sx then | ||||||
| 			table.insert(nr, { | 			table.insert(nr, { | ||||||
| 				x =  rule.y,  | 				x =  rule.y,  | ||||||
| 				y = -rule.x,  | 				y = -rule.x,  | ||||||
| 				z =  rule.z, | 				z =  rule.z, | ||||||
| 			name = rule.name}) | 				sx =  rule.sy,  | ||||||
|  | 				sy = -rule.sx,  | ||||||
|  | 				sz =  rule.sz}) | ||||||
|  | 		else | ||||||
|  | 			table.insert(nr, { | ||||||
|  | 				x =  rule.y,  | ||||||
|  | 				y = -rule.x,  | ||||||
|  | 				z =  rule.z}) | ||||||
|  | 		end | ||||||
| 	end | 	end | ||||||
| 	return nr | 	return nr | ||||||
| end | end | ||||||
|   | |||||||
| @@ -1,30 +1,32 @@ | |||||||
| -- Ugly hack to prevent breaking compatibility with other mods | minetest.swap_node = minetest.swap_node or function(pos, node) | ||||||
| -- Just remove the following two functions to delete the hack, to be done when other mods have updated | 	local data = minetest.get_meta(pos):to_table() | ||||||
| function mesecon.receptor_on(self, pos, rules) | 	minetest.add_node(pos, node) | ||||||
| 	if (self.receptor_on) then | 	minetest.get_meta(pos):from_table(data) | ||||||
| 		print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_on.") |  | ||||||
| 		print("[Mesecons]          If you are the programmer of this mod, please update it ") |  | ||||||
| 		print("[Mesecons]          to use mesecon.receptor_on instead. mesecon:* is deprecated") |  | ||||||
| 		print("[Mesecons]          Otherwise, please make sure you're running the latest version") |  | ||||||
| 		print("[Mesecons]          of that mod and inform the mod creator.") |  | ||||||
| 	else |  | ||||||
| 		rules = pos |  | ||||||
| 		pos = self |  | ||||||
| 	end |  | ||||||
| 	mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) |  | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.receptor_off(self, pos, rules) | local rules = {} | ||||||
| 	if (self.receptor_off) then | rules.a = {x = -1, y = 0, z =  0, name="A"} | ||||||
| 		print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_off.") | rules.b = {x =  0, y = 0, z =  1, name="B"} | ||||||
| 		print("[Mesecons]          If you are the programmer of this mod, please update it ") | rules.c = {x =  1, y = 0, z =  0, name="C"} | ||||||
| 		print("[Mesecons]          to use mesecon.receptor_off instead. mesecon:* is deprecated") | rules.d = {x =  0, y = 0, z = -1, name="D"} | ||||||
| 		print("[Mesecons]          Otherwise, please make sure you're running the latest version") |  | ||||||
| 		print("[Mesecons]          of that mod and inform the mod creator.") |  | ||||||
| 	else |  | ||||||
| 		rules = pos |  | ||||||
| 		pos = self |  | ||||||
| 	end |  | ||||||
| 	mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) |  | ||||||
| end |  | ||||||
|  |  | ||||||
|  | function legacy_update_ports(pos) | ||||||
|  | 	local meta = minetest.get_meta(pos) | ||||||
|  | 	L = { | ||||||
|  | 		a = mesecon:is_power_on(mesecon:addPosRule(pos, rules.a), | ||||||
|  | 			mesecon:invertRule(rules.a)) and | ||||||
|  | 			mesecon:rules_link(mesecon:addPosRule(pos, rules.a), pos), | ||||||
|  | 		b = mesecon:is_power_on(mesecon:addPosRule(pos, rules.b), | ||||||
|  | 			mesecon:invertRule(rules.b)) and | ||||||
|  | 			mesecon:rules_link(mesecon:addPosRule(pos, rules.b), pos), | ||||||
|  | 		c = mesecon:is_power_on(mesecon:addPosRule(pos, rules.c), | ||||||
|  | 			mesecon:invertRule(rules.c)) and | ||||||
|  | 			mesecon:rules_link(mesecon:addPosRule(pos, rules.c), pos), | ||||||
|  | 		d = mesecon:is_power_on(mesecon:addPosRule(pos, rules.d), | ||||||
|  | 			mesecon:invertRule(rules.d)) and | ||||||
|  | 			mesecon:rules_link(mesecon:addPosRule(pos, rules.d), pos), | ||||||
|  | 	} | ||||||
|  | 	local n = (L.a and 1 or 0) + (L.b and 2 or 0) + (L.c and 4 or 0) + (L.d and 8 or 0) + 1 | ||||||
|  | 	meta:set_int("real_portstates", n) | ||||||
|  | 	return L | ||||||
|  | end | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ minetest.register_node("mesecons:mesecon_on", { | |||||||
| 	}, | 	}, | ||||||
| 	groups = {dig_immediate=3, not_in_creaive_inventory=1, mesecon=1}, | 	groups = {dig_immediate=3, not_in_creaive_inventory=1, mesecon=1}, | ||||||
| 	drop = "mesecons:mesecon_off 1", | 	drop = "mesecons:mesecon_off 1", | ||||||
| 	light_source = default.LIGHT_MAX-11, | 	light_source = LIGHT_MAX-11, | ||||||
| 	mesecons = {conductor={ | 	mesecons = {conductor={ | ||||||
| 		state = mesecon.state.on, | 		state = mesecon.state.on, | ||||||
| 		offstate = "mesecons:mesecon_off" | 		offstate = "mesecons:mesecon_off" | ||||||
|   | |||||||
| @@ -15,8 +15,6 @@ mesecon.rules.default = | |||||||
|  {x=0,  y=1,  z=-1}, |  {x=0,  y=1,  z=-1}, | ||||||
|  {x=0,  y=-1, z=-1}} |  {x=0,  y=-1, z=-1}} | ||||||
|  |  | ||||||
| mesecon.rules.pplate = mesecon.mergetable(mesecon.rules.default, {{x=0, y=-2, z=0}}) |  | ||||||
|  |  | ||||||
| mesecon.rules.buttonlike = | mesecon.rules.buttonlike = | ||||||
| {{x = 1,  y = 0, z = 0}, | {{x = 1,  y = 0, z = 0}, | ||||||
|  {x = 1,  y = 1, z = 0}, |  {x = 1,  y = 1, z = 0}, | ||||||
| @@ -31,22 +29,14 @@ mesecon.rules.flat = | |||||||
|  {x = 0, y = 0, z = 1}, |  {x = 0, y = 0, z = 1}, | ||||||
|  {x = 0, y = 0, z =-1}} |  {x = 0, y = 0, z =-1}} | ||||||
|   |   | ||||||
| mesecon.rules.alldirs = |  | ||||||
| {{x= 1, y= 0,  z= 0}, |  | ||||||
|  {x=-1, y= 0,  z= 0}, |  | ||||||
|  {x= 0, y= 1,  z= 0}, |  | ||||||
|  {x= 0, y=-1,  z= 0}, |  | ||||||
|  {x= 0, y= 0,  z= 1}, |  | ||||||
|  {x= 0, y= 0,  z=-1}} |  | ||||||
|  |  | ||||||
| mesecon.rules.buttonlike_get = function(node) | mesecon.rules.buttonlike_get = function(node) | ||||||
| 	local rules = mesecon.rules.buttonlike | 	local rules = mesecon.rules.buttonlike | ||||||
| 	if node.param2 == 2 then | 	if node.param2 == 2 then | ||||||
| 		rules=mesecon.rotate_rules_left(rules) | 		rules=mesecon:rotate_rules_left(rules) | ||||||
| 	elseif node.param2 == 3 then | 	elseif node.param2 == 3 then | ||||||
| 		rules=mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) | 		rules=mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) | ||||||
| 	elseif node.param2 == 0 then | 	elseif node.param2 == 0 then | ||||||
| 		rules=mesecon.rotate_rules_right(rules) | 		rules=mesecon:rotate_rules_right(rules) | ||||||
| 	end | 	end | ||||||
| 	return rules | 	return rules | ||||||
| end | end | ||||||
|   | |||||||
| @@ -1,68 +1,44 @@ | |||||||
| -- Dig and place services | -- Dig and place services | ||||||
|  |  | ||||||
| mesecon.on_placenode = function (pos, node) | mesecon.on_placenode = function (pos, node) | ||||||
| 	mesecon.update_autoconnect(pos, node) |  | ||||||
|  |  | ||||||
| 	-- Receptors: Send on signal when active | 	-- Receptors: Send on signal when active | ||||||
| 	if mesecon.is_receptor_on(node.name) then | 	if mesecon:is_receptor_on(node.name) then | ||||||
| 		mesecon.receptor_on(pos, mesecon.receptor_get_rules(node)) | 		mesecon:receptor_on(pos, mesecon:receptor_get_rules(node)) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	-- Conductors: Send turnon signal when powered or replace by respective offstate conductor | 	-- Conductors: Send turnon signal when powered or replace by respective offstate conductor | ||||||
| 	-- if placed conductor is an onstate one | 	-- if placed conductor is an onstate one | ||||||
| 	if mesecon.is_conductor(node.name) then | 	if mesecon:is_conductor(node.name) then | ||||||
| 		local sources = mesecon.is_powered(pos) | 		if mesecon:is_powered(pos) then | ||||||
| 		if sources then |  | ||||||
| 			-- also call receptor_on if itself is powered already, so that neighboring | 			-- also call receptor_on if itself is powered already, so that neighboring | ||||||
| 			-- conductors will be activated (when pushing an on-conductor with a piston) | 			-- conductors will be activated (when pushing an on-conductor with a piston) | ||||||
| 			for _, s in ipairs(sources) do | 			mesecon:turnon (pos) | ||||||
| 				local rule = vector.subtract(pos, s) | 			mesecon:receptor_on (pos, mesecon:conductor_get_rules(node)) | ||||||
| 				mesecon.turnon(pos, rule) | 		elseif mesecon:is_conductor_off(node.name) then | ||||||
| 			end | 			minetest.swap_node(pos, {name = mesecon:get_conductor_off(node)}) | ||||||
| 			--mesecon.receptor_on (pos, mesecon.conductor_get_rules(node)) |  | ||||||
| 		elseif mesecon.is_conductor_on(node) then |  | ||||||
| 			minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)}) |  | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	-- Effectors: Send changesignal and activate or deactivate | 	-- Effectors: Send changesignal and activate or deactivate | ||||||
| 	if mesecon.is_effector(node.name) then | 	if mesecon:is_effector(node.name) then | ||||||
| 		local powered_rules = {} | 		if mesecon:is_powered(pos) then | ||||||
| 		local unpowered_rules = {} | 			mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on", 1) | ||||||
|  | 			mesecon:activate(pos, node, nil, 1) | ||||||
| 		-- for each input rule, check if powered |  | ||||||
| 		for _, r in ipairs(mesecon.effector_get_rules(node)) do |  | ||||||
| 			local powered = mesecon.is_powered(pos, r) |  | ||||||
| 			if powered then table.insert(powered_rules, r) |  | ||||||
| 			else table.insert(unpowered_rules, r) end |  | ||||||
|  |  | ||||||
| 			local state = powered and mesecon.state.on or mesecon.state.off |  | ||||||
| 			mesecon.changesignal(pos, node, r, state, 1) |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		if (#powered_rules > 0) then |  | ||||||
| 			for _, r in ipairs(powered_rules) do |  | ||||||
| 				mesecon.activate(pos, node, r, 1) |  | ||||||
| 			end |  | ||||||
| 		else | 		else | ||||||
| 			for _, r in ipairs(unpowered_rules) do | 			mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "off", 1) | ||||||
| 				mesecon.deactivate(pos, node, r, 1) | 			mesecon:deactivate(pos, node, nil, 1) | ||||||
| 			end |  | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| mesecon.on_dignode = function (pos, node) | mesecon.on_dignode = function (pos, node) | ||||||
| 	if mesecon.is_conductor_on(node) then | 	if mesecon:is_conductor_on(node) then | ||||||
| 		mesecon.receptor_off(pos, mesecon.conductor_get_rules(node)) | 		mesecon:receptor_off(pos, mesecon:conductor_get_rules(node)) | ||||||
| 	elseif mesecon.is_receptor_on(node.name) then | 	elseif mesecon:is_receptor_on(node.name) then | ||||||
| 		mesecon.receptor_off(pos, mesecon.receptor_get_rules(node)) | 		mesecon:receptor_off(pos, mesecon:receptor_get_rules(node)) | ||||||
| 	end | 	end | ||||||
| 	mesecon.queue:add_action(pos, "update_autoconnect", {node}) |  | ||||||
| end | end | ||||||
|  |  | ||||||
| mesecon.queue:add_function("update_autoconnect", mesecon.update_autoconnect) |  | ||||||
|  |  | ||||||
| minetest.register_on_placenode(mesecon.on_placenode) | minetest.register_on_placenode(mesecon.on_placenode) | ||||||
| minetest.register_on_dignode(mesecon.on_dignode) | minetest.register_on_dignode(mesecon.on_dignode) | ||||||
|  |  | ||||||
| @@ -76,7 +52,7 @@ mesecon.do_overheat = function(pos) | |||||||
| 	heat = heat + 1 | 	heat = heat + 1 | ||||||
| 	meta:set_int("heat", heat) | 	meta:set_int("heat", heat) | ||||||
|  |  | ||||||
| 	if heat < mesecon.setting("overheat_max", 20) then | 	if heat < OVERHEAT_MAX then | ||||||
| 		mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0) | 		mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0) | ||||||
| 	else | 	else | ||||||
| 		return true | 		return true | ||||||
| @@ -87,6 +63,10 @@ end | |||||||
|  |  | ||||||
|  |  | ||||||
| mesecon.queue:add_function("cooldown", function (pos) | mesecon.queue:add_function("cooldown", function (pos) | ||||||
|  | 	if minetest.get_item_group(minetest.get_node(pos).name, "overheat") == 0 then | ||||||
|  | 		return -- node has been moved, this one does not use overheating - ignore | ||||||
|  | 	end | ||||||
|  |  | ||||||
| 	local meta = minetest.get_meta(pos) | 	local meta = minetest.get_meta(pos) | ||||||
| 	local heat = meta:get_int("heat") | 	local heat = meta:get_int("heat") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,15 +1,12 @@ | |||||||
| -- SETTINGS | -- SETTINGS | ||||||
| function mesecon.setting(setting, default) | BLINKY_PLANT_INTERVAL = 3 | ||||||
| 	if type(default) == "boolean" then | NEW_STYLE_WIRES  = true  	-- true = new nodebox wires, false = old raillike wires | ||||||
| 		local read = minetest.setting_getbool("mesecon."..setting) | PRESSURE_PLATE_INTERVAL = 0.1 | ||||||
| 		if read == nil then | OBJECT_DETECTOR_RADIUS = 6 | ||||||
| 			return default | PISTON_MAXIMUM_PUSH = 15 | ||||||
| 		else | MOVESTONE_MAXIMUM_PUSH = 100 | ||||||
| 			return read | MESECONS_RESUMETIME = 4		-- time to wait when starting the server before | ||||||
| 		end | 				-- processing the ActionQueue, don't set this too low | ||||||
| 	elseif type(default) == "string" then | OVERHEAT_MAX = 20		-- maximum heat of any component that directly sends an output | ||||||
| 		return minetest.setting_get("mesecon."..setting) or default | 				-- signal when the input changes (e.g. luacontroller, gates) | ||||||
| 	elseif type(default) == "number" then | 				-- Unit: actions per second, checks are every 1 second | ||||||
| 		return tonumber(minetest.setting_get("mesecon."..setting) or default) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|   | |||||||
| Before Width: | Height: | Size: 592 B After Width: | Height: | Size: 592 B | 
| Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 487 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_crossing_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 341 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_crossing_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 340 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_curved_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 307 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_curved_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 307 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_inverter_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 743 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_inverter_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 725 B | 
| Before Width: | Height: | Size: 204 B After Width: | Height: | Size: 204 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 196 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_plug.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 713 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_socket_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 751 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_socket_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 737 B | 
| Before Width: | Height: | Size: 598 B After Width: | Height: | Size: 598 B | 
| Before Width: | Height: | Size: 692 B After Width: | Height: | Size: 692 B | 
| Before Width: | Height: | Size: 553 B After Width: | Height: | Size: 553 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_t_junction_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 330 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/jeija_mesecon_t_junction_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 319 B | 
| Before Width: | Height: | Size: 867 B After Width: | Height: | Size: 867 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/wires_bump_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 347 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/wires_bump_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 386 B | 
| Before Width: | Height: | Size: 465 B After Width: | Height: | Size: 465 B | 
| Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 464 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/wires_inv.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 167 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/wires_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 454 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/wires_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 492 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/wires_vertical_off.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 373 B | 
							
								
								
									
										
											BIN
										
									
								
								mesecons/textures/wires_vertical_on.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 396 B | 
| @@ -1,12 +1,24 @@ | |||||||
| function mesecon.move_node(pos, newpos) | function mesecon:move_node(pos, newpos) | ||||||
| 	local node = minetest.get_node(pos) | 	local node = minetest.get_node(pos) | ||||||
| 	local meta = minetest.get_meta(pos):to_table() | 	local meta = minetest.get_meta(pos):to_table() | ||||||
| 	minetest.remove_node(pos) | 	minetest.remove_node(pos) | ||||||
| 	minetest.set_node(newpos, node) | 	minetest.add_node(newpos, node) | ||||||
| 	minetest.get_meta(pos):from_table(meta) | 	minetest.get_meta(pos):from_table(meta) | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.flattenrules(allrules) | --[[ new functions: | ||||||
|  | mesecon:flattenrules(allrules) | ||||||
|  | mesecon:rule2bit(findrule, allrules) | ||||||
|  | mesecon:rule2meta(findrule, allrules) | ||||||
|  | dec2bin(n) | ||||||
|  | mesecon:getstate(nodename, states) | ||||||
|  | mesecon:getbinstate(nodename, states) | ||||||
|  | mesecon:get_bit(binary, bit) | ||||||
|  | mesecon:set_bit(binary, bit, value) | ||||||
|  | mesecon:invertRule(r) | ||||||
|  | --]] | ||||||
|  |  | ||||||
|  | function mesecon:flattenrules(allrules) | ||||||
| --[[ | --[[ | ||||||
| 	{ | 	{ | ||||||
| 		{ | 		{ | ||||||
| @@ -41,7 +53,7 @@ function mesecon.flattenrules(allrules) | |||||||
| --]] | --]] | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rule2bit(findrule, allrules) | function mesecon:rule2bit(findrule, allrules) | ||||||
| 	--get the bit of the metarule the rule is in, or bit 1 | 	--get the bit of the metarule the rule is in, or bit 1 | ||||||
| 	if (allrules[1] and | 	if (allrules[1] and | ||||||
| 	    allrules[1].x) or | 	    allrules[1].x) or | ||||||
| @@ -50,36 +62,35 @@ function mesecon.rule2bit(findrule, allrules) | |||||||
| 	end | 	end | ||||||
| 	for m,metarule in ipairs( allrules) do | 	for m,metarule in ipairs( allrules) do | ||||||
| 	for _,    rule in ipairs(metarule ) do | 	for _,    rule in ipairs(metarule ) do | ||||||
| 		if vector.equals(findrule, rule) then | 		if mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then | ||||||
| 			return m | 			return m | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rule2metaindex(findrule, allrules) | function mesecon:rule2metaindex(findrule, allrules) | ||||||
| 	--get the metarule the rule is in, or allrules | 	--get the metarule the rule is in, or allrules | ||||||
|  |  | ||||||
| 	if allrules[1].x then | 	if allrules[1].x then | ||||||
| 		return nil | 		return nil | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	if not(findrule) then | 	if not(findrule) then | ||||||
| 		return mesecon.flattenrules(allrules) | 		return mesecon:flattenrules(allrules) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	for m, metarule in ipairs( allrules) do | 	for m, metarule in ipairs( allrules) do | ||||||
| 	for _,     rule in ipairs(metarule ) do | 	for _,     rule in ipairs(metarule ) do | ||||||
| 		if vector.equals(findrule, rule) then | 		if mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then | ||||||
| 			return m | 			return m | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.rule2meta(findrule, allrules) | function mesecon:rule2meta(findrule, allrules) | ||||||
| 	if #allrules == 0 then return {} end | 	local index = mesecon:rule2metaindex(findrule, allrules) | ||||||
|  |  | ||||||
| 	local index = mesecon.rule2metaindex(findrule, allrules) |  | ||||||
| 	if index == nil then | 	if index == nil then | ||||||
| 		if allrules[1].x then | 		if allrules[1].x then | ||||||
| 			return allrules | 			return allrules | ||||||
| @@ -90,16 +101,25 @@ function mesecon.rule2meta(findrule, allrules) | |||||||
| 	return allrules[index] | 	return allrules[index] | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.dec2bin(n) | if convert_base then | ||||||
|  | 	print( | ||||||
|  | 		"base2dec is tonumber(num,base1)\n".. | ||||||
|  | 		"commonlib needs dec2base(num,base2)\n".. | ||||||
|  | 		"and it needs base2base(num,base1,base2),\n".. | ||||||
|  | 		"which is dec2base(tonumber(num,base1),base2)" | ||||||
|  | 	) | ||||||
|  | else | ||||||
|  | 	function dec2bin(n) | ||||||
| 		local x, y = math.floor(n / 2), n % 2 | 		local x, y = math.floor(n / 2), n % 2 | ||||||
| 		if (n > 1) then | 		if (n > 1) then | ||||||
| 		return mesecon.dec2bin(x)..y | 			return dec2bin(x)..y | ||||||
| 		else | 		else | ||||||
| 			return ""..y | 			return ""..y | ||||||
| 		end | 		end | ||||||
|  | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.getstate(nodename, states) | function mesecon:getstate(nodename, states) | ||||||
| 	for state, name in ipairs(states) do | 	for state, name in ipairs(states) do | ||||||
| 		if name == nodename then | 		if name == nodename then | ||||||
| 			return state | 			return state | ||||||
| @@ -108,41 +128,53 @@ function mesecon.getstate(nodename, states) | |||||||
| 	error(nodename.." doesn't mention itself in "..dump(states)) | 	error(nodename.." doesn't mention itself in "..dump(states)) | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.getbinstate(nodename, states) | function mesecon:getbinstate(nodename, states) | ||||||
| 	return mesecon.dec2bin(mesecon.getstate(nodename, states)-1) | 	return dec2bin(mesecon:getstate(nodename, states)-1) | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.get_bit(binary,bit) | function mesecon:get_bit(binary,bit) | ||||||
| 	bit = bit or 1 | 	bit = bit or 1 | ||||||
| 	local c = binary:len()-(bit-1) | 	local c = binary:len()-(bit-1) | ||||||
| 	return binary:sub(c,c) == "1" | 	return binary:sub(c,c) == "1" | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.set_bit(binary,bit,value) | function mesecon:set_bit(binary,bit,value) | ||||||
| 	if value == "1" then | 	if value == "1" then | ||||||
| 		if not mesecon.get_bit(binary,bit) then | 		if not mesecon:get_bit(binary,bit) then | ||||||
| 			return mesecon.dec2bin(tonumber(binary,2)+math.pow(2,bit-1)) | 			return dec2bin(tonumber(binary,2)+math.pow(2,bit-1)) | ||||||
| 		end | 		end | ||||||
| 	elseif value == "0" then | 	elseif value == "0" then | ||||||
| 		if mesecon.get_bit(binary,bit) then | 		if mesecon:get_bit(binary,bit) then | ||||||
| 			return mesecon.dec2bin(tonumber(binary,2)-math.pow(2,bit-1)) | 			return dec2bin(tonumber(binary,2)-math.pow(2,bit-1)) | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	return binary | 	return binary | ||||||
| 	 | 	 | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.invertRule(r) | function mesecon:invertRule(r) | ||||||
| 	return vector.multiply(r, -1) | 	return {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz} | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.tablecopy(table) -- deep table copy | function mesecon:addPosRule(p, r) | ||||||
|  | 	return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z} | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function mesecon:cmpPos(p1, p2) | ||||||
|  | 	return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function mesecon:cmpSpecial(r1, r2) | ||||||
|  | 	return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | function mesecon:tablecopy(table) -- deep table copy | ||||||
| 	if type(table) ~= "table" then return table end -- no need to copy | 	if type(table) ~= "table" then return table end -- no need to copy | ||||||
| 	local newtable = {} | 	local newtable = {} | ||||||
|  |  | ||||||
| 	for idx, item in pairs(table) do | 	for idx, item in pairs(table) do | ||||||
| 		if type(item) == "table" then | 		if type(item) == "table" then | ||||||
| 			newtable[idx] = mesecon.tablecopy(item) | 			newtable[idx] = mesecon:tablecopy(item) | ||||||
| 		else | 		else | ||||||
| 			newtable[idx] = item | 			newtable[idx] = item | ||||||
| 		end | 		end | ||||||
| @@ -151,125 +183,13 @@ function mesecon.tablecopy(table) -- deep table copy | |||||||
| 	return newtable | 	return newtable | ||||||
| end | end | ||||||
|  |  | ||||||
| function mesecon.cmpAny(t1, t2) | function mesecon:cmpAny(t1, t2) | ||||||
| 	if type(t1) ~= type(t2) then return false end | 	if type(t1) ~= type(t2) then return false end | ||||||
| 	if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end | 	if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end | ||||||
|  |  | ||||||
| 	for i, e in pairs(t1) do | 	for i, e in pairs(t1) do | ||||||
| 		if not mesecon.cmpAny(e, t2[i]) then return false end | 		if not mesecon:cmpAny(e, t2[i]) then return false end | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	return true | 	return true | ||||||
| end | end | ||||||
|  |  | ||||||
| -- does not overwrite values; number keys (ipairs) are appended, not overwritten |  | ||||||
| function mesecon.mergetable(source, dest) |  | ||||||
| 	local rval = mesecon.tablecopy(dest) |  | ||||||
|  |  | ||||||
| 	for k, v in pairs(source) do |  | ||||||
| 		rval[k] = dest[k] or mesecon.tablecopy(v) |  | ||||||
| 	end |  | ||||||
| 	for i, v in ipairs(source) do |  | ||||||
| 		table.insert(rval, mesecon.tablecopy(v)) |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	return rval |  | ||||||
| end |  | ||||||
|  |  | ||||||
| function mesecon.register_node(name, spec_common, spec_off, spec_on) |  | ||||||
| 	spec_common.drop = spec_common.drop or name .. "_off" |  | ||||||
| 	spec_common.__mesecon_basename = name |  | ||||||
| 	spec_on.__mesecon_state = "on" |  | ||||||
| 	spec_off.__mesecon_state = "off" |  | ||||||
|  |  | ||||||
| 	spec_on = mesecon.mergetable(spec_common, spec_on); |  | ||||||
| 	spec_off = mesecon.mergetable(spec_common, spec_off); |  | ||||||
|  |  | ||||||
| 	minetest.register_node(name .. "_on", spec_on) |  | ||||||
| 	minetest.register_node(name .. "_off", spec_off) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- swap onstate and offstate nodes, returns new state |  | ||||||
| function mesecon.flipstate(pos, node) |  | ||||||
| 	local nodedef = minetest.registered_nodes[node.name] |  | ||||||
| 	local newstate |  | ||||||
| 	if (nodedef.__mesecon_state == "on") then newstate = "off" end |  | ||||||
| 	if (nodedef.__mesecon_state == "off") then newstate = "on" end |  | ||||||
|  |  | ||||||
| 	minetest.swap_node(pos, {name = nodedef.__mesecon_basename .. "_" .. newstate, |  | ||||||
| 		param2 = node.param2}) |  | ||||||
|  |  | ||||||
| 	return newstate |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- File writing / reading utilities |  | ||||||
| local wpath = minetest.get_worldpath() |  | ||||||
| function mesecon.file2table(filename) |  | ||||||
| 	local f = io.open(wpath..DIR_DELIM..filename, "r") |  | ||||||
| 	if f == nil then return {} end |  | ||||||
| 	local t = f:read("*all") |  | ||||||
| 	f:close() |  | ||||||
| 	if t == "" or t == nil then return {} end |  | ||||||
| 	return minetest.deserialize(t) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| function mesecon.table2file(filename, table) |  | ||||||
| 	local f = io.open(wpath..DIR_DELIM..filename, "w") |  | ||||||
| 	f:write(minetest.serialize(table)) |  | ||||||
| 	f:close() |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- Forceloading: Force server to load area if node is nil |  | ||||||
| local BLOCKSIZE = 16 |  | ||||||
|  |  | ||||||
| -- convert node position --> block hash |  | ||||||
| local function hash_blockpos(pos) |  | ||||||
| 	return minetest.hash_node_position({ |  | ||||||
| 		x = math.floor(pos.x/BLOCKSIZE), |  | ||||||
| 		y = math.floor(pos.y/BLOCKSIZE), |  | ||||||
| 		z = math.floor(pos.z/BLOCKSIZE) |  | ||||||
| 	}) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- convert block hash --> node position |  | ||||||
| local function unhash_blockpos(hash) |  | ||||||
| 	return vector.multiply(minetest.get_position_from_hash(hash), BLOCKSIZE) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| mesecon.forceloaded_blocks = {} |  | ||||||
|  |  | ||||||
| -- get node and force-load area |  | ||||||
| function mesecon.get_node_force(pos) |  | ||||||
| 	local hash = hash_blockpos(pos) |  | ||||||
|  |  | ||||||
| 	if mesecon.forceloaded_blocks[hash] == nil then |  | ||||||
| 		-- if no more forceload spaces are available, try again next time |  | ||||||
| 		if minetest.forceload_block(pos) then |  | ||||||
| 			mesecon.forceloaded_blocks[hash] = 0 |  | ||||||
| 		end |  | ||||||
| 	else |  | ||||||
| 		mesecon.forceloaded_blocks[hash] = 0 |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	return minetest.get_node_or_nil(pos) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| minetest.register_globalstep(function (dtime) |  | ||||||
| 	for hash, time in pairs(mesecon.forceloaded_blocks) do |  | ||||||
| 		-- unload forceloaded blocks after 10 minutes without usage |  | ||||||
| 		if (time > mesecon.setting("forceload_timeout", 600)) then |  | ||||||
| 			minetest.forceload_free_block(unhash_blockpos(hash)) |  | ||||||
| 			mesecon.forceloaded_blocks[hash] = nil |  | ||||||
| 		else |  | ||||||
| 			mesecon.forceloaded_blocks[hash] = time + dtime |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end) |  | ||||||
|  |  | ||||||
| -- Store and read the forceloaded blocks to / from a file |  | ||||||
| -- so that those blocks are remembered when the game |  | ||||||
| -- is restarted |  | ||||||
| mesecon.forceloaded_blocks = mesecon.file2table("mesecon_forceloaded") |  | ||||||
| minetest.register_on_shutdown(function() |  | ||||||
| 	mesecon.table2file("mesecon_forceloaded", mesecon.forceloaded_blocks) |  | ||||||
| end) |  | ||||||
|   | |||||||
| @@ -1,250 +1,280 @@ | |||||||
| -- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off | -- naming scheme: wire:(xp)(zp)(xm)(zm)_on/off | ||||||
| -- where x= x direction, z= z direction, y= y direction, p = +1, m = -1, e.g. xpym = {x=1, y=-1, z=0} | -- The conditions in brackets define whether there is a mesecon at that place or not | ||||||
| -- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1 | -- 1 = there is one; 0 = there is none | ||||||
| -- Where 0 means the wire has no visual connection to that direction and | -- y always means y+ | ||||||
| -- 1 means that the wire visually connects to that other node. |  | ||||||
|  |  | ||||||
| -- ####################### | box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16} | ||||||
| -- ## Update wire looks ## | box_bump1 =  { -2/16, -8/16,  -2/16, 2/16, -13/32, 2/16 } | ||||||
| -- ####################### |  | ||||||
|  |  | ||||||
| -- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for | box_xp = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} | ||||||
| local wire_getconnect = function (from_pos, self_pos) | box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16} | ||||||
| 	local node = minetest.get_node(self_pos) | box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16} | ||||||
| 	if minetest.registered_nodes[node.name] | box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16} | ||||||
| 	and minetest.registered_nodes[node.name].mesecons then |  | ||||||
| 		-- rules of node to possibly connect to |  | ||||||
| 		local rules = {} |  | ||||||
| 		if (minetest.registered_nodes[node.name].mesecon_wire) then |  | ||||||
| 			rules = mesecon.rules.default |  | ||||||
| 		else |  | ||||||
| 			rules = mesecon.get_any_rules(node) |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		for _, r in ipairs(mesecon.flattenrules(rules)) do | box_xpy = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16} | ||||||
| 			if (vector.equals(vector.add(self_pos, r), from_pos)) then | box_zpy = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5} | ||||||
| 				return true | box_xmy = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16} | ||||||
| 			end | box_zmy = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16} | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| 	return false |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- Update this node | -- Registering the wires | ||||||
| local wire_updateconnect = function (pos) |  | ||||||
| 	local connections = {} |  | ||||||
|  |  | ||||||
| 	for _, r in ipairs(mesecon.rules.default) do | for xp=0, 1 do | ||||||
| 		if wire_getconnect(pos, vector.add(pos, r)) then | for zp=0, 1 do | ||||||
| 			table.insert(connections, r) | for xm=0, 1 do | ||||||
| 		end | for zm=0, 1 do | ||||||
| 	end | for xpy=0, 1 do | ||||||
|  | for zpy=0, 1 do | ||||||
|  | for xmy=0, 1 do | ||||||
|  | for zmy=0, 1 do | ||||||
|  | 	if (xpy == 1 and xp == 0) or (zpy == 1 and zp == 0)  | ||||||
|  | 	or (xmy == 1 and xm == 0) or (zmy == 1 and zm == 0) then break end | ||||||
|  |  | ||||||
| 	local nid = {} | 	local groups | ||||||
| 	for _, vec in ipairs(connections) do | 	local nodeid = 	tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm ).. | ||||||
| 		-- flat component | 			tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy) | ||||||
| 		if vec.x ==  1 then nid[0] = "1" end |  | ||||||
| 		if vec.z ==  1 then nid[1] = "1" end |  | ||||||
| 		if vec.x == -1 then nid[2] = "1" end |  | ||||||
| 		if vec.z == -1 then nid[3] = "1"  end |  | ||||||
|  |  | ||||||
| 		-- slopy component |  | ||||||
| 		if vec.y == 1 then |  | ||||||
| 			if vec.x ==  1 then nid[4] = "1" end |  | ||||||
| 			if vec.z ==  1 then nid[5] = "1" end |  | ||||||
| 			if vec.x == -1 then nid[6] = "1" end |  | ||||||
| 			if vec.z == -1 then nid[7] = "1" end |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	local nodeid = 	  (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0") |  | ||||||
| 			..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0") |  | ||||||
|  |  | ||||||
| 	local state_suffix = string.find(minetest.get_node(pos).name, "_off") and "_off" or "_on" |  | ||||||
| 	minetest.set_node(pos, {name = "mesecons:wire_"..nodeid..state_suffix}) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local update_on_place_dig = function (pos, node) |  | ||||||
| 	-- Update placed node (get_node again as it may have been dug) |  | ||||||
| 	local nn = minetest.get_node(pos) |  | ||||||
| 	if (minetest.registered_nodes[nn.name]) |  | ||||||
| 	and (minetest.registered_nodes[nn.name].mesecon_wire) then |  | ||||||
| 		wire_updateconnect(pos) |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	-- Update nodes around it |  | ||||||
| 	local rules = {} |  | ||||||
| 	if minetest.registered_nodes[node.name] |  | ||||||
| 	and minetest.registered_nodes[node.name].mesecon_wire then |  | ||||||
| 		rules = mesecon.rules.default |  | ||||||
| 	else |  | ||||||
| 		rules = mesecon.get_any_rules(node) |  | ||||||
| 	end |  | ||||||
| 	if (not rules) then return end |  | ||||||
|  |  | ||||||
| 	for _, r in ipairs(mesecon.flattenrules(rules)) do |  | ||||||
| 		local np = vector.add(pos, r) |  | ||||||
| 		if minetest.registered_nodes[minetest.get_node(np).name] |  | ||||||
| 		and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then |  | ||||||
| 			wire_updateconnect(np) |  | ||||||
| 		end |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| function mesecon.update_autoconnect(pos, node) |  | ||||||
| 	if (not node) then node = minetest.get_node(pos) end |  | ||||||
| 	update_on_place_dig(pos, node) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- ############################ |  | ||||||
| -- ## Wire node registration ## |  | ||||||
| -- ############################ |  | ||||||
| -- Nodeboxes: |  | ||||||
| local box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16} |  | ||||||
| local box_bump1 =  { -2/16, -8/16,  -2/16, 2/16, -13/32, 2/16 } |  | ||||||
|  |  | ||||||
| local nbox_nid = |  | ||||||
| { |  | ||||||
| 	[0] = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}, -- x positive |  | ||||||
| 	[1] = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}, -- z positive |  | ||||||
| 	[2] = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}, -- x negative |  | ||||||
| 	[3] = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}, -- z negative |  | ||||||
|  |  | ||||||
| 	[4] = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}, -- x positive up |  | ||||||
| 	[5] = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}, -- z positive up |  | ||||||
| 	[6] = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}, -- x negative up |  | ||||||
| 	[7] = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16}  -- z negative up |  | ||||||
| } |  | ||||||
|  |  | ||||||
| local tiles_off = { "mesecons_wire_off.png" } |  | ||||||
| local tiles_on = { "mesecons_wire_on.png" } |  | ||||||
|  |  | ||||||
| local selectionbox = |  | ||||||
| { |  | ||||||
| 	type = "fixed", |  | ||||||
| 	fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| -- go to the next nodeid (ex.: 01000011 --> 01000100) |  | ||||||
| local nid_inc = function() end |  | ||||||
| nid_inc = function (nid) |  | ||||||
| 	local i = 0 |  | ||||||
| 	while nid[i-1] ~= 1 do |  | ||||||
| 		nid[i] = (nid[i] ~= 1) and 1 or 0 |  | ||||||
| 		i = i + 1 |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	-- BUT: Skip impossible nodeids: |  | ||||||
| 	if ((nid[0] == 0 and nid[4] == 1) or (nid[1] == 0 and nid[5] == 1) |  | ||||||
| 	or (nid[2] == 0 and nid[6] == 1) or (nid[3] == 0 and nid[7] == 1)) then |  | ||||||
| 		return nid_inc(nid) |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	return i <= 8 |  | ||||||
| end |  | ||||||
|  |  | ||||||
| register_wires = function() |  | ||||||
| 	local nid = {} |  | ||||||
| 	while true do |  | ||||||
| 		-- Create group specifiction and nodeid string (see note above for details) |  | ||||||
| 		local nodeid = 	  (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0") |  | ||||||
| 				..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0") |  | ||||||
|  |  | ||||||
| 		-- Calculate nodebox |  | ||||||
| 		local nodebox = {type = "fixed", fixed={box_center}} |  | ||||||
| 		for i=0,7 do |  | ||||||
| 			if nid[i] == 1 then |  | ||||||
| 				table.insert(nodebox.fixed, nbox_nid[i]) |  | ||||||
| 			end |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		-- Add bump to nodebox if curved |  | ||||||
| 		if (nid[0] == 1 and nid[1] == 1) or (nid[1] == 1 and nid[2] == 1) |  | ||||||
| 		or (nid[2] == 1 and nid[3] == 1) or (nid[3] == 1 and nid[0] == 1) then |  | ||||||
| 			table.insert(nodebox.fixed, box_bump1) |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		-- If nothing to connect to, still make a nodebox of a straight wire |  | ||||||
| 	if nodeid == "00000000" then | 	if nodeid == "00000000" then | ||||||
| 			nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} | 		groups = {dig_immediate = 3, mesecon_conductor_craftable=1} | ||||||
|  | 		wiredesc = "Mesecon" | ||||||
|  | 	else | ||||||
|  | 		groups = {dig_immediate = 3, not_in_creative_inventory = 1} | ||||||
|  | 		wiredesc = "Mesecons Wire (ID: "..nodeid..")" | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 		local rules = {} | 	local nodebox = {} | ||||||
| 		if (nid[0] == 1) then table.insert(rules, vector.new( 1,  0,  0)) end | 	local adjx = false | ||||||
| 		if (nid[1] == 1) then table.insert(rules, vector.new( 0,  0,  1)) end | 	local adjz = false | ||||||
| 		if (nid[2] == 1) then table.insert(rules, vector.new(-1,  0,  0)) end | 	if xp == 1 then table.insert(nodebox, box_xp) adjx = true end | ||||||
| 		if (nid[3] == 1) then table.insert(rules, vector.new( 0,  0, -1)) end | 	if zp == 1 then table.insert(nodebox, box_zp) adjz = true end | ||||||
|  | 	if xm == 1 then table.insert(nodebox, box_xm) adjx = true end | ||||||
|  | 	if zm == 1 then table.insert(nodebox, box_zm) adjz = true end | ||||||
|  | 	if xpy == 1 then table.insert(nodebox, box_xpy) end | ||||||
|  | 	if zpy == 1 then table.insert(nodebox, box_zpy) end | ||||||
|  | 	if xmy == 1 then table.insert(nodebox, box_xmy) end | ||||||
|  | 	if zmy == 1 then table.insert(nodebox, box_zmy) end | ||||||
|  |  | ||||||
| 		if (nid[0] == 1) then table.insert(rules, vector.new( 1, -1,  0)) end | 	if adjx and adjz and (xp + zp + xm + zm > 2) then | ||||||
| 		if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1,  1)) end | 		table.insert(nodebox, box_bump1) | ||||||
| 		if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1,  0)) end | 		tiles_off = { | ||||||
| 		if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end | 			"wires_bump_off.png", | ||||||
|  | 			"wires_bump_off.png", | ||||||
| 		if (nid[4] == 1) then table.insert(rules, vector.new( 1,  1,  0)) end | 			"wires_vertical_off.png", | ||||||
| 		if (nid[5] == 1) then table.insert(rules, vector.new( 0,  1,  1)) end | 			"wires_vertical_off.png", | ||||||
| 		if (nid[6] == 1) then table.insert(rules, vector.new(-1,  1,  0)) end | 			"wires_vertical_off.png", | ||||||
| 		if (nid[7] == 1) then table.insert(rules, vector.new( 0,  1, -1)) end | 			"wires_vertical_off.png" | ||||||
|  | 		} | ||||||
| 		local meseconspec_off = { conductor = { | 		tiles_on = { | ||||||
| 			rules = rules, | 			"wires_bump_on.png", | ||||||
| 			state = mesecon.state.off, | 			"wires_bump_on.png", | ||||||
| 			onstate = "mesecons:wire_"..nodeid.."_on" | 			"wires_vertical_on.png", | ||||||
| 		}} | 			"wires_vertical_on.png", | ||||||
|  | 			"wires_vertical_on.png", | ||||||
| 		local meseconspec_on = { conductor = { | 			"wires_vertical_on.png" | ||||||
| 			rules = rules, | 		} | ||||||
| 			state = mesecon.state.on, | 	else | ||||||
| 			offstate = "mesecons:wire_"..nodeid.."_off" | 		table.insert(nodebox, box_center) | ||||||
| 		}} | 		tiles_off = { | ||||||
|  | 			"wires_off.png", | ||||||
| 		local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1, | 			"wires_off.png", | ||||||
| 			not_in_creative_inventory = 1} | 			"wires_vertical_off.png", | ||||||
| 		local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1} | 			"wires_vertical_off.png", | ||||||
| 		if nodeid ~= "00000000" then | 			"wires_vertical_off.png", | ||||||
| 			groups_off["not_in_creative_inventory"] = 1 | 			"wires_vertical_off.png" | ||||||
|  | 		} | ||||||
|  | 		tiles_on = { | ||||||
|  | 			"wires_on.png", | ||||||
|  | 			"wires_on.png", | ||||||
|  | 			"wires_vertical_on.png", | ||||||
|  | 			"wires_vertical_on.png", | ||||||
|  | 			"wires_vertical_on.png", | ||||||
|  | 			"wires_vertical_on.png" | ||||||
|  | 		} | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 		mesecon.register_node("mesecons:wire_"..nodeid, { | 	if nodeid == "00000000" then | ||||||
| 			description = "Mesecon", | 		nodebox = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	minetest.register_node("mesecons:wire_"..nodeid.."_off", { | ||||||
|  | 		description = wiredesc, | ||||||
| 		drawtype = "nodebox", | 		drawtype = "nodebox", | ||||||
| 			inventory_image = "mesecons_wire_inv.png", | 		tiles = tiles_off, | ||||||
| 			wield_image = "mesecons_wire_inv.png", | --		inventory_image = "wires_inv.png", | ||||||
|  | --		wield_image = "wires_inv.png", | ||||||
|  | 		inventory_image = "jeija_mesecon_off.png", | ||||||
|  | 		wield_image = "jeija_mesecon_off.png", | ||||||
| 		paramtype = "light", | 		paramtype = "light", | ||||||
| 		paramtype2 = "facedir", | 		paramtype2 = "facedir", | ||||||
| 		sunlight_propagates = true, | 		sunlight_propagates = true, | ||||||
| 			selection_box = selectionbox, | 		selection_box = { | ||||||
| 			node_box = nodebox, |               		type = "fixed", | ||||||
|  | 			fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5} | ||||||
|  | 		}, | ||||||
|  | 		node_box = { | ||||||
|  | 			type = "fixed", | ||||||
|  | 			fixed = nodebox | ||||||
|  | 		}, | ||||||
|  | 		groups = groups, | ||||||
| 		walkable = false, | 		walkable = false, | ||||||
|  | 		stack_max = 99, | ||||||
| 		drop = "mesecons:wire_00000000_off", | 		drop = "mesecons:wire_00000000_off", | ||||||
| 			mesecon_wire = true | 		mesecons = {conductor={ | ||||||
| 		}, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off}, | 			state = mesecon.state.off, | ||||||
| 		{tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on}) | 			onstate = "mesecons:wire_"..nodeid.."_on" | ||||||
|  | 		}} | ||||||
|  | 	}) | ||||||
|  |  | ||||||
| 		if (nid_inc(nid) == false) then return end | 	minetest.register_node("mesecons:wire_"..nodeid.."_on", { | ||||||
|  | 		description = "Wire ID:"..nodeid, | ||||||
|  | 		drawtype = "nodebox", | ||||||
|  | 		tiles = tiles_on, | ||||||
|  | --		inventory_image = "wires_inv.png", | ||||||
|  | --		wield_image = "wires_inv.png", | ||||||
|  | 		inventory_image = "jeija_mesecon_off.png", | ||||||
|  | 		wield_image = "jeija_mesecon_off.png", | ||||||
|  | 		paramtype = "light", | ||||||
|  | 		paramtype2 = "facedir", | ||||||
|  | 		sunlight_propagates = true, | ||||||
|  | 		selection_box = { | ||||||
|  |               		type = "fixed", | ||||||
|  | 			fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5} | ||||||
|  | 		}, | ||||||
|  | 		node_box = { | ||||||
|  | 			type = "fixed", | ||||||
|  | 			fixed = nodebox | ||||||
|  | 		}, | ||||||
|  | 		groups = {dig_immediate = 3, mesecon = 2, not_in_creative_inventory = 1}, | ||||||
|  | 		walkable = false, | ||||||
|  | 		stack_max = 99, | ||||||
|  | 		drop = "mesecons:wire_00000000_off", | ||||||
|  | 		mesecons = {conductor={ | ||||||
|  | 			state = mesecon.state.on, | ||||||
|  | 			offstate = "mesecons:wire_"..nodeid.."_off" | ||||||
|  | 		}} | ||||||
|  | 	}) | ||||||
|  | end | ||||||
|  | end | ||||||
|  | end | ||||||
|  | end | ||||||
|  | end | ||||||
|  | end | ||||||
|  | end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | -- Updating the wires: | ||||||
|  | -- Place the right connection wire | ||||||
|  |  | ||||||
|  | local update_on_place_dig = function (pos, node) | ||||||
|  | 	if minetest.registered_nodes[node.name] | ||||||
|  | 	and minetest.registered_nodes[node.name].mesecons then | ||||||
|  | 		mesecon:update_autoconnect(pos) | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
| register_wires() |  | ||||||
|  |  | ||||||
| -- ############## | minetest.register_on_placenode(update_on_place_dig) | ||||||
| -- ## Crafting ## | minetest.register_on_dignode(update_on_place_dig) | ||||||
| -- ############## |  | ||||||
| minetest.register_craft({ | function mesecon:update_autoconnect(pos, secondcall, replace_old) | ||||||
|  | 	local xppos = {x=pos.x+1, y=pos.y, z=pos.z} | ||||||
|  | 	local zppos = {x=pos.x, y=pos.y, z=pos.z+1} | ||||||
|  | 	local xmpos = {x=pos.x-1, y=pos.y, z=pos.z} | ||||||
|  | 	local zmpos = {x=pos.x, y=pos.y, z=pos.z-1} | ||||||
|  |  | ||||||
|  | 	local xpympos = {x=pos.x+1, y=pos.y-1, z=pos.z} | ||||||
|  | 	local zpympos = {x=pos.x, y=pos.y-1, z=pos.z+1} | ||||||
|  | 	local xmympos = {x=pos.x-1, y=pos.y-1, z=pos.z} | ||||||
|  | 	local zmympos = {x=pos.x, y=pos.y-1, z=pos.z-1} | ||||||
|  |  | ||||||
|  | 	local xpypos = {x=pos.x+1, y=pos.y+1, z=pos.z} | ||||||
|  | 	local zpypos = {x=pos.x, y=pos.y+1, z=pos.z+1} | ||||||
|  | 	local xmypos = {x=pos.x-1, y=pos.y+1, z=pos.z} | ||||||
|  | 	local zmypos = {x=pos.x, y=pos.y+1, z=pos.z-1} | ||||||
|  |  | ||||||
|  | 	if secondcall == nil then | ||||||
|  | 		mesecon:update_autoconnect(xppos, true) | ||||||
|  | 		mesecon:update_autoconnect(zppos, true) | ||||||
|  | 		mesecon:update_autoconnect(xmpos, true) | ||||||
|  | 		mesecon:update_autoconnect(zmpos, true) | ||||||
|  |  | ||||||
|  | 		mesecon:update_autoconnect(xpypos, true) | ||||||
|  | 		mesecon:update_autoconnect(zpypos, true) | ||||||
|  | 		mesecon:update_autoconnect(xmypos, true) | ||||||
|  | 		mesecon:update_autoconnect(zmypos, true) | ||||||
|  |  | ||||||
|  | 		mesecon:update_autoconnect(xpympos, true) | ||||||
|  | 		mesecon:update_autoconnect(zpympos, true) | ||||||
|  | 		mesecon:update_autoconnect(xmympos, true) | ||||||
|  | 		mesecon:update_autoconnect(zmympos, true) | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	nodename = minetest.get_node(pos).name | ||||||
|  | 	if string.find(nodename, "mesecons:wire_") == nil and not replace_old then return nil end | ||||||
|  |  | ||||||
|  | 	if mesecon:rules_link_anydir(pos, xppos) then xp = 1 else xp = 0 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, xmpos) then xm = 1 else xm = 0 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, zppos) then zp = 1 else zp = 0 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, zmpos) then zm = 1 else zm = 0 end | ||||||
|  |  | ||||||
|  | 	if mesecon:rules_link_anydir(pos, xpympos) then xp = 1 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, xmympos) then xm = 1 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, zpympos) then zp = 1 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, zmympos) then zm = 1 end | ||||||
|  |  | ||||||
|  | 	if mesecon:rules_link_anydir(pos, xpypos) then xpy = 1 else xpy = 0 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, zpypos) then zpy = 1 else zpy = 0 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, xmypos) then xmy = 1 else xmy = 0 end | ||||||
|  | 	if mesecon:rules_link_anydir(pos, zmypos) then zmy = 1 else zmy = 0 end | ||||||
|  |  | ||||||
|  | 	if xpy == 1 then xp = 1 end | ||||||
|  | 	if zpy == 1 then zp = 1 end | ||||||
|  | 	if xmy == 1 then xm = 1 end | ||||||
|  | 	if zmy == 1 then zm = 1 end | ||||||
|  |  | ||||||
|  | 	local nodeid = 	tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm ).. | ||||||
|  | 			tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy) | ||||||
|  |  | ||||||
|  | 	 | ||||||
|  | 	if string.find(nodename, "_off") ~= nil then | ||||||
|  | 		minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_off"}) | ||||||
|  | 	else | ||||||
|  | 		minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_on" }) | ||||||
|  | 	end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | if not minetest.registered_nodes["default:stone_with_mese"] then --before MESE update, use old recipes | ||||||
|  | 	minetest.register_craft({ | ||||||
|  | 		output = "mesecons:wire_00000000_off 18", | ||||||
|  | 		recipe = { | ||||||
|  | 			{"default:mese"}, | ||||||
|  | 		} | ||||||
|  | 	}) | ||||||
|  | else | ||||||
|  |  | ||||||
|  | 	minetest.register_craft({ | ||||||
| 		type = "cooking", | 		type = "cooking", | ||||||
| 		output = "mesecons:wire_00000000_off 2", | 		output = "mesecons:wire_00000000_off 2", | ||||||
| 		recipe = "default:mese_crystal_fragment", | 		recipe = "default:mese_crystal_fragment", | ||||||
| 		cooktime = 3, | 		cooktime = 3, | ||||||
| }) | 	}) | ||||||
|  |  | ||||||
| minetest.register_craft({ | 	minetest.register_craft({ | ||||||
| 		type = "cooking", | 		type = "cooking", | ||||||
| 		output = "mesecons:wire_00000000_off 18", | 		output = "mesecons:wire_00000000_off 18", | ||||||
| 		recipe = "default:mese_crystal", | 		recipe = "default:mese_crystal", | ||||||
| 		cooktime = 15, | 		cooktime = 15, | ||||||
| }) | 	}) | ||||||
|  |  | ||||||
| minetest.register_craft({ | 	minetest.register_craft({ | ||||||
| 		type = "cooking", | 		type = "cooking", | ||||||
| 		output = "mesecons:wire_00000000_off 162", | 		output = "mesecons:wire_00000000_off 162", | ||||||
| 		recipe = "default:mese", | 		recipe = "default:mese", | ||||||
| 		cooktime = 30, | 		cooktime = 30, | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | end | ||||||
|  |  | ||||||
|  | minetest.register_craft({ | ||||||
|  | 	type = "cooking", | ||||||
|  | 	output = "mesecons:wire_00000000_off 16", | ||||||
|  | 	recipe = "default:mese_crystal", | ||||||
| }) | }) | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| The blinky plants toggles between on and off state every three seconds. Can be used to make clocks. Also works after having restarted the game. |  | ||||||
| Before Width: | Height: | Size: 65 KiB | 
| Before Width: | Height: | Size: 2.9 KiB | 
| @@ -1,51 +1,102 @@ | |||||||
| -- The BLINKY_PLANT | -- The BLINKY_PLANT | ||||||
|  | minetest.register_node("mesecons_blinkyplant:blinky_plant", { | ||||||
| local toggle_timer = function (pos) |  | ||||||
| 	local timer = minetest.get_node_timer(pos) |  | ||||||
| 	if timer:is_started() then |  | ||||||
| 		timer:stop() |  | ||||||
| 	else |  | ||||||
| 		timer:start(mesecon.setting("blinky_plant_interval", 3)) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local on_timer = function (pos) |  | ||||||
| 	local node = minetest.get_node(pos) |  | ||||||
| 	if(mesecon.flipstate(pos, node) == "on") then |  | ||||||
| 		mesecon.receptor_on(pos) |  | ||||||
| 	else |  | ||||||
| 		mesecon.receptor_off(pos) |  | ||||||
| 	end |  | ||||||
| 	toggle_timer(pos) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| mesecon.register_node("mesecons_blinkyplant:blinky_plant", { |  | ||||||
| 	description="Blinky Plant", |  | ||||||
| 	drawtype = "plantlike", | 	drawtype = "plantlike", | ||||||
|  | 	visual_scale = 1, | ||||||
|  | 	tiles = {"jeija_blinky_plant_off.png"}, | ||||||
| 	inventory_image = "jeija_blinky_plant_off.png", | 	inventory_image = "jeija_blinky_plant_off.png", | ||||||
| 	paramtype = "light", |  | ||||||
| 	walkable = false, | 	walkable = false, | ||||||
|  | 	groups = {dig_immediate=3, not_in_creative_inventory=1}, | ||||||
|  | 	drop="mesecons_blinkyplant:blinky_plant_off 1", | ||||||
|  |     description="Deactivated Blinky Plant", | ||||||
| 	sounds = default.node_sound_leaves_defaults(), | 	sounds = default.node_sound_leaves_defaults(), | ||||||
| 	selection_box = { | 	selection_box = { | ||||||
| 		type = "fixed", | 		type = "fixed", | ||||||
| 		fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, | 		fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, | ||||||
| 	}, | 	}, | ||||||
| 	on_timer = on_timer, | 	mesecons = {receptor = { | ||||||
| 	on_rightclick = toggle_timer, | 		state = mesecon.state.off | ||||||
| 	on_construct = toggle_timer | 	}}, | ||||||
| },{ | 	on_rightclick = function(pos, node, clicker) | ||||||
|  |         minetest.set_node(pos, {name="mesecons_blinkyplant:blinky_plant_off"}) | ||||||
|  |     end	 | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_node("mesecons_blinkyplant:blinky_plant_off", { | ||||||
|  | 	drawtype = "plantlike", | ||||||
|  | 	visual_scale = 1, | ||||||
| 	tiles = {"jeija_blinky_plant_off.png"}, | 	tiles = {"jeija_blinky_plant_off.png"}, | ||||||
| 	groups = {dig_immediate=3}, | 	inventory_image = "jeija_blinky_plant_off.png", | ||||||
| 	mesecons = {receptor = { state = mesecon.state.off }} | 	paramtype = "light", | ||||||
| },{ | 	walkable = false, | ||||||
|  | 	groups = {dig_immediate=3, mesecon=2}, | ||||||
|  |     description="Blinky Plant", | ||||||
|  | 	sounds = default.node_sound_leaves_defaults(), | ||||||
|  | 	selection_box = { | ||||||
|  | 		type = "fixed", | ||||||
|  | 		fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, | ||||||
|  | 	}, | ||||||
|  | 	mesecons = {receptor = { | ||||||
|  | 		state = mesecon.state.off | ||||||
|  | 	}}, | ||||||
|  | 	on_rightclick = function(pos, node, clicker) | ||||||
|  |         minetest.set_node(pos, {name="mesecons_blinkyplant:blinky_plant"}) | ||||||
|  |     end | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_node("mesecons_blinkyplant:blinky_plant_on", { | ||||||
|  | 	drawtype = "plantlike", | ||||||
|  | 	visual_scale = 1, | ||||||
| 	tiles = {"jeija_blinky_plant_on.png"}, | 	tiles = {"jeija_blinky_plant_on.png"}, | ||||||
| 	groups = {dig_immediate=3, not_in_creative_inventory=1}, | 	inventory_image = "jeija_blinky_plant_off.png", | ||||||
| 	mesecons = {receptor = { state = mesecon.state.on }} | 	paramtype = "light", | ||||||
|  | 	walkable = false, | ||||||
|  | 	groups = {dig_immediate=3, not_in_creative_inventory=1, mesecon=2}, | ||||||
|  | 	drop="mesecons_blinkyplant:blinky_plant_off 1", | ||||||
|  | 	light_source = LIGHT_MAX-7, | ||||||
|  | 	description = "Blinky Plant", | ||||||
|  | 	sounds = default.node_sound_leaves_defaults(), | ||||||
|  | 	selection_box = { | ||||||
|  | 		type = "fixed", | ||||||
|  | 		fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, | ||||||
|  | 	}, | ||||||
|  | 	mesecons = {receptor = { | ||||||
|  | 		state = mesecon.state.on | ||||||
|  | 	}}, | ||||||
|  | 	on_rightclick = function(pos, node, clicker) | ||||||
|  | 		minetest.set_node(pos, {name = "mesecons_blinkyplant:blinky_plant"}) | ||||||
|  | 		mesecon:receptor_off(pos) | ||||||
|  | 	end | ||||||
| }) | }) | ||||||
|  |  | ||||||
| minetest.register_craft({ | minetest.register_craft({ | ||||||
| 	output = "mesecons_blinkyplant:blinky_plant_off 1", | 	output = "mesecons_blinkyplant:blinky_plant_off 1", | ||||||
| 	recipe = {	{"","group:mesecon_conductor_craftable",""}, | 	recipe = { | ||||||
| 	{"","group:mesecon_conductor_craftable",""}, | 	{"","group:mesecon_conductor_craftable",""}, | ||||||
| 			{"group:sapling","group:sapling","group:sapling"}} | 	{"","group:mesecon_conductor_craftable",""}, | ||||||
|  | 	{"default:sapling","default:sapling","default:sapling"}, | ||||||
|  | 	} | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_abm( | ||||||
|  | 	{nodenames = {"mesecons_blinkyplant:blinky_plant_off"}, | ||||||
|  | 	interval = BLINKY_PLANT_INTERVAL, | ||||||
|  | 	chance = 1, | ||||||
|  | 	action = function(pos, node, active_object_count, active_object_count_wider) | ||||||
|  | 		--minetest.remove_node(pos) | ||||||
|  | 		minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_on"}) | ||||||
|  | 		nodeupdate(pos)	 | ||||||
|  | 		mesecon:receptor_on(pos) | ||||||
|  | 	end, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_abm({ | ||||||
|  | 	nodenames = {"mesecons_blinkyplant:blinky_plant_on"}, | ||||||
|  | 	interval = BLINKY_PLANT_INTERVAL, | ||||||
|  | 	chance = 1, | ||||||
|  | 	action = function(pos, node, active_object_count, active_object_count_wider) | ||||||
|  | 		--minetest.remove_node(pos) | ||||||
|  | 		minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_off"}) | ||||||
|  | 		nodeupdate(pos)	 | ||||||
|  | 		mesecon:receptor_off(pos) | ||||||
|  | 	end, | ||||||
| }) | }) | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| This receptor can be attached to walls. It turns on for 1 second if it's punched. |  | ||||||
| Before Width: | Height: | Size: 78 KiB | 
| Before Width: | Height: | Size: 7.8 KiB | 
| @@ -8,7 +8,7 @@ mesecon.button_turnoff = function (pos) | |||||||
| 		minetest.swap_node(pos, {name = "mesecons_button:button_off", param2=node.param2}) | 		minetest.swap_node(pos, {name = "mesecons_button:button_off", param2=node.param2}) | ||||||
| 		minetest.sound_play("mesecons_button_pop", {pos=pos}) | 		minetest.sound_play("mesecons_button_pop", {pos=pos}) | ||||||
| 		local rules = mesecon.rules.buttonlike_get(node) | 		local rules = mesecon.rules.buttonlike_get(node) | ||||||
| 		mesecon.receptor_off(pos, rules) | 		mesecon:receptor_off(pos, rules) | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -40,9 +40,9 @@ minetest.register_node("mesecons_button:button_off", { | |||||||
| 	}, | 	}, | ||||||
| 	groups = {dig_immediate=2, mesecon_needs_receiver = 1}, | 	groups = {dig_immediate=2, mesecon_needs_receiver = 1}, | ||||||
| 	description = "Button", | 	description = "Button", | ||||||
| 	on_rightclick = function (pos, node) | 	on_punch = function (pos, node) | ||||||
| 		minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2}) | 		minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2}) | ||||||
| 		mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node)) | 		mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node)) | ||||||
| 		minetest.sound_play("mesecons_button_push", {pos=pos}) | 		minetest.sound_play("mesecons_button_push", {pos=pos}) | ||||||
| 		minetest.after(1, mesecon.button_turnoff, pos) | 		minetest.after(1, mesecon.button_turnoff, pos) | ||||||
| 	end, | 	end, | ||||||
| @@ -67,7 +67,7 @@ minetest.register_node("mesecons_button:button_on", { | |||||||
| 	paramtype2 = "facedir", | 	paramtype2 = "facedir", | ||||||
| 	legacy_wallmounted = true, | 	legacy_wallmounted = true, | ||||||
| 	walkable = false, | 	walkable = false, | ||||||
| 	light_source = default.LIGHT_MAX-7, | 	light_source = LIGHT_MAX-7, | ||||||
| 	sunlight_propagates = true, | 	sunlight_propagates = true, | ||||||
| 	selection_box = { | 	selection_box = { | ||||||
| 		type = "fixed", | 		type = "fixed", | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| There is no crafting recipe as this should only be available for server admins. Quite similar to the Minecraft counterpart. Executes server commands. |  | ||||||
| Before Width: | Height: | Size: 36 KiB | 
| @@ -43,7 +43,7 @@ minetest.register_chatcommand("hp", { | |||||||
| }) | }) | ||||||
|  |  | ||||||
| local function initialize_data(meta) | local function initialize_data(meta) | ||||||
| 	local commands = minetest.formspec_escape(meta:get_string("commands")) | 	local commands = meta:get_string("commands") | ||||||
| 	meta:set_string("formspec", | 	meta:set_string("formspec", | ||||||
| 		"invsize[9,5;]" .. | 		"invsize[9,5;]" .. | ||||||
| 		"textarea[0.5,0.5;8.5,4;commands;Commands;"..commands.."]" .. | 		"textarea[0.5,0.5;8.5,4;commands;Commands;"..commands.."]" .. | ||||||
| @@ -79,7 +79,7 @@ local function after_place(pos, placer) | |||||||
| end | end | ||||||
|  |  | ||||||
| local function receive_fields(pos, formname, fields, sender) | local function receive_fields(pos, formname, fields, sender) | ||||||
| 	if not fields.submit then | 	if fields.quit then | ||||||
| 		return | 		return | ||||||
| 	end | 	end | ||||||
| 	local meta = minetest.get_meta(pos) | 	local meta = minetest.get_meta(pos) | ||||||
| @@ -93,22 +93,9 @@ local function receive_fields(pos, formname, fields, sender) | |||||||
| end | end | ||||||
|  |  | ||||||
| local function resolve_commands(commands, pos) | local function resolve_commands(commands, pos) | ||||||
| 	local players = minetest.get_connected_players() |  | ||||||
|  |  | ||||||
| 	-- No players online: remove all commands containing |  | ||||||
| 	-- @nearest, @farthest and @random |  | ||||||
| 	if #players == 0 then |  | ||||||
| 		commands = commands:gsub("[^\r\n]+", function (line) |  | ||||||
| 			if line:find("@nearest") then return "" end |  | ||||||
| 			if line:find("@farthest") then return "" end |  | ||||||
| 			if line:find("@random") then return "" end |  | ||||||
| 			return line |  | ||||||
| 		end) |  | ||||||
| 		return commands |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	local nearest, farthest = nil, nil | 	local nearest, farthest = nil, nil | ||||||
| 	local min_distance, max_distance = math.huge, -1 | 	local min_distance, max_distance = math.huge, -1 | ||||||
|  | 	local players = minetest.get_connected_players() | ||||||
| 	for index, player in pairs(players) do | 	for index, player in pairs(players) do | ||||||
| 		local distance = vector.distance(pos, player:getpos()) | 		local distance = vector.distance(pos, player:getpos()) | ||||||
| 		if distance < min_distance then | 		if distance < min_distance then | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| The delayer delays the signal from the input for a determined time. The time can be set by punching the delayer. Possible delays are: 0.1 seconds, 0.3 seconds, 0.5 seconds and 1 second. You may try to use it for creating songs with the noteblock. |  | ||||||
| Before Width: | Height: | Size: 61 KiB | 
| Before Width: | Height: | Size: 8.3 KiB | 
| @@ -2,7 +2,7 @@ | |||||||
| local delayer_get_output_rules = function(node) | local delayer_get_output_rules = function(node) | ||||||
| 	local rules = {{x = 0, y = 0, z = 1}} | 	local rules = {{x = 0, y = 0, z = 1}} | ||||||
| 	for i = 0, node.param2 do | 	for i = 0, node.param2 do | ||||||
| 		rules = mesecon.rotate_rules_left(rules) | 		rules = mesecon:rotate_rules_left(rules) | ||||||
| 	end | 	end | ||||||
| 	return rules | 	return rules | ||||||
| end | end | ||||||
| @@ -10,7 +10,7 @@ end | |||||||
| local delayer_get_input_rules = function(node) | local delayer_get_input_rules = function(node) | ||||||
| 	local rules = {{x = 0, y = 0, z = -1}} | 	local rules = {{x = 0, y = 0, z = -1}} | ||||||
| 	for i = 0, node.param2 do | 	for i = 0, node.param2 do | ||||||
| 		rules = mesecon.rotate_rules_left(rules) | 		rules = mesecon:rotate_rules_left(rules) | ||||||
| 	end | 	end | ||||||
| 	return rules | 	return rules | ||||||
| end | end | ||||||
|   | |||||||
| @@ -1,6 +0,0 @@ | |||||||
| The node detector is a receptor. It changes its state when either any node |  | ||||||
| or a specific node is detected. Right-click it to set a nodename to scan for. |  | ||||||
| It can also receive digiline signals. You can either send "GET" and it will |  | ||||||
| respond with the detected nodename or you can send any other string and it will |  | ||||||
| set this string as the node to scan for. |  | ||||||
| Nodenames must include the mod they reside in, so for instance default:dirt, not just dirt. |  | ||||||
| Before Width: | Height: | Size: 48 KiB | 
| Before Width: | Height: | Size: 9.8 KiB | 
| @@ -1,3 +0,0 @@ | |||||||
| The object detector is a receptor. It changes its state when a player approaches. |  | ||||||
| Right-click it to set a name to scan for. |  | ||||||
| It can also receive digiline signals which are the name to scan for on the specified channel in the right-click menu. |  | ||||||
| Before Width: | Height: | Size: 84 KiB | 
| Before Width: | Height: | Size: 9.6 KiB | 
| @@ -1,18 +1,17 @@ | |||||||
| local GET_COMMAND = "GET" |  | ||||||
|  |  | ||||||
| -- Object detector | -- Object detector | ||||||
| -- Detects players in a certain radius | -- Detects players in a certain radius | ||||||
| -- The radius can be specified in mesecons/settings.lua | -- The radius can be specified in mesecons/settings.lua | ||||||
|  |  | ||||||
| local function object_detector_make_formspec(pos) | local object_detector_make_formspec = function (pos) | ||||||
| 	minetest.get_meta(pos):set_string("formspec", "size[9,2.5]" .. | 	local meta = minetest.get_meta(pos) | ||||||
|  | 	meta:set_string("formspec", "size[9,2.5]" .. | ||||||
| 		"field[0.3,  0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]".. | 		"field[0.3,  0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]".. | ||||||
| 		"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]".. | 		"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]".. | ||||||
| 		"button_exit[7,0.75;2,3;;Save]") | 		"button_exit[7,0.75;2,3;;Save]") | ||||||
| end | end | ||||||
|  |  | ||||||
| local function object_detector_on_receive_fields(pos, _, fields) | local object_detector_on_receive_fields = function(pos, formname, fields) | ||||||
| 	if not fields.scanname or not fields.digiline_channel then return end | 	if not fields.scanname or not fields.digiline_channel then return end; | ||||||
|  |  | ||||||
| 	local meta = minetest.get_meta(pos) | 	local meta = minetest.get_meta(pos) | ||||||
| 	meta:set_string("scanname", fields.scanname) | 	meta:set_string("scanname", fields.scanname) | ||||||
| @@ -21,35 +20,25 @@ local function object_detector_on_receive_fields(pos, _, fields) | |||||||
| end | end | ||||||
|  |  | ||||||
| -- returns true if player was found, false if not | -- returns true if player was found, false if not | ||||||
| local function object_detector_scan(pos) | local object_detector_scan = function (pos) | ||||||
| 	local objs = minetest.get_objects_inside_radius(pos, mesecon.setting("detector_radius", 6)) | 	local objs = minetest.get_objects_inside_radius(pos, OBJECT_DETECTOR_RADIUS) | ||||||
|  | 	for k, obj in pairs(objs) do | ||||||
| 	-- abort if no scan results were found | 		local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil! | ||||||
| 	if next(objs) == nil then return false end |  | ||||||
|  |  | ||||||
| 		local scanname = minetest.get_meta(pos):get_string("scanname") | 		local scanname = minetest.get_meta(pos):get_string("scanname") | ||||||
| 	local every_player = scanname == "" | 		if (isname == scanname and isname ~= "") or (isname  ~= "" and scanname == "") then -- player with scanname found or not scanname specified | ||||||
| 	for _, obj in pairs(objs) do |  | ||||||
| 		-- "" is returned if it is not a player; "" ~= nil; so only handle objects with foundname ~= "" |  | ||||||
| 		local foundname = obj:get_player_name() |  | ||||||
|  |  | ||||||
| 		if foundname ~= "" then |  | ||||||
| 			-- return true if scanning for any player or if specific playername was detected |  | ||||||
| 			if scanname == "" or foundname == scanname then |  | ||||||
| 			return true | 			return true | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	return false | 	return false | ||||||
| end | end | ||||||
|  |  | ||||||
| -- set player name when receiving a digiline signal on a specific channel | -- set player name when receiving a digiline signal on a specific channel | ||||||
| local object_detector_digiline = { | object_detector_digiline = { | ||||||
| 	effector = { | 	effector = { | ||||||
| 		action = function(pos, node, channel, msg) | 		action = function (pos, node, channel, msg) | ||||||
| 			local meta = minetest.get_meta(pos) | 			local meta = minetest.get_meta(pos) | ||||||
| 			if channel == meta:get_string("digiline_channel") then | 			local active_channel = meta:get_string("digiline_channel") | ||||||
|  | 			if channel == active_channel then | ||||||
| 				meta:set_string("scanname", msg) | 				meta:set_string("scanname", msg) | ||||||
| 				object_detector_make_formspec(pos) | 				object_detector_make_formspec(pos) | ||||||
| 			end | 			end | ||||||
| @@ -64,8 +53,7 @@ minetest.register_node("mesecons_detector:object_detector_off", { | |||||||
| 	groups = {cracky=3}, | 	groups = {cracky=3}, | ||||||
| 	description="Player Detector", | 	description="Player Detector", | ||||||
| 	mesecons = {receptor = { | 	mesecons = {receptor = { | ||||||
| 		state = mesecon.state.off, | 		state = mesecon.state.off | ||||||
| 		rules = mesecon.rules.pplate |  | ||||||
| 	}}, | 	}}, | ||||||
| 	on_construct = object_detector_make_formspec, | 	on_construct = object_detector_make_formspec, | ||||||
| 	on_receive_fields = object_detector_on_receive_fields, | 	on_receive_fields = object_detector_on_receive_fields, | ||||||
| @@ -80,8 +68,7 @@ minetest.register_node("mesecons_detector:object_detector_on", { | |||||||
| 	groups = {cracky=3,not_in_creative_inventory=1}, | 	groups = {cracky=3,not_in_creative_inventory=1}, | ||||||
| 	drop = 'mesecons_detector:object_detector_off', | 	drop = 'mesecons_detector:object_detector_off', | ||||||
| 	mesecons = {receptor = { | 	mesecons = {receptor = { | ||||||
| 		state = mesecon.state.on, | 		state = mesecon.state.on | ||||||
| 		rules = mesecon.rules.pplate |  | ||||||
| 	}}, | 	}}, | ||||||
| 	on_construct = object_detector_make_formspec, | 	on_construct = object_detector_make_formspec, | ||||||
| 	on_receive_fields = object_detector_on_receive_fields, | 	on_receive_fields = object_detector_on_receive_fields, | ||||||
| @@ -98,169 +85,26 @@ minetest.register_craft({ | |||||||
| 	} | 	} | ||||||
| }) | }) | ||||||
|  |  | ||||||
| minetest.register_abm({ | minetest.register_abm( | ||||||
| 	nodenames = {"mesecons_detector:object_detector_off"}, | 	{nodenames = {"mesecons_detector:object_detector_off"}, | ||||||
| 	interval = 1, | 	interval = 1.0, | ||||||
| 	chance = 1, | 	chance = 1, | ||||||
| 	action = function(pos, node) | 	action = function(pos) | ||||||
| 		if not object_detector_scan(pos) then return end | 		if object_detector_scan(pos) then | ||||||
|  | 			minetest.swap_node(pos, {name = "mesecons_detector:object_detector_on"}) | ||||||
| 		node.name = "mesecons_detector:object_detector_on" | 			mesecon:receptor_on(pos) | ||||||
| 		minetest.swap_node(pos, node) |  | ||||||
| 		mesecon.receptor_on(pos, mesecon.rules.pplate) |  | ||||||
| 	end, |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| minetest.register_abm({ |  | ||||||
| 	nodenames = {"mesecons_detector:object_detector_on"}, |  | ||||||
| 	interval = 1, |  | ||||||
| 	chance = 1, |  | ||||||
| 	action = function(pos, node) |  | ||||||
| 		if object_detector_scan(pos) then return end |  | ||||||
|  |  | ||||||
| 		node.name = "mesecons_detector:object_detector_off" |  | ||||||
| 		minetest.swap_node(pos, node) |  | ||||||
| 		mesecon.receptor_off(pos, mesecon.rules.pplate) |  | ||||||
| 	end, |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| -- Node detector |  | ||||||
| -- Detects the node in front of it |  | ||||||
|  |  | ||||||
| local function node_detector_make_formspec(pos) |  | ||||||
| 	minetest.get_meta(pos):set_string("formspec", "size[9,2.5]" .. |  | ||||||
| 		"field[0.3,  0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]".. |  | ||||||
| 		"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]".. |  | ||||||
| 		"button_exit[7,0.75;2,3;;Save]") |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function node_detector_on_receive_fields(pos, _, fields) |  | ||||||
| 	if not fields.scanname or not fields.digiline_channel then return end |  | ||||||
|  |  | ||||||
| 	local meta = minetest.get_meta(pos) |  | ||||||
| 	meta:set_string("scanname", fields.scanname) |  | ||||||
| 	meta:set_string("digiline_channel", fields.digiline_channel) |  | ||||||
| 	node_detector_make_formspec(pos) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- returns true if node was found, false if not |  | ||||||
| local function node_detector_scan(pos) |  | ||||||
| 	local node = minetest.get_node_or_nil(pos) |  | ||||||
| 	if not node then return end |  | ||||||
|  |  | ||||||
| 	local frontname = minetest.get_node( |  | ||||||
| 		vector.subtract(pos, minetest.facedir_to_dir(node.param2)) |  | ||||||
| 	).name |  | ||||||
| 	local scanname = minetest.get_meta(pos):get_string("scanname") |  | ||||||
|  |  | ||||||
| 	return (frontname == scanname) or |  | ||||||
| 		(frontname ~= "air" and frontname ~= "ignore" and scanname == "") |  | ||||||
| end |  | ||||||
|  |  | ||||||
| -- set player name when receiving a digiline signal on a specific channel |  | ||||||
| local node_detector_digiline = { |  | ||||||
| 	effector = { |  | ||||||
| 		action = function(pos, node, channel, msg) |  | ||||||
| 			local meta = minetest.get_meta(pos) |  | ||||||
| 			if channel ~= meta:get_string("digiline_channel") then return end |  | ||||||
|  |  | ||||||
| 			if msg == GET_COMMAND then |  | ||||||
| 				local nodename = minetest.get_node( |  | ||||||
| 					vector.subtract(pos, minetest.facedir_to_dir(node.param2)) |  | ||||||
| 				).name |  | ||||||
|  |  | ||||||
| 				digiline:receptor_send(pos, digiline.rules.default, channel, nodename) |  | ||||||
| 			else |  | ||||||
| 				meta:set_string("scanname", msg) |  | ||||||
| 				node_detector_make_formspec(pos) |  | ||||||
| 		end | 		end | ||||||
| 	end, | 	end, | ||||||
| 	}, |  | ||||||
| 	receptor = {} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| local function after_place_node_detector(pos, placer) |  | ||||||
| 	local placer_pos = placer:getpos() |  | ||||||
| 	if not placer_pos then |  | ||||||
| 		return |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	--correct for the player's height |  | ||||||
| 	if placer:is_player() then |  | ||||||
| 		placer_pos.y = placer_pos.y + 1.625 |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	--correct for 6d facedir |  | ||||||
| 	local node = minetest.get_node(pos) |  | ||||||
| 	node.param2 = minetest.dir_to_facedir(vector.subtract(pos, placer_pos), true) |  | ||||||
| 	minetest.set_node(pos, node) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| minetest.register_node("mesecons_detector:node_detector_off", { |  | ||||||
| 	tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"}, |  | ||||||
| 	paramtype = "light", |  | ||||||
| 	paramtype2 = "facedir", |  | ||||||
| 	walkable = true, |  | ||||||
| 	groups = {cracky=3}, |  | ||||||
| 	description="Node Detector", |  | ||||||
| 	mesecons = {receptor = { |  | ||||||
| 		state = mesecon.state.off |  | ||||||
| 	}}, |  | ||||||
| 	on_construct = node_detector_make_formspec, |  | ||||||
| 	on_receive_fields = node_detector_on_receive_fields, |  | ||||||
| 	after_place_node = after_place_node_detector, |  | ||||||
| 	sounds = default.node_sound_stone_defaults(), |  | ||||||
| 	digiline = node_detector_digiline |  | ||||||
| }) | }) | ||||||
|  |  | ||||||
| minetest.register_node("mesecons_detector:node_detector_on", { | minetest.register_abm( | ||||||
| 	tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"}, | 	{nodenames = {"mesecons_detector:object_detector_on"}, | ||||||
| 	paramtype = "light", | 	interval = 1.0, | ||||||
| 	paramtype2 = "facedir", |  | ||||||
| 	walkable = true, |  | ||||||
| 	groups = {cracky=3,not_in_creative_inventory=1}, |  | ||||||
| 	drop = 'mesecons_detector:node_detector_off', |  | ||||||
| 	mesecons = {receptor = { |  | ||||||
| 		state = mesecon.state.on |  | ||||||
| 	}}, |  | ||||||
| 	on_construct = node_detector_make_formspec, |  | ||||||
| 	on_receive_fields = node_detector_on_receive_fields, |  | ||||||
| 	after_place_node = after_place_node_detector, |  | ||||||
| 	sounds = default.node_sound_stone_defaults(), |  | ||||||
| 	digiline = node_detector_digiline |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| minetest.register_craft({ |  | ||||||
| 	output = 'mesecons_detector:node_detector_off', |  | ||||||
| 	recipe = { |  | ||||||
| 		{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"}, |  | ||||||
| 		{"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"}, |  | ||||||
| 		{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, |  | ||||||
| 	} |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| minetest.register_abm({ |  | ||||||
| 	nodenames = {"mesecons_detector:node_detector_off"}, |  | ||||||
| 	interval = 1, |  | ||||||
| 	chance = 1, | 	chance = 1, | ||||||
| 	action = function(pos, node) | 	action = function(pos) | ||||||
| 		if not node_detector_scan(pos) then return end | 		if not object_detector_scan(pos) then | ||||||
|  | 			minetest.swap_node(pos, {name = "mesecons_detector:object_detector_off"}) | ||||||
| 		node.name = "mesecons_detector:node_detector_on" | 			mesecon:receptor_off(pos) | ||||||
| 		minetest.swap_node(pos, node) | 		end | ||||||
| 		mesecon.receptor_on(pos) |  | ||||||
| 	end, |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| minetest.register_abm({ |  | ||||||
| 	nodenames = {"mesecons_detector:node_detector_on"}, |  | ||||||
| 	interval = 1, |  | ||||||
| 	chance = 1, |  | ||||||
| 	action = function(pos, node) |  | ||||||
| 		if node_detector_scan(pos) then return end |  | ||||||
|  |  | ||||||
| 		node.name = "mesecons_detector:node_detector_off" |  | ||||||
| 		minetest.swap_node(pos, node) |  | ||||||
| 		mesecon.receptor_off(pos) |  | ||||||
| 	end, | 	end, | ||||||
| }) | }) | ||||||
|   | |||||||
| Before Width: | Height: | Size: 717 B | 
| Before Width: | Height: | Size: 727 B | 
| @@ -1,2 +1,2 @@ | |||||||
| mesecons |  | ||||||
| doors | doors | ||||||
|  | mesecons | ||||||
|   | |||||||
| @@ -1,129 +1,130 @@ | |||||||
| -- Modified, from minetest_game/mods/doors/init.lua | local other_state_node = {} | ||||||
| local function on_rightclick(pos, dir, check_name, replace, replace_dir, params) | for _, material in ipairs({ | ||||||
| 	pos.y = pos.y + dir | 	{ id = "wood", desc = "Wooden", color = "brown" }, | ||||||
| 	if not minetest.get_node(pos).name == check_name then | 	{ id = "steel", desc = "Steel", color = "grey" }, | ||||||
| 		return | }) do | ||||||
| 	end | 	doors:register_door("mesecons_doors:op_door_"..material.id, { | ||||||
| 	local p2 = minetest.get_node(pos).param2 | 		description = "Mesecon-operated "..material.desc.." Door", | ||||||
| 	p2 = params[p2 + 1] | 		inventory_image = minetest.registered_items["doors:door_"..material.id].inventory_image, | ||||||
|  | 		groups = minetest.registered_nodes["doors:door_"..material.id.."_b_1"].groups, | ||||||
| 	minetest.swap_node(pos, {name = replace_dir, param2 = p2}) | 		tiles_bottom = {"door_"..material.id.."_b.png", "door_"..material.color..".png"}, | ||||||
|  | 		tiles_top = {"door_"..material.id.."_a.png", "door_"..material.color..".png"}, | ||||||
| 	pos.y = pos.y - dir |  | ||||||
| 	minetest.swap_node(pos, {name = replace, param2 = p2}) |  | ||||||
|  |  | ||||||
| 	if (minetest.get_meta(pos):get_int("right") ~= 0) == (params[1] ~= 3) then |  | ||||||
| 		minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10}) |  | ||||||
| 	else |  | ||||||
| 		minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10}) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function meseconify_door(name) |  | ||||||
| 	if minetest.registered_items[name .. "_b_1"] then |  | ||||||
| 		-- old style double-node doors |  | ||||||
| 		local function toggle_state1 (pos, node) |  | ||||||
| 			on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0}) |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		local function toggle_state2 (pos, node) |  | ||||||
| 			on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2}) |  | ||||||
| 		end |  | ||||||
|  |  | ||||||
| 		minetest.override_item(name.."_b_1", { |  | ||||||
| 			mesecons = {effector = { |  | ||||||
| 				action_on = toggle_state1, |  | ||||||
| 				action_off = toggle_state1, |  | ||||||
| 				rules = mesecon.rules.pplate |  | ||||||
| 			}} |  | ||||||
| 	}) | 	}) | ||||||
|  | 	local groups_plus_mesecon = { mesecon = 2 } | ||||||
| 		minetest.override_item(name.."_b_2", { | 	for k, v in pairs(minetest.registered_nodes["doors:door_"..material.id.."_b_1"].groups) do | ||||||
| 			mesecons = {effector = { | 		groups_plus_mesecon[k] = v | ||||||
| 				action_on = toggle_state2, | 	end | ||||||
| 				action_off = toggle_state2, | 	doors:register_door("mesecons_doors:sig_door_"..material.id, { | ||||||
| 				rules = mesecon.rules.pplate | 		description = "Mesecon-signalling "..material.desc.." Door", | ||||||
| 			}} | 		inventory_image = minetest.registered_items["doors:door_"..material.id].inventory_image, | ||||||
|  | 		groups = groups_plus_mesecon, | ||||||
|  | 		tiles_bottom = {"door_"..material.id.."_b.png", "door_"..material.color..".png"}, | ||||||
|  | 		tiles_top = {"door_"..material.id.."_a.png", "door_"..material.color..".png"}, | ||||||
| 	}) | 	}) | ||||||
| 	elseif minetest.registered_items[name .. "_a"] then | 	for _, thishalf in ipairs({ "t", "b" }) do | ||||||
| 		-- new style mesh node based doors | 		local otherhalf = thishalf == "t" and "b" or "t" | ||||||
| 		local override = { | 		local otherdir = thishalf == "t" and -1 or 1 | ||||||
| 			mesecons = {effector = { | 		for orientation = 1, 2 do | ||||||
| 				action_on = function(pos, node) | 			local thissuffix = material.id.."_"..thishalf.."_"..orientation | ||||||
| 					local door = doors.get(pos) | 			local othersuffix = material.id.."_"..otherhalf.."_"..orientation | ||||||
| 					if door then | 			local thisopname = "mesecons_doors:op_door_"..thissuffix | ||||||
| 						door:open() | 			local otheropname = "mesecons_doors:op_door_"..othersuffix | ||||||
|  | 			local oponr = minetest.registered_nodes[thisopname].on_rightclick | ||||||
|  | 			local function handle_mesecon_signal (thispos, thisnode, signal) | ||||||
|  | 				local thismeta = minetest.get_meta(thispos) | ||||||
|  | 				if signal == thismeta:get_int("sigstate") then return end | ||||||
|  | 				thismeta:set_int("sigstate", signal) | ||||||
|  | 				local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z } | ||||||
|  | 				if minetest.get_node(otherpos).name ~= otheropname then return end | ||||||
|  | 				local othermeta = minetest.get_meta(otherpos) | ||||||
|  | 				local newdoorstate = math.max(thismeta:get_int("sigstate"), othermeta:get_int("sigstate")) | ||||||
|  | 				if newdoorstate == thismeta:get_int("doorstate") then return end | ||||||
|  | 				oponr(thispos, thisnode, nil) | ||||||
|  | 				thismeta:set_int("doorstate", newdoorstate) | ||||||
|  | 				othermeta:set_int("doorstate", newdoorstate) | ||||||
|  | 			end | ||||||
|  | 			minetest.override_item(thisopname, { | ||||||
|  | 				on_construct = function (pos) | ||||||
|  | 					if mesecon:is_powered(pos) then | ||||||
|  | 						local node = minetest.get_node(pos) | ||||||
|  | 						mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on", 1) | ||||||
|  | 						mesecon:activate(pos, node, nil, 1) | ||||||
| 					end | 					end | ||||||
| 				end, | 				end, | ||||||
| 				action_off = function(pos, node) | 				on_rightclick = function (pos, node, clicker) end, | ||||||
| 					local door = doors.get(pos) | 				mesecons = { | ||||||
| 					if door then | 					effector = { | ||||||
| 						door:close() | 						action_on = function (pos, node) | ||||||
| 					end | 							handle_mesecon_signal(pos, node, 1) | ||||||
| 						end, | 						end, | ||||||
| 				rules = mesecon.rules.pplate | 						action_off = function (pos, node) | ||||||
| 			}} | 							handle_mesecon_signal(pos, node, 0) | ||||||
| 		} |  | ||||||
| 		minetest.override_item(name .. "_a", override) |  | ||||||
| 		minetest.override_item(name .. "_b", override) |  | ||||||
| 	end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| meseconify_door("doors:door_wood") |  | ||||||
| meseconify_door("doors:door_steel") |  | ||||||
| meseconify_door("doors:door_glass") |  | ||||||
| meseconify_door("doors:door_obsidian_glass") |  | ||||||
|  |  | ||||||
| -- Trapdoor |  | ||||||
| local function trapdoor_switch(pos, node) |  | ||||||
| 	local state = minetest.get_meta(pos):get_int("state") |  | ||||||
|  |  | ||||||
| 	if state == 1 then |  | ||||||
| 		minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10}) |  | ||||||
| 		minetest.set_node(pos, {name="doors:trapdoor", param2 = node.param2}) |  | ||||||
| 	else |  | ||||||
| 		minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10}) |  | ||||||
| 		minetest.set_node(pos, {name="doors:trapdoor_open", param2 = node.param2}) |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	minetest.get_meta(pos):set_int("state", state == 1 and 0 or 1) |  | ||||||
| end |  | ||||||
|  |  | ||||||
| if doors and doors.get then |  | ||||||
| 	local override = { |  | ||||||
| 		mesecons = {effector = { |  | ||||||
| 			action_on = function(pos, node) |  | ||||||
| 				local door = doors.get(pos) |  | ||||||
| 				if door then |  | ||||||
| 					door:open() |  | ||||||
| 				end |  | ||||||
| 						end, | 						end, | ||||||
| 			action_off = function(pos, node) | 					}, | ||||||
| 				local door = doors.get(pos) | 				}, | ||||||
| 				if door then |  | ||||||
| 					door:close() |  | ||||||
| 				end |  | ||||||
| 			end, |  | ||||||
| 		}}, |  | ||||||
| 	} |  | ||||||
| 	minetest.override_item("doors:trapdoor", override) |  | ||||||
| 	minetest.override_item("doors:trapdoor_open", override) |  | ||||||
| 	minetest.override_item("doors:trapdoor_steel", override) |  | ||||||
| 	minetest.override_item("doors:trapdoor_steel_open", override) |  | ||||||
| else |  | ||||||
| 	if minetest.registered_nodes["doors:trapdoor"] then |  | ||||||
| 		minetest.override_item("doors:trapdoor", { |  | ||||||
| 			mesecons = {effector = { |  | ||||||
| 				action_on = trapdoor_switch, |  | ||||||
| 				action_off = trapdoor_switch |  | ||||||
| 			}}, |  | ||||||
| 		}) |  | ||||||
|  |  | ||||||
| 		minetest.override_item("doors:trapdoor_open", { |  | ||||||
| 			mesecons = {effector = { |  | ||||||
| 				action_on = trapdoor_switch, |  | ||||||
| 				action_off = trapdoor_switch |  | ||||||
| 			}}, |  | ||||||
| 			}) | 			}) | ||||||
|  | 			local thissigname = "mesecons_doors:sig_door_"..thissuffix | ||||||
|  | 			local othersigname = "mesecons_doors:sig_door_"..othersuffix | ||||||
|  | 			local sigonr = minetest.registered_nodes[thissigname].on_rightclick | ||||||
|  | 			minetest.override_item(thissigname, { | ||||||
|  | 				on_rightclick = function (thispos, thisnode, clicker) | ||||||
|  | 					local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z } | ||||||
|  | 					print("open: otherpos.name="..minetest.get_node(otherpos).name..", othersigname="..othersigname) | ||||||
|  | 					if minetest.get_node(otherpos).name ~= othersigname then return end | ||||||
|  | 					sigonr(thispos, thisnode, clicker) | ||||||
|  | 					for _, pos in ipairs({ thispos, otherpos }) do | ||||||
|  | 						local node = minetest.get_node(pos) | ||||||
|  | 						node.name = other_state_node[node.name] | ||||||
|  | 						minetest.swap_node(pos, node) | ||||||
|  | 						mesecon:receptor_on(pos) | ||||||
| 					end | 					end | ||||||
|  | 				end, | ||||||
|  | 				mesecons = { receptor = { state = mesecon.state.off } }, | ||||||
|  | 			}) | ||||||
|  | 			other_state_node[thissigname] = thissigname.."_on" | ||||||
|  | 			local ondef = {} | ||||||
|  | 			for k, v in pairs(minetest.registered_nodes[thissigname]) do | ||||||
|  | 				ondef[k] = v | ||||||
|  | 			end | ||||||
|  | 			ondef.on_rightclick = function (thispos, thisnode, clicker) | ||||||
|  | 				local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z } | ||||||
|  | 				print("close: otherpos.name="..minetest.get_node(otherpos).name..", othersigname="..othersigname) | ||||||
|  | 				if minetest.get_node(otherpos).name ~= othersigname.."_on" then return end | ||||||
|  | 				for _, pos in ipairs({ thispos, otherpos }) do | ||||||
|  | 					local node = minetest.get_node(pos) | ||||||
|  | 					node.name = other_state_node[node.name] | ||||||
|  | 					minetest.swap_node(pos, node) | ||||||
|  | 					mesecon:receptor_off(pos) | ||||||
|  | 				end | ||||||
|  | 				sigonr(thispos, thisnode, clicker) | ||||||
|  | 			end | ||||||
|  | 			ondef.mesecons = { receptor = { state = mesecon.state.on } } | ||||||
|  | 			ondef.after_destruct = function (thispos, thisnode) | ||||||
|  | 				local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z } | ||||||
|  | 				if minetest.get_node(otherpos).name == othersigname.."_on" then | ||||||
|  | 					minetest.remove_node(otherpos) | ||||||
|  | 					mesecon:receptor_off(otherpos) | ||||||
|  | 				end | ||||||
|  | 			end | ||||||
|  | 			other_state_node[thissigname.."_on"] = thissigname | ||||||
|  | 			ondef.mesecon_other_state_node = thissigname | ||||||
|  | 			minetest.register_node(thissigname.."_on", ondef) | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	minetest.register_craft({ | ||||||
|  | 		output = "mesecons_doors:op_door_"..material.id, | ||||||
|  | 		recipe = { | ||||||
|  | 			{ "group:mesecon_conductor_craftable", "", "" }, | ||||||
|  | 			{ "", "doors:door_"..material.id, "group:mesecon_conductor_craftable" }, | ||||||
|  | 			{ "group:mesecon_conductor_craftable", "", "" }, | ||||||
|  | 		}, | ||||||
|  | 	}) | ||||||
|  | 	minetest.register_craft({ | ||||||
|  | 		output = "mesecons_doors:sig_door_"..material.id, | ||||||
|  | 		recipe = { | ||||||
|  | 			{ "", "", "group:mesecon_conductor_craftable" }, | ||||||
|  | 			{ "group:mesecon_conductor_craftable", "doors:door_"..material.id, "" }, | ||||||
|  | 			{ "", "", "group:mesecon_conductor_craftable" }, | ||||||
|  | 		}, | ||||||
|  | 	}) | ||||||
| end | end | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ local corner_get_rules = function (node) | |||||||
| 	 {x = 0,  y = 0,  z = -1}} | 	 {x = 0,  y = 0,  z = -1}} | ||||||
|  |  | ||||||
| 	for i = 0, node.param2 do | 	for i = 0, node.param2 do | ||||||
| 		rules = mesecon.rotate_rules_left(rules) | 		rules = mesecon:rotate_rules_left(rules) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	return rules | 	return rules | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ minetest.register_node("mesecons_extrawires:crossover_off", { | |||||||
| 			{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, | 			{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| 	groups = {dig_immediate=3, mesecon=3}, | 	groups = {dig_immediate=3, mesecon=3, mesecon_conductor_craftable=1}, | ||||||
| 	mesecons = { | 	mesecons = { | ||||||
| 		conductor = { | 		conductor = { | ||||||
| 			states = crossover_states, | 			states = crossover_states, | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| Insulated corners are conductors that only conduct between the inputs (also not up or down). When placing they always point to the left in direction of your vision. |  | ||||||
| Before Width: | Height: | Size: 41 KiB | 
| Before Width: | Height: | Size: 3.8 KiB | 
| @@ -1 +0,0 @@ | |||||||
| Insulated crossing are conductors that conduct two signals between the opposing sides, the signals are insulated to each other. |  | ||||||
| Before Width: | Height: | Size: 61 KiB | 
| Before Width: | Height: | Size: 3.7 KiB | 
| @@ -1 +0,0 @@ | |||||||
| The basic prerequesite for mesecons, can be crafted into wires and other stuff. Have a look at the <a href="http://wiki.minetest.net/Mese">Minetest Wiki</a> for more information. Mese is a conductor. It conducts in all six directions: Up/Down/Left/Right/Forward/Backward |  | ||||||
| Before Width: | Height: | Size: 30 KiB | 
| Before Width: | Height: | Size: 6.1 KiB | 
| @@ -1 +0,0 @@ | |||||||
| Insulated T-Junctions are conductors that only conduct between the inputs (also not up or down). |  | ||||||
| Before Width: | Height: | Size: 54 KiB | 
| Before Width: | Height: | Size: 3.9 KiB | 
| @@ -1 +0,0 @@ | |||||||
| Vertical Mesecons only conduct up and down. Plates appear at the ends, at that place they also conduct to the side. |  | ||||||
| Before Width: | Height: | Size: 14 KiB | 
| Before Width: | Height: | Size: 3.0 KiB | 
| @@ -8,7 +8,12 @@ local mesewire_rules = | |||||||
| 	{x = 0, y = 0, z =-1}, | 	{x = 0, y = 0, z =-1}, | ||||||
| } | } | ||||||
|  |  | ||||||
| minetest.override_item("default:mese", { | minetest.register_node(":default:mese", { | ||||||
|  | 	description = "Mese Block", | ||||||
|  | 	tiles = {minetest.registered_nodes["default:mese"].tiles[1]}, | ||||||
|  | 	is_ground_content = true, | ||||||
|  | 	groups = {cracky=1}, | ||||||
|  | 	sounds = default.node_sound_stone_defaults(), | ||||||
| 	mesecons = {conductor = { | 	mesecons = {conductor = { | ||||||
| 		state = mesecon.state.off, | 		state = mesecon.state.off, | ||||||
| 		onstate = "mesecons_extrawires:mese_powered", | 		onstate = "mesecons_extrawires:mese_powered", | ||||||
| @@ -16,21 +21,15 @@ minetest.override_item("default:mese", { | |||||||
| 	}} | 	}} | ||||||
| }) | }) | ||||||
|  |  | ||||||
| -- Copy node definition of powered mese from normal mese | minetest.register_node("mesecons_extrawires:mese_powered", { | ||||||
| -- and brighten texture tiles to indicate mese is powered | 	tiles = {minetest.registered_nodes["default:mese"].tiles[1].."^[brighten"}, | ||||||
| local powered_def = mesecon.mergetable(minetest.registered_nodes["default:mese"], { | 	is_ground_content = true, | ||||||
| 	drop = "default:mese", | 	groups = {cracky=1, not_in_creative_inventory = 1}, | ||||||
| 	light_source = 5, | 	sounds = default.node_sound_stone_defaults(), | ||||||
| 	mesecons = {conductor = { | 	mesecons = {conductor = { | ||||||
| 		state = mesecon.state.on, | 		state = mesecon.state.on, | ||||||
| 		offstate = "default:mese", | 		offstate = "default:mese", | ||||||
| 		rules = mesewire_rules | 		rules = mesewire_rules | ||||||
| 	}}, | 	}}, | ||||||
| 	groups = {cracky = 1, not_in_creative_inventory = 1} | 	drop = "default:mese" | ||||||
| }) | }) | ||||||
|  |  | ||||||
| for i, v in pairs(powered_def.tiles) do |  | ||||||
| 	powered_def.tiles[i] = v .. "^[brighten" |  | ||||||
| end |  | ||||||
|  |  | ||||||
| minetest.register_node("mesecons_extrawires:mese_powered", powered_def) |  | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ local tjunction_get_rules = function (node) | |||||||
| 	 {x = 0,  y = 0,  z = -1}} | 	 {x = 0,  y = 0,  z = -1}} | ||||||
|  |  | ||||||
| 	for i = 0, node.param2 do | 	for i = 0, node.param2 do | ||||||
| 		rules = mesecon.rotate_rules_left(rules) | 		rules = mesecon:rotate_rules_left(rules) | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	return rules | 	return rules | ||||||
| @@ -65,7 +65,7 @@ minetest.register_node("mesecons_extrawires:tjunction_off", { | |||||||
| 	sunlight_propagates = true, | 	sunlight_propagates = true, | ||||||
| 	selection_box = tjunction_selectionbox, | 	selection_box = tjunction_selectionbox, | ||||||
| 	node_box = tjunction_nodebox, | 	node_box = tjunction_nodebox, | ||||||
| 	groups = {dig_immediate = 3}, | 	groups = {dig_immediate = 3, mesecon_conductor_craftable=1}, | ||||||
| 	mesecons = {conductor =  | 	mesecons = {conductor =  | ||||||
| 	{ | 	{ | ||||||
| 		state = mesecon.state.off, | 		state = mesecon.state.off, | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ local bottom_box = { | |||||||
|  |  | ||||||
| local vertical_rules = { | local vertical_rules = { | ||||||
| 	{x=0, y=1, z=0}, | 	{x=0, y=1, z=0}, | ||||||
| 	{x=0, y=-1, z=0} | 	{x=0, y=-1, z=0}, | ||||||
| } | } | ||||||
|  |  | ||||||
| local top_rules = { | local top_rules = { | ||||||
| @@ -26,7 +26,7 @@ local top_rules = { | |||||||
| 	{x=-1,y=0, z=0}, | 	{x=-1,y=0, z=0}, | ||||||
| 	{x=0,y=0, z=1}, | 	{x=0,y=0, z=1}, | ||||||
| 	{x=0,y=0, z=-1}, | 	{x=0,y=0, z=-1}, | ||||||
| 	{x=0,y=-1, z=0} | 	{x=0,y=-1, z=0}, | ||||||
| } | } | ||||||
|  |  | ||||||
| local bottom_rules = { | local bottom_rules = { | ||||||
| @@ -35,81 +35,85 @@ local bottom_rules = { | |||||||
| 	{x=0, y=0, z=1}, | 	{x=0, y=0, z=1}, | ||||||
| 	{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=0, y=2, z=0} -- receive power from pressure plate / detector / ... 2 nodes above |  | ||||||
| } | } | ||||||
|  |  | ||||||
| local vertical_updatepos = function (pos) | local vertical_updatepos = function (pos) | ||||||
| 	local node = minetest.get_node(pos) | 	local node = minetest.get_node(pos) | ||||||
| 	if minetest.registered_nodes[node.name] | 	if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].is_vertical_conductor then | ||||||
| 	and minetest.registered_nodes[node.name].is_vertical_conductor then | 		local node_above = minetest.get_node(mesecon:addPosRule(pos, vertical_rules[1])) | ||||||
| 		local node_above = minetest.get_node(vector.add(pos, vertical_rules[1])) | 		local node_below = minetest.get_node(mesecon:addPosRule(pos, vertical_rules[2])) | ||||||
| 		local node_below = minetest.get_node(vector.add(pos, vertical_rules[2])) | 		local namestate = minetest.registered_nodes[node.name].vertical_conductor_state | ||||||
|  |  | ||||||
| 		local above = minetest.registered_nodes[node_above.name] | 		local above = minetest.registered_nodes[node_above.name] and minetest.registered_nodes[node_above.name].is_vertical_conductor | ||||||
| 			and minetest.registered_nodes[node_above.name].is_vertical_conductor | 		local below = minetest.registered_nodes[node_below.name] and minetest.registered_nodes[node_below.name].is_vertical_conductor | ||||||
| 		local below = minetest.registered_nodes[node_below.name] |  | ||||||
| 			and minetest.registered_nodes[node_below.name].is_vertical_conductor |  | ||||||
|  |  | ||||||
| 		mesecon.on_dignode(pos, node) |  | ||||||
|  |  | ||||||
| 		-- Always place offstate conductor and let mesecon.on_placenode take care |  | ||||||
| 		local newname = "mesecons_extrawires:vertical_" |  | ||||||
| 		if above and below then -- above and below: vertical mesecon | 		if above and below then -- above and below: vertical mesecon | ||||||
| 			newname = newname .. "off" | 			minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate}) | ||||||
| 		elseif above and not below then -- above only: bottom | 		elseif above and not below then -- above only: bottom | ||||||
| 			newname = newname .. "bottom_off" | 			minetest.add_node(pos, {name = "mesecons_extrawires:vertical_bottom_" .. namestate}) | ||||||
| 		elseif not above and below then -- below only: top | 		elseif not above and below then -- below only: top | ||||||
| 			newname = newname .. "top_off" | 			minetest.add_node(pos, {name = "mesecons_extrawires:vertical_top_" .. namestate}) | ||||||
| 		else -- no vertical wire above, no vertical wire below: use bottom | 		else -- no vertical wire above, no vertical wire below: use default wire | ||||||
| 			newname = newname .. "bottom_off" | 			minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate}) | ||||||
| 		end | 		end | ||||||
|  |  | ||||||
| 		minetest.set_node(pos, {name = newname}) |  | ||||||
| 		mesecon.on_placenode(pos, {name = newname}) |  | ||||||
| 	end | 	end | ||||||
| end | end | ||||||
|  |  | ||||||
| local vertical_update = function (pos, node) | local vertical_update = function (pos, node) | ||||||
| 	vertical_updatepos(pos) -- this one | 	vertical_updatepos(pos) -- this one | ||||||
| 	vertical_updatepos(vector.add(pos, vertical_rules[1])) -- above | 	vertical_updatepos(mesecon:addPosRule(pos, vertical_rules[1])) -- above | ||||||
| 	vertical_updatepos(vector.add(pos, vertical_rules[2])) -- below | 	vertical_updatepos(mesecon:addPosRule(pos, vertical_rules[2])) -- below | ||||||
| end | end | ||||||
|  |  | ||||||
| -- Vertical wire | -- Vertical wire | ||||||
| mesecon.register_node("mesecons_extrawires:vertical", { | minetest.register_node("mesecons_extrawires:vertical_on", { | ||||||
| 	description = "Vertical mesecon", | 	description = "Vertical mesecon", | ||||||
| 	drawtype = "nodebox", | 	drawtype = "nodebox", | ||||||
|  | 	tiles = {"wires_vertical_on.png"}, | ||||||
| 	walkable = false, | 	walkable = false, | ||||||
| 	paramtype = "light", | 	paramtype = "light", | ||||||
| 	sunlight_propagates = true, | 	sunlight_propagates = true, | ||||||
|  | 	groups = {dig_immediate=3, not_in_creative_inventory=1}, | ||||||
| 	selection_box = vertical_box, | 	selection_box = vertical_box, | ||||||
| 	node_box = vertical_box, | 	node_box = vertical_box, | ||||||
| 	is_vertical_conductor = true, | 	is_vertical_conductor = true, | ||||||
| 	drop = "mesecons_extrawires:vertical_off", | 	vertical_conductor_state = "on", | ||||||
| 	after_place_node = vertical_update, |  | ||||||
| 	after_dig_node = vertical_update |  | ||||||
| },{ |  | ||||||
| 	tiles = {"mesecons_wire_off.png"}, |  | ||||||
| 	groups = {dig_immediate=3}, |  | ||||||
| 	mesecons = {conductor = { |  | ||||||
| 		state = mesecon.state.off, |  | ||||||
| 		onstate = "mesecons_extrawires:vertical_on", |  | ||||||
| 		rules = vertical_rules, |  | ||||||
| 	}} |  | ||||||
| },{ |  | ||||||
| 	tiles = {"mesecons_wire_on.png"}, |  | ||||||
| 	groups = {dig_immediate=3, not_in_creative_inventory=1}, |  | ||||||
| 	mesecons = {conductor = { | 	mesecons = {conductor = { | ||||||
| 		state = mesecon.state.on, | 		state = mesecon.state.on, | ||||||
| 		offstate = "mesecons_extrawires:vertical_off", | 		offstate = "mesecons_extrawires:vertical_off", | ||||||
| 		rules = vertical_rules, | 		rules = vertical_rules, | ||||||
| 	}} | 	}}, | ||||||
|  | 	drop = "mesecons_extrawires:vertical_off", | ||||||
|  | 	after_place_node = vertical_update, | ||||||
|  | 	after_dig_node = vertical_update, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_node("mesecons_extrawires:vertical_off", { | ||||||
|  | 	description = "Vertical mesecon", | ||||||
|  | 	drawtype = "nodebox", | ||||||
|  | 	tiles = {"wires_vertical_off.png"}, | ||||||
|  | 	walkable = false, | ||||||
|  | 	paramtype = "light", | ||||||
|  | 	sunlight_propagates = true, | ||||||
|  | 	groups = {dig_immediate=3}, | ||||||
|  | 	selection_box = vertical_box, | ||||||
|  | 	node_box = vertical_box, | ||||||
|  | 	is_vertical_conductor = true, | ||||||
|  | 	vertical_conductor_state = "off", | ||||||
|  | 	mesecons = {conductor = { | ||||||
|  | 		state = mesecon.state.off, | ||||||
|  | 		onstate = "mesecons_extrawires:vertical_on", | ||||||
|  | 		rules = vertical_rules, | ||||||
|  | 	}}, | ||||||
|  | 	after_place_node = vertical_update, | ||||||
|  | 	after_dig_node = vertical_update, | ||||||
| }) | }) | ||||||
|  |  | ||||||
| -- Vertical wire top | -- Vertical wire top | ||||||
| mesecon.register_node("mesecons_extrawires:vertical_top", { | minetest.register_node("mesecons_extrawires:vertical_top_on", { | ||||||
| 	description = "Vertical mesecon", | 	description = "Vertical mesecon", | ||||||
| 	drawtype = "nodebox", | 	drawtype = "nodebox", | ||||||
|  | 	tiles = {"wires_full_on.png","wires_full_on.png","wires_vertical_on.png"}, | ||||||
| 	walkable = false, | 	walkable = false, | ||||||
| 	paramtype = "light", | 	paramtype = "light", | ||||||
| 	sunlight_propagates = true, | 	sunlight_propagates = true, | ||||||
| @@ -117,29 +121,65 @@ mesecon.register_node("mesecons_extrawires:vertical_top", { | |||||||
| 	selection_box = top_box, | 	selection_box = top_box, | ||||||
| 	node_box = top_box, | 	node_box = top_box, | ||||||
| 	is_vertical_conductor = true, | 	is_vertical_conductor = true, | ||||||
| 	drop = "mesecons_extrawires:vertical_off", | 	vertical_conductor_state = "on", | ||||||
| 	after_place_node = vertical_update, |  | ||||||
| 	after_dig_node = vertical_update |  | ||||||
| },{ |  | ||||||
| 	tiles = {"mesecons_wire_off.png"}, |  | ||||||
| 	mesecons = {conductor = { |  | ||||||
| 		state = mesecon.state.off, |  | ||||||
| 		onstate = "mesecons_extrawires:vertical_top_on", |  | ||||||
| 		rules = top_rules, |  | ||||||
| 	}} |  | ||||||
| },{ |  | ||||||
| 	tiles = {"mesecons_wire_on.png"}, |  | ||||||
| 	mesecons = {conductor = { | 	mesecons = {conductor = { | ||||||
| 		state = mesecon.state.on, | 		state = mesecon.state.on, | ||||||
| 		offstate = "mesecons_extrawires:vertical_top_off", | 		offstate = "mesecons_extrawires:vertical_top_off", | ||||||
| 		rules = top_rules, | 		rules = top_rules, | ||||||
| 	}} | 	}}, | ||||||
|  | 	drop = "mesecons_extrawires:vertical_off", | ||||||
|  | 	after_place_node = vertical_update, | ||||||
|  | 	after_dig_node = vertical_update, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_node("mesecons_extrawires:vertical_top_off", { | ||||||
|  | 	description = "Vertical mesecon", | ||||||
|  | 	drawtype = "nodebox", | ||||||
|  | 	tiles = {"wires_full_off.png","wires_full_off.png","wires_vertical_off.png"}, | ||||||
|  | 	walkable = false, | ||||||
|  | 	paramtype = "light", | ||||||
|  | 	sunlight_propagates = true, | ||||||
|  | 	groups = {dig_immediate=3, not_in_creative_inventory=1}, | ||||||
|  | 	selection_box = top_box, | ||||||
|  | 	node_box = top_box, | ||||||
|  | 	is_vertical_conductor = true, | ||||||
|  | 	vertical_conductor_state = "off", | ||||||
|  | 	mesecons = {conductor = { | ||||||
|  | 		state = mesecon.state.off, | ||||||
|  | 		onstate = "mesecons_extrawires:vertical_top_on", | ||||||
|  | 		rules = top_rules, | ||||||
|  | 	}}, | ||||||
|  | 	drop = "mesecons_extrawires:vertical_off", | ||||||
|  | 	after_place_node = vertical_update, | ||||||
|  | 	after_dig_node = vertical_update, | ||||||
| }) | }) | ||||||
|  |  | ||||||
| -- Vertical wire bottom | -- Vertical wire bottom | ||||||
| mesecon.register_node("mesecons_extrawires:vertical_bottom", { | minetest.register_node("mesecons_extrawires:vertical_bottom_on", { | ||||||
| 	description = "Vertical mesecon", | 	description = "Vertical mesecon", | ||||||
| 	drawtype = "nodebox", | 	drawtype = "nodebox", | ||||||
|  | 	tiles = {"wires_full_on.png","wires_full_on.png","wires_vertical_on.png"}, | ||||||
|  | 	walkable = false, | ||||||
|  | 	paramtype = "light", | ||||||
|  | 	sunlight_propagates = true, | ||||||
|  | 	vertical_conductor_state = "on", | ||||||
|  | 	groups = {dig_immediate = 3, not_in_creative_inventory = 1}, | ||||||
|  | 	selection_box = bottom_box, | ||||||
|  | 	node_box = bottom_box, | ||||||
|  | 	mesecons = {conductor = { | ||||||
|  | 		state = mesecon.state.on, | ||||||
|  | 		offstate = "mesecons_extrawires:vertical_bottom_off", | ||||||
|  | 		rules = bottom_rules, | ||||||
|  | 	}}, | ||||||
|  | 	drop = "mesecons_extrawires:vertical_off", | ||||||
|  | 	after_place_node = vertical_update, | ||||||
|  | 	after_dig_node = vertical_update, | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_node("mesecons_extrawires:vertical_bottom_off", { | ||||||
|  | 	description = "Vertical mesecon", | ||||||
|  | 	drawtype = "nodebox", | ||||||
|  | 	tiles = {"wires_full_off.png","wires_full_off.png","wires_vertical_off.png"}, | ||||||
| 	walkable = false, | 	walkable = false, | ||||||
| 	paramtype = "light", | 	paramtype = "light", | ||||||
| 	sunlight_propagates = true, | 	sunlight_propagates = true, | ||||||
| @@ -147,23 +187,15 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", { | |||||||
| 	selection_box = bottom_box, | 	selection_box = bottom_box, | ||||||
| 	node_box = bottom_box, | 	node_box = bottom_box, | ||||||
| 	is_vertical_conductor = true, | 	is_vertical_conductor = true, | ||||||
| 	drop = "mesecons_extrawires:vertical_off", | 	vertical_conductor_state = "off", | ||||||
| 	after_place_node = vertical_update, |  | ||||||
| 	after_dig_node = vertical_update |  | ||||||
| },{ |  | ||||||
| 	tiles = {"mesecons_wire_off.png"}, |  | ||||||
| 	mesecons = {conductor = { | 	mesecons = {conductor = { | ||||||
| 		state = mesecon.state.off, | 		state = mesecon.state.off, | ||||||
| 		onstate = "mesecons_extrawires:vertical_bottom_on", | 		onstate = "mesecons_extrawires:vertical_bottom_on", | ||||||
| 		rules = bottom_rules, | 		rules = bottom_rules, | ||||||
| 	}} | 	}}, | ||||||
| },{ | 	drop = "mesecons_extrawires:vertical_off", | ||||||
| 	tiles = {"mesecons_wire_on.png"}, | 	after_place_node = vertical_update, | ||||||
| 	mesecons = {conductor = { | 	after_dig_node = vertical_update, | ||||||
| 		state = mesecon.state.on, |  | ||||||
| 		offstate = "mesecons_extrawires:vertical_bottom_off", |  | ||||||
| 		rules = bottom_rules, |  | ||||||
| 	}} |  | ||||||
| }) | }) | ||||||
|  |  | ||||||
| minetest.register_craft({ | minetest.register_craft({ | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| And gates power their output if both inputs (from left and right) are powered. |  | ||||||
| Before Width: | Height: | Size: 68 KiB | 
| Before Width: | Height: | Size: 2.7 KiB | 
| @@ -1 +0,0 @@ | |||||||
| Mesecon diodes, just like real ones, only transfer power (signals) in one direction only. |  | ||||||
| Before Width: | Height: | Size: 71 KiB | 
| Before Width: | Height: | Size: 2.0 KiB | 
| @@ -1 +0,0 @@ | |||||||
| Nand gates do not power their output if both inputs (from left and right) are powered, but power it in every other case. |  | ||||||
| Before Width: | Height: | Size: 62 KiB | 
| Before Width: | Height: | Size: 2.7 KiB |