From f1ae54ed12413ee90675a6fc92da25f3a78e97d2 Mon Sep 17 00:00:00 2001
From: Novatux <nathanael.courant@laposte.net>
Date: Fri, 10 Jan 2014 16:38:02 +0100
Subject: Try to fix gateswith serverstep code.

---
 mesecons/legacy.lua               | 29 ++++++++++++++++++-
 mesecons_gates/init.lua           |  3 +-
 mesecons_luacontroller/init.lua   | 51 +++++++++++++++++++++++++-------
 mesecons_microcontroller/init.lua | 61 ++++++++++++++++++++++++++-------------
 4 files changed, 111 insertions(+), 33 deletions(-)

diff --git a/mesecons/legacy.lua b/mesecons/legacy.lua
index a68bab4..c4334cf 100644
--- a/mesecons/legacy.lua
+++ b/mesecons/legacy.lua
@@ -2,4 +2,31 @@ minetest.swap_node = minetest.swap_node or function(pos, node)
 	local data = minetest.get_meta(pos):to_table()
 	minetest.add_node(pos, node)
 	minetest.get_meta(pos):from_table(data)
-end
\ No newline at end of file
+end
+
+local rules = {}
+rules.a = {x = -1, y = 0, z =  0, name="A"}
+rules.b = {x =  0, y = 0, z =  1, name="B"}
+rules.c = {x =  1, y = 0, z =  0, name="C"}
+rules.d = {x =  0, y = 0, z = -1, name="D"}
+
+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
diff --git a/mesecons_gates/init.lua b/mesecons_gates/init.lua
index 1a9ee83..51ed4af 100644
--- a/mesecons_gates/init.lua
+++ b/mesecons_gates/init.lua
@@ -23,7 +23,8 @@ function gate_get_input_rules_twoinputs(node)
 	return gate_rotate_rules(node)
 end
 
-function update_gate(pos)
+function update_gate(pos, node, rulename, newstate)
+	yc_update_real_portstates(pos, node, rulename, newstate)
 	gate = get_gate(pos)
 	L = rotate_ports(
 		yc_get_real_portstates(pos),
diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua
index acbf023..c9a765e 100644
--- a/mesecons_luacontroller/init.lua
+++ b/mesecons_luacontroller/init.lua
@@ -31,18 +31,46 @@ rules.d = {x =  0, y = 0, z = -1, name="D"}
 ------------------
 -- These helpers are required to set the portstates of the luacontroller
 
+function lc_update_real_portstates(pos, rulename, newstate)
+	local meta = minetest.get_meta(pos)
+	if rulename == nil then
+		meta:set_int("real_portstates", 1)
+		return
+	end
+	local n = meta:get_int("real_portstates") - 1
+	if n < 0 then
+		legacy_update_ports(pos)
+		n = meta:get_int("real_portstates") - 1
+	end
+	local L = {}
+	for i = 1, 4 do
+		L[i] = n%2
+		n = math.floor(n/2)
+	end
+	if rulename.x == nil then
+		for _, rname in ipairs(rulename) do
+			local port = ({4, 1, nil, 3, 2})[rname.x+2*rname.z+3]
+			L[port] = (newstate == "on") and 1 or 0
+		end
+	else
+		local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3]
+		L[port] = (newstate == "on") and 1 or 0
+	end
+	meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4])
+end
+
 local get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside)
-	ports = {
-		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),
-	}
-	return ports
+	local meta = minetest.get_meta(pos)
+	local L = {}
+	local n = meta:get_int("real_portstates") - 1
+	if n < 0 then
+		return legacy_update_ports(pos)
+	end
+	for _, index in ipairs({"a", "b", "c", "d"}) do
+		L[index] = ((n%2) == 1)
+		n = math.floor(n/2)
+	end
+	return L
 end
 
 local merge_portstates = function (ports, vports)
@@ -457,6 +485,7 @@ local mesecons = {
 	{
 		rules = input_rules[cid],
 		action_change = function (pos, _, rulename, newstate)
+			lc_update_real_portstates(pos, rulename, newstate)
 			lc_update(pos, {type=newstate,  pin=rulename})
 		end,
 	},
diff --git a/mesecons_microcontroller/init.lua b/mesecons_microcontroller/init.lua
index 55faa5c..b6134da 100644
--- a/mesecons_microcontroller/init.lua
+++ b/mesecons_microcontroller/init.lua
@@ -39,7 +39,8 @@ mesecon:add_rules(nodename, rules)
 local mesecons = {effector =
 {
 	rules = input_rules,
-	action_change = function (pos, node, rulename)
+	action_change = function (pos, node, rulename, newstate)
+		yc_update_real_portstates(pos, node, rulename, newstate)
 		update_yc(pos)
 	end
 }}
@@ -633,25 +634,45 @@ function yc_set_portstate(port, state, L)
 	return L
 end
 
-function yc_get_real_portstates(pos) -- port powered or not (by itself or from outside)?
-	rulesA = mesecon:get_rules("mesecons_microcontroller:microcontroller0001")
-	rulesB = mesecon:get_rules("mesecons_microcontroller:microcontroller0010")
-	rulesC = mesecon:get_rules("mesecons_microcontroller:microcontroller0100")
-	rulesD = mesecon:get_rules("mesecons_microcontroller:microcontroller1000")
-	L = {
-		a = mesecon:is_power_on(mesecon:addPosRule(pos, rulesA[1]),
-			mesecon:invertRule(rulesA[1])) and
-			mesecon:rules_link(mesecon:addPosRule(pos, rulesA[1]), pos),
-		b = mesecon:is_power_on(mesecon:addPosRule(pos, rulesB[1]),
-			mesecon:invertRule(rulesB[1])) and
-			mesecon:rules_link(mesecon:addPosRule(pos, rulesB[1]), pos),
-		c = mesecon:is_power_on(mesecon:addPosRule(pos, rulesC[1]),
-			mesecon:invertRule(rulesC[1])) and
-			mesecon:rules_link(mesecon:addPosRule(pos, rulesC[1]), pos),
-		d = mesecon:is_power_on(mesecon:addPosRule(pos, rulesD[1]),
-			mesecon:invertRule(rulesD[1])) and
-			mesecon:rules_link(mesecon:addPosRule(pos, rulesD[1]), pos),
-	}
+function yc_update_real_portstates(pos, node, rulename, newstate)
+	local meta = minetest.get_meta(pos)
+	if rulename == nil then
+		meta:set_int("real_portstates", 1)
+		return
+	end
+	local n = meta:get_int("real_portstates") - 1
+	if n < 0 then
+		legacy_update_ports(pos)
+		n = meta:get_int("real_portstates") - 1
+	end
+	local L = {}
+	for i = 1, 4 do
+		L[i] = n%2
+		n = math.floor(n/2)
+	end
+	if rulename.x == nil then
+		for _, rname in ipairs(rulename) do
+			local port = ({4, 1, nil, 3, 2})[rname.x+2*rname.z+3]
+			L[port] = (newstate == "on") and 1 or 0
+		end
+	else
+		local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3]
+		L[port] = (newstate == "on") and 1 or 0
+	end
+	meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4])
+end
+
+function yc_get_real_portstates(pos) -- determine if ports are powered (by itself or from outside)
+	local meta = minetest.get_meta(pos)
+	local L = {}
+	local n = meta:get_int("real_portstates") - 1
+	if n < 0 then
+		return legacy_update_ports(pos)
+	end
+	for _, index in ipairs({"a", "b", "c", "d"}) do
+		L[index] = ((n%2) == 1)
+		n = math.floor(n/2)
+	end
 	return L
 end
 
-- 
cgit v1.2.3