diff --git a/mesecons/internal.lua b/mesecons/internal.lua
index 419a337ec0a77975059f476206db9505fad2ce22..bde0593f329962f95636ba2c9e4636816995472e 100644
--- a/mesecons/internal.lua
+++ b/mesecons/internal.lua
@@ -297,9 +297,7 @@ function mesecon:turnon(pos)
 				mesecon:turnon(np)
 			end
 		end
-	end
-
-	if mesecon:is_effector(node.name) then
+	elseif mesecon:is_effector(node.name) then
 		mesecon:changesignal(pos, node)
 		if mesecon:is_effector_off(node.name) then
 			mesecon:activate(pos, node)
@@ -321,9 +319,7 @@ function mesecon:turnoff(pos)
 				mesecon:turnoff(np)
 			end
 		end
-	end
-
-	if mesecon:is_effector(node.name) then
+	elseif mesecon:is_effector(node.name) then
 		mesecon:changesignal(pos, node)
 		if mesecon:is_effector_on(node.name)
 		and not mesecon:is_powered(pos) then
diff --git a/mesecons/services.lua b/mesecons/services.lua
index c82e06bca65775ba92672aa5480e15b7842cca8f..ada93519c385fcaacaff5def830b07146075caaa 100644
--- a/mesecons/services.lua
+++ b/mesecons/services.lua
@@ -8,6 +8,10 @@ mesecon.on_placenode = function (pos, node)
 			mesecon:changesignal(pos, node)
 			mesecon:activate(pos, node)
 		end
+	elseif mesecon:is_conductor_on(node.name) then
+		mesecon:swap_node(pos, mesecon:get_conductor_off(node.name))
+	elseif mesecon:is_effector_on (node.name) then
+		mesecon:deactivate(pos, node)
 	end
 end
 
diff --git a/mesecons/util.lua b/mesecons/util.lua
index b95cf6e5f75940461dd2ed5220b0bfb386a9982a..2871c0ac9d6c3e9fb48e67017a34c11db92459c6 100644
--- a/mesecons/util.lua
+++ b/mesecons/util.lua
@@ -6,6 +6,15 @@ function mesecon:swap_node(pos, name)
 	minetest.env:get_meta(pos):from_table(data)
 end
 
+function mesecon:move_node(pos, newpos)
+	local node = minetest.env:get_node(pos)
+	local meta = minetest.env:get_meta(pos):to_table()
+	minetest.env:remove_node(pos)
+	minetest.env:add_node(newpos, node)
+	minetest.env:get_meta(pos):from_table(meta)
+end
+
+
 function mesecon:addPosRule(p, r)
 	return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
 end
diff --git a/mesecons/wires.lua b/mesecons/wires.lua
index f5c0f3b6f3739980eb4dc7db53bab0089ceeaee7..6c5f6efa17841787e8f886980550b74f60e3b521 100644
--- a/mesecons/wires.lua
+++ b/mesecons/wires.lua
@@ -216,10 +216,10 @@ function mesecon:update_autoconnect(pos, secondcall, replace_old)
 	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(pos, xpypos) then xpy = 1 else xpy = 0 end
-	if mesecon:rules_link(pos, zpypos) then zpy = 1 else zpy = 0 end
-	if mesecon:rules_link(pos, xmypos) then xmy = 1 else xmy = 0 end
-	if mesecon:rules_link(pos, zmypos) then zmy = 1 else zmy = 0 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
diff --git a/mesecons_pistons/init.lua b/mesecons_pistons/init.lua
index 0eb2b6ef9b478ed78f766a86d7d3ed920768dc49..92dbd32b3ab9db0cf9c643e2c1c94cbd59c41386 100644
--- a/mesecons_pistons/init.lua
+++ b/mesecons_pistons/init.lua
@@ -1,5 +1,25 @@
 --PISTONS
 
+-- Get mesecon rules of pistons
+piston_rules =
+{{x=0,  y=0,  z=1}, --everything apart from z- (pusher side)
+ {x=1,  y=0,  z=0},
+ {x=-1, y=0,  z=0},
+ {x=1,  y=1,  z=0},
+ {x=1,  y=-1, z=0},
+ {x=-1, y=1,  z=0},
+ {x=-1, y=-1, z=0},
+ {x=0,  y=1,  z=1},
+ {x=0,  y=-1, z=1}}
+
+local piston_get_rules = function (node)
+	local rules = piston_rules
+	for i = 1, node.param2 do
+		rules = mesecon:rotate_rules_left(rules)
+	end
+	return rules
+end
+
 --starts the timer to make the piston update to its new state
 local update = function(pos, node)
 	local timer = minetest.env:get_node_timer(pos)
@@ -44,11 +64,12 @@ end
 function mesecon:piston_push(pos)
 	local node = minetest.env:get_node(pos)
 	local dir = mesecon:piston_get_direction(node)
-	pos = {x=pos.x + dir.x, y=pos.y + dir.y, z=pos.z + dir.z} --move to first node being pushed
+	pos = addPosRule(pos, dir) --move to first node being pushed
 
 	--determine the number of nodes that need to be pushed
 	local count = 0
 	local checkpos = {x=pos.x, y=pos.y, z=pos.z} --first node being pushed
+
 	while true do
 		local checknode = minetest.env:get_node(checkpos)
 
@@ -69,10 +90,13 @@ function mesecon:piston_push(pos)
 			return
 		end
 
-		checkpos.x, checkpos.y, checkpos.z = checkpos.x + dir.x, checkpos.y + dir.y, checkpos.z + dir.z
+		checkpos = addPosRule(checkpos, dir)
 	end
 
-	local checknode = minetest.env:get_node(pos)
+	local thisnode = minetest.env:get_node(pos)
+	minetest.env:remove_node(pos)
+		mesecon.on_dignode(pos, thisnode)
+	local nextnode
 
 	--add pusher
 	if node.name == "mesecons_pistons:piston_normal" then
@@ -91,25 +115,15 @@ function mesecon:piston_push(pos)
 
 	--move nodes forward
 	for i = 1, count do
-		pos.x, pos.y, pos.z = pos.x + dir.x, pos.y + dir.y, pos.z + dir.z --move to the next node
-
-		--check for conductor --wip: not sure if still needed
-		if mesecon:is_conductor_on(checknode.name) then
-			checknode.name = mesecon:get_conductor_off(checknode.name)
-		end
-
-		--move the node forward
-		local nextnode = minetest.env:get_node(pos)
-		minetest.env:add_node(pos, checknode)
-		checknode = nextnode
-	end
-
-	--update nodes
-	for i = 1, count do
-		mesecon:updatenode(pos)
+		pos = addPosRule(pos, dir)  --move to the next node
+
+		nextnode = minetest.env:get_node(pos)
+		minetest.env:remove_node(pos)
+			mesecon.on_dignode(pos, thisnode)
+		minetest.env:add_node(pos, thisnode)
+			mesecon.on_placenode(pos, thisnode)
+		thisnode = nextnode
 		nodeupdate(pos)
-
-		pos.x, pos.y, pos.z = pos.x - dir.x, pos.y - dir.y, pos.z - dir.z --move to the previous node
 	end
 end
 
@@ -140,23 +154,17 @@ function mesecon:piston_pull(pos)
 
 	--retract piston
 	minetest.env:remove_node(pos) --remove pusher
-	if node.name == "mesecons_pistons:piston_sticky"
-	or node.name == "mesecons_pistons:piston_up_sticky"
-	or node.name == "mesecons_pistons:piston_down_sticky" then --retract block if piston is sticky
-		local checkpos = {x=pos.x + dir.x, y=pos.y + dir.y, z=pos.z + dir.z} --move to the node to be retracted
-		checknode = minetest.env:get_node(checkpos)
-		if checknode.name ~= "air"
-		and checknode.name ~= "ignore"
-		and minetest.registered_nodes[checknode.name].liquidtype == "none"
-		and not mesecon:is_mvps_stopper(checknode.name) then
-			minetest.env:add_node(pos, checknode)
-			minetest.env:remove_node(checkpos)
-			mesecon:updatenode(checkpos)
-			nodeupdate(checkpos)
+	if minetest.registered_nodes[node.name].is_sticky_piston then --retract block if piston is sticky
+		local retractpos  = addPosRule(pos, dir)  --move to the node to be retracted
+		local retractnode = minetest.env:get_node(retractpos)
+		if  minetest.registered_nodes[retractnode.name].liquidtype == "none"
+		and not mesecon:is_mvps_stopper(retractnode.name) then
+			mesecon:move_node(retractpos, pos)
+			mesecon.on_dignode(retractpos, retractnode)
+			mesecon.on_placenode(pos, retractnode)
+			nodeupdate(pos)
 		end
 	end
-	mesecon:updatenode(pos)
-	nodeupdate(pos)
 end
 
 --push direction of a piston
@@ -208,7 +216,8 @@ minetest.register_node("mesecons_pistons:piston_normal", {
 		return minetest.item_place(itemstack, placer, pointed_thing) --place piston normally
 	end,
 	mesecons = {effector={
-		action_change = update
+		action_change = update,
+		rules = piston_get_rules
 	}}
 })
 
@@ -219,6 +228,7 @@ minetest.register_node("mesecons_pistons:piston_sticky", {
 	paramtype2 = "facedir",
 	after_destruct = destruct,
 	on_timer = timer,
+	is_sticky_piston = true,
 	on_place = function(itemstack, placer, pointed_thing)
 		if pointed_thing.type ~= "node" then --can be placed only on nodes
 			return itemstack
@@ -243,7 +253,8 @@ minetest.register_node("mesecons_pistons:piston_sticky", {
 		return minetest.item_place(itemstack, placer, pointed_thing) --place piston normally
 	end,
 	mesecons = {effector={
-		action_change = update
+		action_change = update,
+		rules = piston_get_rules
 	}}
 })
 
@@ -307,6 +318,7 @@ minetest.register_node("mesecons_pistons:piston_up_normal", {
 	groups = {cracky=3, mesecon=2},
 	after_destruct = destruct,
 	on_timer = timer,
+	is_sticky_piston = true,
 	mesecons = {effector={
 		action_change = update
 	}},
@@ -393,6 +405,7 @@ minetest.register_node("mesecons_pistons:piston_down_sticky", {
 	groups = {cracky=3, mesecon=2},
 	after_destruct = destruct,
 	on_timer = timer,
+	is_sticky_piston = true,
 	mesecons = {effector={
 		action_change = update
 	}},