function CharacterRealism.UpdateLookAngles(J,E)local Z,y=J:ComputeLookAngle()J:OnLookReceive(J.Player,Z,y)local p=J.LastUpdate or 0 local K=os.clock()if K-p>.5 then Z=Util:RoundNearestInterval(Z,.05)y=Util:RoundNearestInterval(y,.05)if Z~=J.Pitch then J.Pitch=Z J.Dirty=true end if y~=J.Yaw then J.Yaw=y J.Dirty=true end if J.Dirty then J.Dirty=false J.LastUpdate=K J.SetLookAngles:FireServer(Z,y)end end local e=workspace.CurrentCamera local S=e.CFrame.Position local k=J.Player local u for E,Z in pairs(J.Rotators)do if not E.Parent then if not u then u={}end u[E]=true continue end local y=Players:GetPlayerFromCharacter(E)local p=y and y:DistanceFromCharacter(S)or 0 if y~=k and p>30 then continue end local e=Z.LastStep or 0 local A=K-e local i=E:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")local o=i and i.RootPart if not o then continue end local r=Z.Pitch J:StepValue(r,A)local M=Z.Yaw J:StepValue(M,A)local G=Z.Motors Z.LastStep=K if not G then continue end for J,y in pairs(J.RotationFactors)do local p=G and G[J]if not p then continue end local K=p.Motor local e=p.Origin if e then local E=K.Part0 local J=e.Parent if E and E~=J then local J=E:FindFirstChild(e.Name)if J and J:IsA("\065\116\116\097\099\104\109\101\110\116")then e=J p.Origin=J end end e=e.CFrame elseif p.C0 then e=p.C0 else continue end local S=r.Current or 0 local k=M.Current or 0 if Z.SnapFirstPerson and J=="\072\101\097\100"then if FpsCamera:IsInFirstPerson()then S=r.Goal k=M.Goal end end local u=S*y.Pitch local A=k*y.Yaw if J:sub(-4)==" \065\114\109"or J:sub(-8)=="\085\112\112\101\114\065\114\109"then local Z=E:FindFirstChildOfClass("\084\111\111\108")if Z and not CollectionService:HasTag(Z,"\078\111\065\114\109\082\111\116\097\116\105\111\110")then if J:sub(1,5)=="\082\105\103\104\116"and o:GetRootPart()~=o then u=S*1.3 A=k*1.3 elseif J:sub(1,4)=="\076\101\102\116"and o:GetRootPart()~=o then u=S*1 A=k*1.5 else A=k*.8 end end end local i=false if u~=r.Value then r.Value=u i=true end if A~=M.Value then M.Value=A i=true end if i then local E=e-e.Position local J=CFrame.Angles(0,u,0)*CFrame.Angles(A,0,0)K.C0=((e*E:Inverse())*J)*E end end end if u then for E in pairs(u)do local Z=J.Rotators[E]local y=Z and Z.Listener if y then y:Disconnect()end J.Rotators[E]=nil end end end


function CharacterRealism:UpdateLookAngles(delta)
	-- Update our own look-angles with no latency
	local pitch, yaw = self:ComputeLookAngle()
	self:OnLookReceive(self.Player, pitch, yaw)
	
	-- Submit our look-angles if they have changed enough.
	local lastUpdate = self.LastUpdate or 0
	local now = os.clock()
	
	if (now - lastUpdate) > .5 then
		pitch = Util:RoundNearestInterval(pitch, .05)
		yaw = Util:RoundNearestInterval(yaw, .05)

		if pitch ~= self.Pitch then
			self.Pitch = pitch
			self.Dirty = true
		end

		if yaw ~= self.Yaw then
			self.Yaw = yaw
			self.Dirty = true
		end
		
		if self.Dirty then
			self.Dirty = false
			self.LastUpdate = now
			self.SetLookAngles:FireServer(pitch, yaw)	
		end
	end
	
	-- Update all of the character look-angles
	local camera = workspace.CurrentCamera
	local camPos = camera.CFrame.Position
	
	local player = self.Player
	local dropList
	
	for character, rotator in pairs(self.Rotators) do
		if not character.Parent then
			if not dropList then
				dropList = {}
			end
			
			dropList[character] = true
			continue
		end
		
		local owner = Players:GetPlayerFromCharacter(character)
		local dist = owner and owner:DistanceFromCharacter(camPos) or 0

		if owner ~= player and dist > 30 then
			continue
		end
		
		local lastStep = rotator.LastStep or 0
		local stepDelta = now - lastStep

		local humanoid = character:FindFirstChildOfClass("Humanoid")
		local rootPart = humanoid and humanoid.RootPart

		if not rootPart then
			continue
		end
		
		local pitchState = rotator.Pitch
		self:StepValue(pitchState, stepDelta)

		local yawState = rotator.Yaw
		self:StepValue(yawState, stepDelta)
		
		local motors = rotator.Motors
		rotator.LastStep = now
		
		if not motors then
			continue
		end
		
		for name, factors in pairs(self.RotationFactors) do
			local data = motors and motors[name]

			if not data then
				continue
			end

			local motor = data.Motor
			local origin = data.Origin
			
			if origin then
				local part0 = motor.Part0
				local setPart0 = origin.Parent
				
				if part0 and part0 ~= setPart0 then
					local newOrigin = part0:FindFirstChild(origin.Name)

					if newOrigin and newOrigin:IsA("Attachment") then
						origin = newOrigin
						data.Origin = newOrigin
					end
				end
				
				origin = origin.CFrame
			elseif data.C0 then
				origin = data.C0
			else
				continue
			end

			local pitch = pitchState.Current or 0
			local yaw = yawState.Current or 0

			if rotator.SnapFirstPerson and name == "Head" then
				if FpsCamera:IsInFirstPerson() then
					pitch = pitchState.Goal
					yaw = yawState.Goal
				end
			end

			local fPitch = pitch * factors.Pitch
			local fYaw = yaw * factors.Yaw

			-- HACK: Make the arms rotate with a tool.
			if name:sub(-4) == " Arm" or name:sub(-8) == "UpperArm" then
				local tool = character:FindFirstChildOfClass("Tool")
				
				if tool and not CollectionService:HasTag(tool, "NoArmRotation") then
					if name:sub(1, 5) == "Right" and rootPart:GetRootPart() ~= rootPart then
						fPitch = pitch * 1.3
						fYaw = yaw * 1.3
						
					elseif name:sub(1, 4) == "Left" and rootPart:GetRootPart() ~= rootPart then
						fPitch = pitch * 1
						fYaw = yaw * 1.5
						
					else
						fYaw = yaw * .8
					end
				end
			end

			local dirty = false

			if fPitch ~= pitchState.Value then
				pitchState.Value = fPitch
				dirty = true
			end

			if fYaw ~= yawState.Value then
				yawState.Value = fYaw
				dirty = true
			end

			if dirty then
				local rot = origin - origin.Position
				
				local cf = CFrame.Angles(0, fPitch, 0)
				         * CFrame.Angles(fYaw, 0, 0)
				
				motor.C0 = origin * rot:Inverse() * cf * rot
			end
		end
	end
	
	-- If the dropList is declared, remove any characters that 
	-- were indexed into it. This is done after iterating over
	-- the rotators to avoid problems with removing data from
	-- a table while iterating over said table.
	
	if dropList then
		for character in pairs(dropList) do
			local rotator = self.Rotators[character]
			local listener = rotator and rotator.Listener
			
			if listener then
				listener:Disconnect()
			end
			
			self.Rotators[character] = nil
		end
	end
end
