diff options
Diffstat (limited to 'mesecons_gates')
| -rw-r--r-- | mesecons_gates/init.lua | 253 | 
1 files changed, 123 insertions, 130 deletions
diff --git a/mesecons_gates/init.lua b/mesecons_gates/init.lua index 8a4629f..dabefd5 100644 --- a/mesecons_gates/init.lua +++ b/mesecons_gates/init.lua @@ -1,62 +1,127 @@ -outrules = { -	{x=1, y=0, z=0}, -} -oneinput = { -	{x=-1, y=0, z=0}, -	{x=1, y=0, z=0}, -} -twoinputs = { +function gate_rotate_rules(node) +	for rotations = 0, node.param2 - 1 do +		rules = mesecon:rotate_rules_left(rules) +	end +	return rules +end + +function gate_get_output_rules(node) +	rules = {{x=1, y=0, z=0}} +	return gate_rotate_rules(node) +end + +function gate_get_input_rules_oneinput(node) +	rules = {{x=-1, y=0, z=0}, {x=1, y=0, z=0}} +	return gate_rotate_rules(node) +end + +function gate_get_input_rules_twoinputs(node) +	rules = {  	{x=0, y=0, z=1},  	{x=0, y=0, z=-1}, -	{x=1, y=0, z=0}, -} -function get_gate_rules(param2, onlyout, singleinput) -	if onlyout then -		rules = outrules -	else -		if singleinput then -			rules = oneinput +	{x=1, y=0, z=0}} +	return gate_rotate_rules(node) +end + +function update_gate(pos) +	gate = get_gate(pos) +	L = rotate_ports( +		yc_get_real_portstates(pos), +		minetest.env:get_node(pos).param2 +	) +	if gate == "diode" then +		set_gate(pos, L.a) +	elseif gate == "not" then +		set_gate(pos, not L.a) +	elseif gate == "nand" then +		set_gate(pos, not(L.b and L.d)) +	elseif gate == "and" then +		set_gate(pos, L.b and L.d) +	elseif gate == "xor" then +		set_gate(pos, (L.b and not L.d) or (not L.b and L.d)) +	end +end + +function set_gate(pos, on) +	gate = get_gate(pos) +	local meta = minetest.env:get_meta(pos) +	if on ~= gate_state(pos) then +		yc_heat(meta) +		minetest.after(0.5, yc_cool, meta) +		if yc_overheat(meta) then +			pop_gate(pos)  		else -			rules = twoinputs +			if on then +				mesecon:swap_node(pos, "mesecons_gates:"..gate.."_on") +				mesecon:receptor_on(pos, +				gate_get_output_rules(minetest.env:get_node(pos))) +			else +				mesecon:swap_node(pos, "mesecons_gates:"..gate.."_off") +				mesecon:receptor_off(pos, +				gate_get_output_rules(minetest.env:get_node(pos))) +			end  		end  	end +end + +function get_gate(pos) +	return minetest.registered_nodes[minetest.env:get_node(pos).name].mesecons_gate +end + +function gate_state(pos) +	name = minetest.env:get_node(pos).name +	return string.find(name, "_on") ~= nil +end + +function pop_gate(pos) +	gate = get_gate(pos) +	minetest.env:remove_node(pos) +	minetest.after(0.2, yc_overheat_off, pos) +	minetest.env:add_item(pos, "mesecons_gates:"..gate.."_off") +end + +function rotate_ports(L, param2)  	for rotations=0, param2-1 do -		rules = mesecon:rotate_rules_left(rules) +		port = L.a +		L.a = L.b +		L.b = L.c +		L.c = L.d +		L.d = port  	end -	return rules +	return L  end -function get_gate_rules_one(param2) return get_gate_rules(param2, false, true) end -function get_gate_rules_two(param2) return get_gate_rules(param2, false, false) end -function get_gate_rules_out(param2) return get_gate_rules(param2, true) end -gates = {"diode", "not", "nand", "and", "xor"} -for g in ipairs(gates) do gate = gates[g] -	if g < 3 then -		get_rules = get_gate_rules_one -	else -		get_rules = get_gate_rules_two +gates = { +{name = "diode", inputnumber = 1},  +{name = "not"  , inputnumber = 1},  +{name = "nand" , inputnumber = 2}, +{name = "and"  , inputnumber = 2}, +{name = "xor"  , inputnumber = 2}} + +for i, gate in ipairs(gates) do +	if gate.inputnumber == 1 then +		get_rules = gate_get_input_rules_oneinput +	elseif gate.inputnumber == 2 then +		get_rules = gate_get_input_rules_twoinputs  	end -	for on=0,1 do -		nodename = "mesecons_gates:"..gate +	for on = 0, 1 do +		nodename = "mesecons_gates:"..gate.name  		if on == 1 then  			onoff = "on"  			drop = nodename.."_off"  			nodename = nodename.."_"..onoff  			description = "You hacker you!" -			groups = {dig_immediate=2, not_in_creative_inventory=1, mesecon = 3} -			mesecon:add_receptor_node(nodename, get_rules, get_gate_rules_out) -			--mesecon:add_receptor_node(nodename, mesecon:get_rules("insulated_all")) +			groups = {dig_immediate=2, not_in_creative_inventory=1}  		else  			onoff = "off"  			nodename = nodename.."_"..onoff -			description = gate.." Gate" -			groups = {dig_immediate=2, mesecon = 3} -			--mesecon:add_receptor_node_off(nodename, get_gate_rules_out) +			description = gate.name.." Gate" +			groups = {dig_immediate=2}  		end  		tiles = "jeija_microcontroller_bottom.png^"..  			"jeija_gate_"..onoff..".png^".. -			"jeija_gate_"..gate..".png" +			"jeija_gate_"..gate.name..".png"  		node_box = {  			type = "fixed", @@ -65,6 +130,13 @@ for g in ipairs(gates) do gate = gates[g]  			},  		} +		local mesecon_state +		if on == 1 then +			mesecon_state = mesecon.state.on +		else +			mesecon_state = mesecon.state.off +		end +  		minetest.register_node(nodename, {  			description = description,  			paramtype = "light", @@ -82,103 +154,24 @@ for g in ipairs(gates) do gate = gates[g]  			end,  			groups = groups,  			drop = drop, - +			mesecons_gate = gate.name, +			mesecons = +			{ +				receptor = +				{ +					state = mesecon_state, +					rules = gate_get_output_rules +				}, +				effector = +				{ +					rules = get_rules, +					action_change = update_gate +				} +			}  		}) - -		mesecon:register_effector(nodename, nodename, all_rules, get_rules)  	end  end -function get_gate(pos) -	return -	string.gsub(  -	string.gsub( -	string.gsub( -	minetest.env:get_node(pos).name -	, "mesecons_gates:", "") --gate -	,"_on", "") -	,"_off", "") -end - -function gate_state(pos) -	name = minetest.env:get_node(pos).name -	return string.find(name, "_on") ~= nil -end - -function pop_gate(pos) -	gate = get_gate(pos) -	minetest.env:remove_node(pos) -	minetest.after(0.2, yc_overheat_off, pos) -	minetest.env:add_item(pos, "mesecons_gates:"..gate.."_off") -end - -function set_gate(pos, on) -	gate = get_gate(pos) -	local meta = minetest.env:get_meta(pos) -	if on ~= gate_state(pos) then -		yc_heat(meta) -		minetest.after(0.5, yc_cool, meta) -		if yc_overheat(meta) then -			pop_gate(pos) -		else -			heat = meta:get_int("heat") -			if on then -				onoff = "_on" -			else -				onoff = "_off" -			end -			param2 = minetest.env:get_node(pos).param2 -			minetest.env:add_node(pos, { -				name = "mesecons_gates:"..gate..onoff, -				param2 = param2, -			}) -			local meta2 = minetest.env:get_meta(pos) -			meta2:set_int("heat", heat) -			if on then -				mesecon:receptor_on(pos, get_gate_rules(param2, true)) -			else -				mesecon:receptor_off(pos, all_rules) -			end -		end -	end -end - -function rotate_ports(L, param2) -	for rotations=0, param2-1 do -		port = L.a -		L.a = L.b -		L.b = L.c -		L.c = L.d -		L.d = port -	end -	return L -end - -function update_gate(pos) -	gate = get_gate(pos) -	L = rotate_ports( -		yc_get_real_portstates(pos), -		minetest.env:get_node(pos).param2 -	) -	if gate == "diode" then -		set_gate(pos, L.a)	 -	elseif gate == "not" then -		set_gate(pos, not L.a) -	elseif gate == "nand" then -		set_gate(pos, not(L.b and L.d)) -	elseif gate == "and" then -		set_gate(pos, L.b and L.d) -	else--if gate == "xor" then -		set_gate(pos, (L.b and not L.d) or (not L.b and L.d)) -	end -end - -mesecon:register_on_signal_change(function(pos,node) -	if string.find(node.name, "mesecons_gates:")~=nil then -		update_gate(pos) -	end -end) -  minetest.register_craft({  	output = 'mesecons_gates:diode_off',  	recipe = {  | 
