remote.OnServerEvent:connect(function(a)if IsCoupled.Value then IsCoupled.Value=false else Allow.Value=not Allow.Value Recolor()end end)IsCoupled.Changed:connect(function()if IsCoupled.Value==false then Decouple()end Recolor()end)function rotate(a,y)local e=Instance.new("\082\111\116\097\116\101")e.Part0=a e.Part1=y e.C0=CFrame.new()e.C1=y.CFrame:inverse()*a.CFrame e.Name="\067\111\117\112\108\101\114\082\111\116\097\116\101"return e end function rotateSpecial(a,y)local e=Instance.new("\082\111\116\097\116\101")e.Part0=a e.Part1=y e.C0=CFrame.new(0,0,-0.6)e.C1=CFrame.new(0,0,-0.6)*CFrame.Angles(0,math.pi,0)e.Name="\067\111\117\112\108\101\114\082\111\116\097\116\101"return e end function PGSRotates(a,y)local e=Instance.new("\080\097\114\116")e.CanCollide=false e.Transparency=1 e.FormFactor="\080\108\097\116\101"e.Size=Vector3.new()e.TopSurface="\083\109\111\111\116\104"e.BottomSurface="\083\109\111\111\116\104"local g=e:Clone()e.CFrame=a.CFrame g.CFrame=y.CFrame;(rotate(a,e)).Parent=a;(rotate(y,g)).Parent=y;(rotateSpecial(e,g)).Parent=e e.Parent=coupler.Parent g.Parent=coupler.Parent return e,g end function Couple(a,y)if PGS then a.CanCollide=false y.CanCollide=false R1,R2=PGSRotates(a,y)else MyWeld=weld(a,y)MyWeld.Parent=model end a.SoundClose:Play()end CoupledTo.Changed:connect(function()if CoupledTo.Value then local a=CoupledTo.Value:FindFirstChild("\067\111\117\112\108\101\114")if a and(CoupledTo.Value:FindFirstChild("\073\115\067\111\117\112\108\101\100")and(CoupledTo.Value.IsCoupled:IsA("\066\111\111\108\086\097\108\117\101")and CoupledTo.Value.IsCoupled.Value))then else return end local y=coupler:GetNetworkOwner()local e=a:GetNetworkOwner()local g=coupler:GetNetworkOwnershipAuto()local s=a:GetNetworkOwnershipAuto()if coupler:CanSetNetworkOwnership()then coupler:SetNetworkOwner(nil)end if CoupledTo.Value.Coupler:CanSetNetworkOwnership()then coupler:SetNetworkOwner(nil)end Couple(coupler,a)if coupler:CanSetNetworkOwnership()then if g and s then coupler:SetNetworkOwnershipAuto()elseif g then coupler:SetNetworkOwner(e)elseif s then coupler:SetNetworkOwner(y)else coupler:SetNetworkOwner(y)end end wait()if PGS then WeldDisappear=coupler.ChildRemoved:connect(function(a)if a.Name=="\067\111\117\112\108\101\114\082\111\116\097\116\101"then Decouple()WeldDisappear:disconnect()end end)else WeldDisappear=MyWeld.AncestryChanged:connect(function()Decouple()WeldDisappear:disconnect()end)end else coupler.CanCollide=true end end)coupler.Touched:connect(function(a)if a.Parent and a.Name=="\067\111\117\112\108\101\114"then local y=a.Parent local e=y:FindFirstChild("\065\108\108\111\119")local g=y:FindFirstChild("\073\115\067\111\117\112\108\101\100")if e and g then if e.Value==true and(Allow.Value==true and(g.Value==false and IsCoupled.Value==false))then IsCoupled.Value=true g.Value=true CoupledTo.Value=y if y:FindFirstChild("\067\111\117\112\108\101\100\084\111")then y.CoupledTo.Value=model end end end end end)


remote.OnServerEvent:connect(function(player)
	if IsCoupled.Value then
		IsCoupled.Value = false
	else
		Allow.Value = not Allow.Value
		Recolor()
	end
end)

IsCoupled.Changed:connect(function()
	if IsCoupled.Value == false then
		Decouple()
	end
	Recolor()
end)

function rotate(a,b)
	local weld = Instance.new("Rotate")
	weld.Part0 = a
	weld.Part1 = b
	weld.C0 = CFrame.new()
	weld.C1 = b.CFrame:inverse() * a.CFrame--use this because you get less floating point errors
	weld.Name = "CouplerRotate"
	return weld
end

function rotateSpecial(a,b)
	local weld = Instance.new("Rotate")
	weld.Part0 = a
	weld.Part1 = b
	weld.C0 = CFrame.new(0,0,-0.6)
	weld.C1 = CFrame.new(0,0,-0.6)*CFrame.Angles(0,math.pi,0)
	weld.Name = "CouplerRotate"
	return weld
end

function PGSRotates(coupler1,coupler2)
	local R1 = Instance.new("Part")
	R1.CanCollide = false
	R1.Transparency = 1
	R1.FormFactor = "Plate"
	R1.Size = Vector3.new()
	--R1.CanCollide = false
	R1.TopSurface = "Smooth"
	R1.BottomSurface = "Smooth"
	local R2 = R1:Clone()
	R1.CFrame = coupler1.CFrame
	R2.CFrame = coupler2.CFrame
	rotate(coupler1,R1).Parent = coupler1
	rotate(coupler2,R2).Parent = coupler2
	rotateSpecial(R1,R2).Parent = R1
	R1.Parent = coupler.Parent
	R2.Parent = coupler.Parent
	return R1,R2
end

function Couple(coupler,otherCoupler)
	if PGS then
		coupler.CanCollide = false
		otherCoupler.CanCollide = false
		R1,R2 = PGSRotates(coupler,otherCoupler)
	else
		MyWeld = weld(coupler,otherCoupler)
		MyWeld.Parent = model
	end
	coupler.SoundClose:Play()
end

CoupledTo.Changed:connect(function()
	if CoupledTo.Value then
		--the network ownership means the couplers won't freak out when you couple
		local otherCoupler = CoupledTo.Value:FindFirstChild("Coupler")
		if otherCoupler
		and CoupledTo.Value:FindFirstChild("IsCoupled")
		and CoupledTo.Value.IsCoupled:IsA("BoolValue")
		and CoupledTo.Value.IsCoupled.Value
		then
			--continue
		else
			return
		end
		local owner = coupler:GetNetworkOwner()
		local otherOwner = otherCoupler:GetNetworkOwner()
		local ownerAuto = coupler:GetNetworkOwnershipAuto()
		local otherOwnerAuto = otherCoupler:GetNetworkOwnershipAuto()
		if coupler:CanSetNetworkOwnership() then
			coupler:SetNetworkOwner(nil)
		end
		if CoupledTo.Value.Coupler:CanSetNetworkOwnership() then
			coupler:SetNetworkOwner(nil)
		end
		Couple(coupler,otherCoupler)
		if coupler:CanSetNetworkOwnership() then
			if ownerAuto and otherOwnerAuto then
				coupler:SetNetworkOwnershipAuto()
			elseif ownerAuto then
				coupler:SetNetworkOwner(otherOwner)
			elseif otherOwnerAuto then
				coupler:SetNetworkOwner(owner)
			else
				coupler:SetNetworkOwner(owner)
			end
		end
		wait()
		if PGS then
			WeldDisappear = coupler.ChildRemoved:connect(function(it)
				if it.Name == "CouplerRotate" then
					Decouple()
					WeldDisappear:disconnect()
				end
			end)
		else
			WeldDisappear = MyWeld.AncestryChanged:connect(function()
				Decouple()
				WeldDisappear:disconnect()
			end)
		end
	else
		coupler.CanCollide = true
	end
end)

coupler.Touched:connect(function(TouchedPart)
	if TouchedPart.Parent and TouchedPart.Name == "Coupler" then--make sure the part still exists and that it is called "Coupler" (a good indicator)
		local OtherCoupler = TouchedPart.Parent
		local OtherAllow = OtherCoupler:FindFirstChild("Allow")--make sure this is a coupler by looking for the value that says we can couple
		local OtherIsCoupled = OtherCoupler:FindFirstChild("IsCoupled")--make sure this is a coupler by looking for the value that says it is coupled
		if OtherAllow and OtherIsCoupled then
			if OtherAllow.Value == true
			and Allow.Value == true
			and OtherIsCoupled.Value == false
			and IsCoupled.Value == false
			then
				IsCoupled.Value = true
				OtherIsCoupled.Value = true
				CoupledTo.Value = OtherCoupler
				if OtherCoupler:FindFirstChild("CoupledTo") then
					OtherCoupler.CoupledTo.Value = model
				end
			end
		end
	end
end)
