local function A(A,X)animation.AnimationId="\114\098\120\097\115\115\101\116\105\100\058\047\047"..X return A:LoadAnimation(animation)end local function X(A,X)X=X or 1 local U,r=A:ToEulerAnglesXYZ()return CFrame.new(A.Position)*CFrame.Angles(0,r*X,0)end local function U(A)if not A then return end local U=A-npcModel.PrimaryPart.Position local r=rotationOffset*CFrame.new(Vector3.new(),U.Unit)or rotationOffset if not waveAnimationTrack.IsPlaying then NPC.Root.Transform=X(r,TwistProportions.Root)NPC.Waist.Transform=X(r,TwistProportions.Waist)end NPC.Neck.Transform=X(r,waveAnimationTrack.IsPlaying and TwistProportions.Full or TwistProportions.Neck)return U.Magnitude end

local function loadAnimation(controller, animationId)
	animation.AnimationId = "rbxassetid://" .. animationId
	return controller:LoadAnimation(animation)
end

local function isolateAndDampenYAngle(targetCFrame, proportionMultiplier)
	proportionMultiplier = proportionMultiplier or 1
	local _, y = targetCFrame:ToEulerAnglesXYZ()
	
	return CFrame.new(targetCFrame.Position) * CFrame.Angles(
		0,
		y * proportionMultiplier,
		0
	)
end

local function makeNPCLookAt(lookAtPosition)
	if not lookAtPosition then
		return
	end
	
	local differenceVector = lookAtPosition - npcModel.PrimaryPart.Position
	local targetCFrame = rotationOffset * CFrame.new(Vector3.new(), differenceVector.Unit) or rotationOffset
	
	-- Let the waving animation move the body
	if not waveAnimationTrack.IsPlaying then
		NPC.Root.Transform = isolateAndDampenYAngle(targetCFrame, TwistProportions.Root)
		NPC.Waist.Transform = isolateAndDampenYAngle(targetCFrame, TwistProportions.Waist)
	end
	NPC.Neck.Transform = isolateAndDampenYAngle(targetCFrame, waveAnimationTrack.IsPlaying and TwistProportions.Full or TwistProportions.Neck)
	
	return differenceVector.Magnitude
end

