diff options
| -rw-r--r-- | mesecons/init.lua | 5 | ||||
| -rw-r--r-- | mesecons/internal.lua | 397 | ||||
| -rw-r--r-- | mesecons/services.lua | 19 | 
3 files changed, 416 insertions, 5 deletions
| diff --git a/mesecons/init.lua b/mesecons/init.lua index 6715a2f..4b29ff5 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -41,9 +41,6 @@  --rules=mesecon:rotate_rules_right/left/up/down(rules)  --  -- ---!! If a receptor node is removed, the circuit should be recalculated. This means you have to ---send an mesecon:receptor_off signal to the api when the node is dug, using the ---after_dig_node node property.  --  --EFFECTORS  -- @@ -96,7 +93,7 @@ mesecon.conductors={}  dofile(minetest.get_modpath("mesecons").."/settings.lua")  --Internal API -dofile(minetest.get_modpath("mesecons").."/internal_api.lua"); +dofile(minetest.get_modpath("mesecons").."/internal.lua");  -- API API API API API API API API API API API API API API API API API API diff --git a/mesecons/internal.lua b/mesecons/internal.lua new file mode 100644 index 0000000..a926719 --- /dev/null +++ b/mesecons/internal.lua @@ -0,0 +1,397 @@ +-- INTERNAL API + +function mesecon:is_receptor_node(nodename) +	local i = 1 +	while mesecon.pwr_srcs[i] ~= nil do +		if mesecon.pwr_srcs[i].name == nodename then +			return true +		end +		i = i + 1 +	end +	return false +end + +function mesecon:is_receptor_node_off(nodename, pos, ownpos) +	local i = 1 +	while mesecon.pwr_srcs_off[i] ~= nil do +		if mesecon.pwr_srcs_off[i].name == nodename then +			return true +		end +		i = i + 1 +	end +	return false +end + +function mesecon:receptor_get_rules(node) +	local i = 1 +	while(mesecon.pwr_srcs[i] ~= nil) do +		if mesecon.pwr_srcs[i].name == node.name then +			if mesecon.pwr_srcs[i].get_rules ~= nil then +				return mesecon.pwr_srcs[i].get_rules(node.param2) +			elseif mesecon.pwr_srcs[i].rules ~=nil then +				return mesecon.pwr_srcs[i].rules +			else +				return mesecon:get_rules("default") +			end +		end +		i = i + 1 +	end + +	while(mesecon.pwr_srcs_off[i] ~= nil) do +		if mesecon.pwr_srcs_off[i].name == node.name then +			if mesecon.pwr_srcs_off[i].get_rules ~= nil then +				return mesecon.pwr_srcs_off[i].get_rules(node.param2) +			elseif mesecon.pwr_srcs_off[i].rules ~=nil then +				return mesecon.pwr_srcs_off[i].rules +			else +				return mesecon:get_rules("default") +			end +		end +		i = i + 1 +	end +	return nil +end + +--Signals + +function mesecon:activate(pos) +	local node = minetest.env:get_node(pos)	 +	local i = 1 +	repeat +		i=i+1 +		if mesecon.actions_on[i]~=nil then mesecon.actions_on[i](pos, node)  +		else break			 +		end +	until false +end + +function mesecon:deactivate(pos) +	local node = minetest.env:get_node(pos)	 +	local i = 1 +	repeat +		i=i+1 +		if mesecon.actions_off[i]~=nil then mesecon.actions_off[i](pos, node)  +		else break			 +		end +	until false +end + +function mesecon:changesignal(pos) +	local node = minetest.env:get_node(pos)	 +	local i = 1 +	repeat +		i=i+1 +		if mesecon.actions_change[i]~=nil then mesecon.actions_change[i](pos, node)  +		else break			 +		end +	until false +end + +--Rules + +function mesecon:add_rules(name, rules) +	local i=0 +	while mesecon.rules[i]~=nil do +		i=i+1 +	end +	mesecon.rules[i]={} +	mesecon.rules[i].name=name +	mesecon.rules[i].rules=rules +end + +function mesecon:get_rules(name) +	local i=0 +	while mesecon.rules[i]~=nil do +		if mesecon.rules[i].name==name then +			return mesecon.rules[i].rules +		end +		i=i+1 +	end +end + +--Conductor system stuff + +function mesecon:get_conductor_on(offstate) +	local i=0 +	while mesecon.conductors[i]~=nil do +		if mesecon.conductors[i].off==offstate then +			return mesecon.conductors[i].on +		end +		i=i+1 +	end +	return false +end + +function mesecon:get_conductor_off(onstate) +	local i=0 +	while mesecon.conductors[i]~=nil do +		if mesecon.conductors[i].on==onstate then +			return mesecon.conductors[i].off +		end +		i=i+1 +	end +	return false +end + +function mesecon:is_conductor_on(name) +	local i=0 +	while mesecon.conductors[i]~=nil do +		if mesecon.conductors[i].on==name then +			return true +		end +		i=i+1 +	end +	return false +end + +function mesecon:is_conductor_off(name) +	local i=0 +	while mesecon.conductors[i]~=nil do +		if mesecon.conductors[i].off==name then +			return true +		end +		i=i+1 +	end +	return false +end + +--Rules rotation Functions: +function mesecon:rotate_rules_right(rules) +	local i=1 +	local nr={}; +	while rules[i]~=nil do +		nr[i]={} +		nr[i].z=rules[i].x +		nr[i].x=-rules[i].z +		nr[i].y=rules[i].y +		i=i+1 +	end +	return nr +end + +function mesecon:rotate_rules_left(rules) +	local i=1 +	local nr={}; +	while rules[i]~=nil do +		nr[i]={} +		nr[i].z=-rules[i].x +		nr[i].x=rules[i].z +		nr[i].y=rules[i].y +		i=i+1 +	end +	return nr +end + +function mesecon:rotate_rules_down(rules) +	local i=1 +	local nr={}; +	while rules[i]~=nil do +		nr[i]={} +		nr[i].y=rules[i].x +		nr[i].x=-rules[i].y +		nr[i].z=rules[i].z +		i=i+1 +	end +	return nr +end + +function mesecon:rotate_rules_up(rules) +	local i=1 +	local nr={}; +	while rules[i]~=nil do +		nr[i]={} +		nr[i].y=-rules[i].x +		nr[i].x=rules[i].y +		nr[i].z=rules[i].z +		i=i+1 +	end +	return nr +end + +function mesecon:is_power_on(pos) +	local node = minetest.env:get_node(pos) +	if mesecon:is_conductor_on(node.name) or mesecon:is_receptor_node(node.name) then +		return true +	end +	return false +end + +function mesecon:is_power_off(pos) +	local node = minetest.env:get_node(pos) +	if mesecon:is_conductor_off(node.name) or mesecon:is_receptor_node_off(node.name) then +		return 1 +	end +	return 0 +end + +function mesecon:turnon(pos) +	local node = minetest.env:get_node(pos) + +	if mesecon:is_conductor_off(node.name) then +		minetest.env:add_node(pos, {name=mesecon:get_conductor_on(node.name)}) +		nodeupdate(pos) + +		rules = mesecon:get_rules("default") --TODO: Use rules of conductor +		local i=1 +		while rules[i]~=nil do +			local np = {} +			np.x = pos.x + rules[i].x +			np.y = pos.y + rules[i].y +			np.z = pos.z + rules[i].z +			mesecon:turnon(np) +			i=i+1 +		end +	end + +	mesecon:changesignal(pos) +	if minetest.get_item_group(node.name, "mesecon_effector_off") == 1 then +		mesecon:activate(pos) +	end +end + +function mesecon:turnoff(pos) +	local node = minetest.env:get_node(pos) + +	if mesecon:is_conductor_on(node.name) then +		minetest.env:add_node(pos, {name=mesecon:get_conductor_off(node.name)}) +		nodeupdate(pos) + +		rules = mesecon:get_rules("default") --TODO: Use ruels of conductor +		local i = 1 +		while rules[i]~=nil do +			local np = {} +			np.x = pos.x + rules[i].x +			np.y = pos.y + rules[i].y +			np.z = pos.z + rules[i].z +			mesecon:turnoff(np) +			i=i+1 +		end +	end + +	mesecon:changesignal(pos) --Changesignal is always thrown because nodes can be both receptors and effectors +	if minetest.get_item_group(node.name, "mesecon_effector_on") == 1 and +	not mesecon:is_powered(pos) then --Check if the signal comes from another source +		--Send Signals to effectors: +		mesecon:deactivate(pos) +	end +end + + +function mesecon:connected_to_pw_src(pos, checked) +	if checked == nil then +		checked = {} +	end +	local connected +	local i = 1 + +	while checked[i] ~= nil do --find out if node has already been checked +		if  compare_pos(checked[i], pos) then  +			return false, checked +		end +		i = i + 1 +	end + +	checked[i] = {x=pos.x, y=pos.y, z=pos.z} --add current node to checked + +	local node = minetest.env:get_node_or_nil(pos) +	if node == nil then return false, checked end + +	if mesecon:is_conductor_on(node.name) or mesecon:is_conductor_off(node.name) then +		if mesecon:is_powered_by_receptor(pos) then --return if conductor is powered +			return true, checked +		end + +		local rules = mesecon:get_rules("default") --TODO: Use conductor specific rules +		local i = 1 +		while rules[i] ~= nil do +			local np = {} +			np.x = pos.x + rules[i].x +			np.y = pos.y + rules[i].y +			np.z = pos.z + rules[i].z +			connected, checked = mesecon:connected_to_pw_src(np, checked) +			if connected then  +				return true +			end +			i=i+1 +		end +	end +	return false, checked +end + +function mesecon:is_powered_by_receptor(pos) +	local rcpt +	local rcpt_pos = {} +	local rcpt_checked = {} --using a checked array speeds this up +	local i = 1 +	local j = 1 +	local k = 1 +	local pos_checked = false + +	while mesecon.rules[i]~=nil do +		j=1 +		while mesecon.rules[i].rules[j]~=nil do +			rcpt_pos = { +			x = pos.x-mesecon.rules[i].rules[j].x,  +			y = pos.y-mesecon.rules[i].rules[j].y,  +			z = pos.z-mesecon.rules[i].rules[j].z} + +			k = 1 +			pos_checked = false +			while rcpt_checked[k] ~= nil do +				if compare_pos(rcpt_checked[k], rcpt_pos) then +					pos_checked = true +				end +				k = k + 1 +			end + +			if not pos_checked then +				table.insert(rcpt_checked, rcpt_pos) +				rcpt = minetest.env:get_node(rcpt_pos) + +				if mesecon:is_receptor_node(rcpt.name) then  +					rules = mesecon:receptor_get_rules(rcpt) +					while rules[j] ~= nil do +					if pos.x + rules[j].x == rcpt_pos.x +					and pos.y + rules[j].y == rcpt_pos.y +					and pos.z + rules[j].z == rcpt_pos.z then +						return true +					end +					j=j+1 +				end +				end +			end +			j=j+1 +		end +		i=i+1 +	end +	return false +end + +function mesecon:is_powered_by_conductor(pos) +	local k=1 + +	rules=mesecon:get_rules("default") --TODO: use conductor specific rules +	while rules[k]~=nil do +		if mesecon:is_conductor_on(minetest.env:get_node({x=pos.x+rules[k].x, y=pos.y+rules[k].y, z=pos.z+rules[k].z}).name) then +			return true +		end +		k=k+1 +	end +	return false +end + +function mesecon:is_powered(pos) +	return mesecon:is_powered_by_conductor(pos) or mesecon:is_powered_by_receptor(pos) +end + +function mesecon:updatenode(pos) +    if mesecon:connected_to_pw_src(pos) then +        mesecon:turnon(pos) +    else +	mesecon:turnoff(pos) +    end +end + +function compare_pos(pos1, pos2) +	return pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z +end diff --git a/mesecons/services.lua b/mesecons/services.lua index cf3b78b..4cf615e 100644 --- a/mesecons/services.lua +++ b/mesecons/services.lua @@ -6,7 +6,24 @@ minetest.register_on_dignode(  		end	  		if mesecon:is_receptor_node(oldnode.name) then -			mesecon:receptor_off(pos) +			mesecon:receptor_off(pos, mesecon:receptor_get_rules(oldnode)) +		end +	end +) + +minetest.register_on_placenode( +	function (pos, node) +		if mesecon:is_receptor_node(node.name) then +			mesecon:receptor_on(pos, mesecon:receptor_get_rules(node)) +		end + +		if mesecon:is_powered(pos) then +			if mesecon:is_conductor_off(node.name) then +				mesecon:turnon(pos)		 +			else +				mesecon:changesignal(pos) +				mesecon:activate(pos) +			end  		end  	end  ) | 
