diff options
| author | Jeija <norrepli@gmail.com> | 2012-04-22 07:48:45 +0200 | 
|---|---|---|
| committer | Jeija <norrepli@gmail.com> | 2012-04-22 07:48:45 +0200 | 
| commit | 11b5ef8c94800aca3d2f153e88b437bd36cb3876 (patch) | |
| tree | a3b6885dcf5a4c07f877b16fe1b9293212a566f5 | |
| parent | 700cd06dd946e5473996c222e1fbb8ef93c99150 (diff) | |
Add new conductor system
| -rw-r--r-- | mesecons/init.lua | 360 | ||||
| -rw-r--r-- | mesecons/internal_api.lua | 405 | 
2 files changed, 413 insertions, 352 deletions
| diff --git a/mesecons/init.lua b/mesecons/init.lua index fd830ee..1b6992f 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -76,6 +76,11 @@ mesecon.actions_change={} -- Saves registered function callbacks for mesecon cha  mesecon.pwr_srcs={}  mesecon.pwr_srcs_off={}  mesecon.rules={} +mesecon.conductors={} + +--Internal API +dofile(minetest.get_modpath("mesecons").."/internal_api.lua"); +  -- MESECONS @@ -91,7 +96,7 @@ minetest.register_node("mesecons:mesecon_off", {  	selection_box = {  		type = "fixed",  	}, -	groups = {dig_immediate=3}, +	groups = {snappy=0},      	description="Mesecons",  }) @@ -116,185 +121,7 @@ minetest.register_craft({  	}  }) -function mesecon:is_power_on(pos) -	local node = minetest.env:get_node(pos) -	if node.name == "mesecons:mesecon_on" 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 node.name == "mesecons:mesecon_off" or mesecon:is_receptor_node_off(node.name) then -		return 1 -	end -	return 0 -end - -function mesecon:turnon(p, x, y, z, firstcall, rules) -	if rules==nil then -		rules=mesecon:get_rules("default") -	end -	local lpos = {} -	lpos.x=p.x+x -	lpos.y=p.y+y -	lpos.z=p.z+z - -	mesecon:changesignal(lpos) -	mesecon:activate(lpos) - -	local node = minetest.env:get_node(lpos) -	if node.name == "mesecons:mesecon_off" then -		--minetest.env:remove_node(lpos) -		minetest.env:add_node(lpos, {name="mesecons:mesecon_on"}) -		nodeupdate(lpos) -	end -	if node.name == "mesecons:mesecon_off" or firstcall then -		local i=1 -		while rules[i]~=nil do  -			mesecon:turnon(lpos, rules[i].x, rules[i].y, rules[i].z, false) -			i=i+1 -		end -	end -end - -function mesecon:turnoff(pos, x, y, z, firstcall, rules) -	if rules==nil then -		rules=mesecon:get_rules("default") -	end -	local lpos = {} -	lpos.x=pos.x+x -	lpos.y=pos.y+y -	lpos.z=pos.z+z - -	local node = minetest.env:get_node(lpos) -	local connected = 0 -	local checked = {} - -	--Send Signals to effectors: -	mesecon:changesignal(lpos) -	if not mesecon:check_if_turnon(lpos) then -		mesecon:deactivate(lpos) -	end - -	if not(firstcall) and connected==0 then -		connected=mesecon:connected_to_pw_src(lpos, 0, 0, 0, checked)	 -	end - -	if connected == 0 and  node.name == "mesecons:mesecon_on" then -		--minetest.env:remove_node(lpos) -		minetest.env:add_node(lpos, {name="mesecons:mesecon_off"}) -		nodeupdate(lpos) -	end - - -	if node.name == "mesecons:mesecon_on" or firstcall then -		if connected == 0 then -			local i=1 -			while rules[i]~=nil do  -				mesecon:turnoff(lpos, rules[i].x, rules[i].y, rules[i].z, false) -				i=i+1 -			end -		end -	end -end - - -function mesecon:connected_to_pw_src(pos, x, y, z, checked, firstcall) -	local i=1 -	local lpos = {} - -	lpos.x=pos.x+x -	lpos.y=pos.y+y -	lpos.z=pos.z+z - -	 -	local node = minetest.env:get_node_or_nil(lpos) - -	if not(node==nil) then -		repeat -			i=i+1 -			if checked[i]==nil then checked[i]={} break end -			if  checked[i].x==lpos.x and checked[i].y==lpos.y and checked[i].z==lpos.z then  -				return 0 -			end -		until false - -		checked[i].x=lpos.x -		checked[i].y=lpos.y -		checked[i].z=lpos.z - -		if mesecon:is_receptor_node(node.name, lpos, pos) == true then -- receptor nodes (power sources) can be added using mesecon:add_receptor_node -			return 1 -		end - -		if node.name=="mesecons:mesecon_on" or firstcall then -- add other conductors here -				local pw_source_found=0				 -				local rules=mesecon:get_rules("default") -				local i=1 -				while rules[i]~=nil do  -					pw_source_found=pw_source_found+mesecon:connected_to_pw_src(lpos, rules[i].x, rules[i].y, rules[i].z, checked, false) -					i=i+1 -				end -			if pw_source_found > 0 then -				return 1 -			end  -		end -	end -	return 0 -end - -function mesecon:check_if_turnon(pos) -	local i=1 -	local j=1 -	local k=1 -	local rcpt -	local rcpt_pos={} -	local rules - -	rules=mesecon:get_rules("default") -	while rules[k]~=nil do -		if minetest.env:get_node({x=pos.x+rules[k].x, y=pos.y+rules[k].y, z=pos.z+rules[k].z}).name=="mesecons:mesecon_on" then -			return true -		end -		k=k+1 -	end - -	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} -			rcpt=minetest.env:get_node(rcpt_pos) -			if mesecon:is_receptor_node(rcpt.name, rcpt_pos, pos) then  -				return true  -			end -			j=j+1 -		end -		i=i+1 -	end -	 -	return false -end - -minetest.register_on_placenode(function(pos, newnode, placer) -	if mesecon:check_if_turnon(pos) then -		if newnode.name == "mesecons:mesecon_off" then -			mesecon:turnon(pos, 0, 0, 0)		 -		else -			mesecon:changesignal(pos) -			mesecon:activate(pos) -		end -	end -end) - -minetest.register_on_dignode( -	function(pos, oldnode, digger) -		if oldnode.name == "mesecons:mesecon_on" then -			mesecon:turnoff(pos, 0, 0, 0, true) -		end	 -	end -) +mesecon:register_conductor("mesecons:mesecon_on", "mesecons:mesecon_off")  -- API API API API API API API API API API API API API API API API API API @@ -363,123 +190,6 @@ function mesecon:register_on_signal_change(action)  	mesecon.actions_change[i]=action  end - - --- INTERNAL API - - -function mesecon:is_receptor_node(nodename, pos, ownpos) --ownpos must be position of the effector/mesecon NOT of the receptor node; pos is the receptor position -	local i=1 -	local j=1 -	repeat -		if mesecon.pwr_srcs[i].name==nodename then -			if pos==nil and ownpos==nil then --old usage still possible -				return true -			end -			local rules=mesecon.pwr_srcs[i].rules -			local node=minetest.env:get_node(pos) -			if rules==nil then -				rules=mesecon.pwr_srcs[i].get_rules(node.param2) -			end - -			j=1 -			while rules[j]~=nil do --Check if dest. position is specified in the receptor's rules -				if pos.x+rules[j].x==ownpos.x -				and pos.y+rules[j].y==ownpos.y -				and pos.z+rules[j].z==ownpos.z then -					return true -				end -				j=j+1 -			end -		end -		i=i+1 -	until mesecon.pwr_srcs[i]==nil -	return false -end - -function mesecon:is_receptor_node_off(nodename, pos, ownpos) --ownpos must be position of the effector/mesecon NOT of the receptor node; pos is the receptor position -	local i=1 -	local j=1 -	repeat -		if mesecon.pwr_srcs_off[i].name==nodename then -			if pos==nil and ownpos==nil then --old usage still possible -				return true -			end -			local rules=mesecon.pwr_srcs_off[i].rules -			local node=minetest.env:get_node(pos) -			if rules==nil then -				rules=mesecon.pwr_srcs_off[i].get_rules(node.param2) -			end - -			j=1 -			while rules[j]~=nil do -				if pos.x+rules[j].x==ownpos.x -				and pos.y+rules[j].y==ownpos.y -				and pos.z+rules[j].z==ownpos.z then -					return true -				end -				j=j+1 -			end -		end -		i=i+1 -	until mesecon.pwr_srcs_off[i]==nil -	return false -end - - -function mesecon:activate(pos) -	local node = minetest.env:get_node(pos)	 -	local i = 1 -	repeat -		i=i+1 -		if mesecon.actions_on[i]~=nil then mesecon.actions_on[i](pos, node)  -		else break			 -		end -	until false -end - -function mesecon:deactivate(pos) -	local node = minetest.env:get_node(pos)	 -	local i = 1 -	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 - -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 -  mesecon:add_rules("default",   {{x=0,  y=0,  z=-1},  {x=1,  y=0,  z=0}, @@ -494,61 +204,7 @@ mesecon:add_rules("default",  {x=0,  y=1,  z=-1},  {x=0,  y=-1, z=-1}}) - ---Rules rotation Functions: -function mesecon:rotate_rules_right(rules) -	local i=1 -	local nr={}; -	while rules[i]~=nil do -		nr[i]={} -		nr[i].z=rules[i].x -		nr[i].x=-rules[i].z -		nr[i].y=rules[i].y -		i=i+1 -	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 - -print("[MESEcons] Loaded!") +print("[MESEcons] Main mod Loaded!")  --minetest.register_on_newplayer(function(player)  	--local i=1 diff --git a/mesecons/internal_api.lua b/mesecons/internal_api.lua new file mode 100644 index 0000000..d25af51 --- /dev/null +++ b/mesecons/internal_api.lua @@ -0,0 +1,405 @@ +-- INTERNAL API + +function mesecon:is_receptor_node(nodename, pos, ownpos) --ownpos must be position of the effector/mesecon NOT of the receptor node; pos is the receptor position +	local i=1 +	local j=1 +	repeat +		if mesecon.pwr_srcs[i].name==nodename then +			if pos==nil and ownpos==nil then --old usage still possible +				return true +			end +			local rules=mesecon.pwr_srcs[i].rules +			local node=minetest.env:get_node(pos) +			if rules==nil then +				rules=mesecon.pwr_srcs[i].get_rules(node.param2) +			end + +			j=1 +			while rules[j]~=nil do --Check if dest. position is specified in the receptor's rules +				if pos.x+rules[j].x==ownpos.x +				and pos.y+rules[j].y==ownpos.y +				and pos.z+rules[j].z==ownpos.z then +					return true +				end +				j=j+1 +			end +		end +		i=i+1 +	until mesecon.pwr_srcs[i]==nil +	return false +end + +function mesecon:is_receptor_node_off(nodename, pos, ownpos) --ownpos must be position of the effector/mesecon NOT of the receptor node; pos is the receptor position +	local i=1 +	local j=1 +	repeat +		if mesecon.pwr_srcs_off[i].name==nodename then +			if pos==nil and ownpos==nil then --old usage still possible +				return true +			end +			local rules=mesecon.pwr_srcs_off[i].rules +			local node=minetest.env:get_node(pos) +			if rules==nil then +				rules=mesecon.pwr_srcs_off[i].get_rules(node.param2) +			end + +			j=1 +			while rules[j]~=nil do +				if pos.x+rules[j].x==ownpos.x +				and pos.y+rules[j].y==ownpos.y +				and pos.z+rules[j].z==ownpos.z then +					return true +				end +				j=j+1 +			end +		end +		i=i+1 +	until mesecon.pwr_srcs_off[i]==nil +	return false +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:register_conductor(onstate, offstate) +	local i=0 +	while mesecon.conductors[i]~=nil do +		i=i+1 +	end +	mesecon.conductors[i]={} +	mesecon.conductors[i].on=onstate +	mesecon.conductors[i].off=offstate +end + +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 node.name == "mesecons:mesecon_on" 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(p, x, y, z, firstcall, rules) +	if rules==nil then +		rules=mesecon:get_rules("default") +	end +	local lpos = {} +	lpos.x=p.x+x +	lpos.y=p.y+y +	lpos.z=p.z+z + +	mesecon:changesignal(lpos) +	mesecon:activate(lpos) + +	local node = minetest.env:get_node(lpos) +	if mesecon:is_conductor_off(node.name) then +		minetest.env:add_node(lpos, {name=mesecon:get_conductor_on(node.name)}) +		nodeupdate(lpos) +	end +	if mesecon:is_conductor_off(node.name) or firstcall then +		local i=1 +		while rules[i]~=nil do  +			mesecon:turnon(lpos, rules[i].x, rules[i].y, rules[i].z, false) +			i=i+1 +		end +	end +end + +function mesecon:turnoff(pos, x, y, z, firstcall, rules) +	if rules==nil then +		rules=mesecon:get_rules("default") +	end +	local lpos = {} +	lpos.x=pos.x+x +	lpos.y=pos.y+y +	lpos.z=pos.z+z + +	local node = minetest.env:get_node(lpos) +	local connected = 0 +	local checked = {} + +	--Send Signals to effectors: +	mesecon:changesignal(lpos) +	if not mesecon:check_if_turnon(lpos) then +		mesecon:deactivate(lpos) +	end + +	if not(firstcall) and connected==0 then +		connected=mesecon:connected_to_pw_src(lpos, 0, 0, 0, checked)	 +	end + +	if connected == 0 and  mesecon:is_conductor_on(node.name) then +		--minetest.env:remove_node(lpos) +		minetest.env:add_node(lpos, {name=mesecon:get_conductor_off(node.name)}) +		nodeupdate(lpos) +	end + + +	if mesecon:is_conductor_on(node.name) or firstcall then +		if connected == 0 then +			local i=1 +			while rules[i]~=nil do  +				mesecon:turnoff(lpos, rules[i].x, rules[i].y, rules[i].z, false) +				i=i+1 +			end +		end +	end +end + + +function mesecon:connected_to_pw_src(pos, x, y, z, checked, firstcall) +	local i=1 +	local lpos = {} + +	lpos.x=pos.x+x +	lpos.y=pos.y+y +	lpos.z=pos.z+z + +	 +	local node = minetest.env:get_node_or_nil(lpos) + +	if not(node==nil) then +		repeat +			i=i+1 +			if checked[i]==nil then checked[i]={} break end +			if  checked[i].x==lpos.x and checked[i].y==lpos.y and checked[i].z==lpos.z then  +				return 0 +			end +		until false + +		checked[i].x=lpos.x +		checked[i].y=lpos.y +		checked[i].z=lpos.z + +		if mesecon:is_receptor_node(node.name, lpos, pos) == true then -- receptor nodes (power sources) can be added using mesecon:add_receptor_node +			return 1 +		end + +		if mesecon:is_conductor_on(node.name) or firstcall then -- add other conductors here +				local pw_source_found=0				 +				local rules=mesecon:get_rules("default") +				local i=1 +				while rules[i]~=nil do  +					pw_source_found=pw_source_found+mesecon:connected_to_pw_src(lpos, rules[i].x, rules[i].y, rules[i].z, checked, false) +					i=i+1 +				end +			if pw_source_found > 0 then +				return 1 +			end  +		end +	end +	return 0 +end + +function mesecon:check_if_turnon(pos) +	local i=1 +	local j=1 +	local k=1 +	local rcpt +	local rcpt_pos={} +	local rules + +	rules=mesecon:get_rules("default") --Power form a on-conductor +	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 + +	while mesecon.rules[i]~=nil do --Power from a receptor +		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} +			rcpt=minetest.env:get_node(rcpt_pos) +			if mesecon:is_receptor_node(rcpt.name, rcpt_pos, pos) then  +				return true  +			end +			j=j+1 +		end +		i=i+1 +	end +	return false +end + +minetest.register_on_placenode(function(pos, newnode, placer) +	if mesecon:check_if_turnon(pos) then +		if mesecon:is_conductor_off(newnode.name) then +			print ("IS CONDUCTOR OFF") +			mesecon:turnon(pos, 0, 0, 0)		 +		else +			mesecon:changesignal(pos) +			mesecon:activate(pos) +		end +	end +end) + +minetest.register_on_dignode( +	function(pos, oldnode, digger) +		if mesecon:is_conductor_on(oldnode.name) then +			mesecon:turnoff(pos, 0, 0, 0, true) +		end	 +	end +) | 
