diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index 9a33c75a65d27c00806cccf2aebcdf11635c8267..950083934fc188294e03b0dd97c76566a588efb9 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -363,7 +363,7 @@ void LLInspectObject::updateButtons(LLSelectNode* nodep)
 		|| (parent && parent->flagHandleTouch()))
 	{
 		getChild<LLUICtrl>("touch_btn")->setVisible(true);
-// [RLVa:KB] - Checked: 2010-11-12 (RLVa-1.2.1g) | Added: RLVa-1.2.1g
+// [RLVa:KB] - Checked: RLVa-1.2.1
 		if (RlvActions::isRlvEnabled())
 			getChild<LLUICtrl>("touch_btn")->setEnabled(RlvActions::canTouch(object));
 // [/RLVa:KB]
diff --git a/indra/newview/lltoolface.cpp b/indra/newview/lltoolface.cpp
index f6697f65ed59729a178e88f6f8e6faf3e65eba6d..f380de18377f1439408206d3fd779ca23e3dd5aa 100644
--- a/indra/newview/lltoolface.cpp
+++ b/indra/newview/lltoolface.cpp
@@ -39,9 +39,8 @@
 #include "llviewerobject.h"
 #include "llviewerwindow.h"
 #include "llfloatertools.h"
-// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e)
+// [RLVa:KB] - Checked: RLVa-2.1.0
 #include "rlvactions.h"
-#include "rlvhandler.h"
 // [/RLVa:KB]
 
 //
@@ -94,10 +93,8 @@ void LLToolFace::pickCallback(const LLPickInfo& pick_info)
 			return;
 		}
 
-// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
-		if ( (RlvActions::isRlvEnabled()) &&
-			 ( (!RlvActions::canEdit(hit_obj)) || 
-			   ((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!RlvActions::canTouch(hit_obj, pick_info.mObjectOffset))) ) )
+// [RLVa:KB] - Checked: RLVa-1.3.0
+		if ( (RlvActions::isRlvEnabled()) && ((!RlvActions::canEdit(hit_obj)) || (!RlvActions::canInteract(hit_obj, pick_info.mObjectOffset))) )
 		{
 			return;
 		}
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index 5dfd345875ac3ec3c5e07b750b120b50de7f858a..2fce58088eda06d550b2642380d3aaad434e0061 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -57,9 +57,8 @@
 #include "llvoavatarself.h"
 #include "llworld.h"
 #include "llmenugl.h"
-// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e)
+// [RLVa:KB] - Checked: RLVa-2.1.0
 #include "rlvactions.h"
-#include "rlvhandler.h"
 // [/RLVa:KB]
 
 const S32 SLOP_DIST_SQ = 4;
@@ -175,7 +174,7 @@ void LLToolGrab::pickCallback(const LLPickInfo& pick_info)
 
 	// if not over object, do nothing
 //	if (!objectp)
-// [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Added: RLVa-1.1.0l
+// [RLVa:KB] - Checked: RLVa-1.1.0
 	// Block initiating a drag operation on an object that can't be touched
 	if ( (!objectp) || ((RlvActions::isRlvEnabled()) && (!RlvActions::canTouch(objectp, pick_info.mObjectOffset))) )
 // [/RLVa:KB]
@@ -439,10 +438,9 @@ BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
 		return TRUE;
 	}
 
-// [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l
-	// Block dragging an object beyond touch range when @fartouch=n restricted
-	if ( (RlvActions::isRlvEnabled()) && (GRAB_INACTIVE != mMode) && (GRAB_NOOBJECT != mMode) && (hasMouseCapture()) &&
-		 (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!RlvActions::canTouch(mGrabPick.getObject(), mGrabPick.mObjectOffset)) )
+// [RLVa:KB] - Checked: RLVa-1.1.0
+	// Block dragging an object beyond touch range
+	if ( (RlvActions::isRlvEnabled()) && (GRAB_INACTIVE != mMode) && (GRAB_NOOBJECT != mMode) && (hasMouseCapture()) && (!RlvActions::canTouch(mGrabPick.getObject(), mGrabPick.mObjectOffset)) )
 	{
 		if (gGrabTransientTool)
 		{
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 20965d88f69ee71092801541fcd27495294ed201..a151a271e862f4105706c7c7ea0aeee0079fd2d5 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -206,10 +206,9 @@ BOOL LLToolPie::handleLeftClickPick()
 	// If it's a left-click, and we have a special action, do it.
 	if (useClickAction(mask, object, parent))
 	{
-// [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l
-		// Block left-click special actions when fartouch restricted
-		if ( (RlvActions::isRlvEnabled()) && 
-			 (gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) && (!RlvActions::canTouch(object, mPick.mObjectOffset)) )
+// [RLVa:KB] - Checked: RLVa-1.1.0
+		// Blanket block all left-click special actions on objects the user can't interact with
+		if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canInteract(object, mPick.mObjectOffset)) )
 		{
 			return TRUE;
 		}
@@ -336,7 +335,7 @@ BOOL LLToolPie::handleLeftClickPick()
 		((object->flagUsePhysics() || (parent && !parent->isAvatar() && parent->flagUsePhysics())) || touchable) 
 		)
 	{
-// [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l
+// [RLVa:KB] - Checked: RLVa-1.1.0
 		// Triggered by left-clicking on a touchable object
 		if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canTouch(object, mPick.mObjectOffset)) )
 		{
@@ -580,20 +579,15 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 	mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE, FALSE);
 	LLViewerObject *parent = NULL;
 	LLViewerObject *object = mHoverPick.getObject();
-// [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l
-	// Block all special click action cursors when:
-	//   - @fartouch=n restricted and the object is out of range
-	//   - @interact=n restricted and the object isn't a HUD attachment
-	if ( (object) && (RlvActions::isRlvEnabled()) && 
-		( ((gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH))) && (!RlvActions::canTouch(object, mHoverPick.mObjectOffset)) || 
-		  ((gRlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) && (!object->isHUDAttachment())) ) )
+// [RLVa:KB] - Checked: RLVa-1.1.0
+	// Blanket block all left-click special actions on objects the user can't interact with
+	if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canInteract(object, mHoverPick.mObjectOffset)) )
 	{
 		gViewerWindow->setCursor(UI_CURSOR_ARROW);
 		return TRUE;
 	}
 // [/RLVa:KB]
 	LLSelectMgr::getInstance()->setHoverObject(object, mHoverPick.mObjectFace);
-
 	if (object)
 	{
 		parent = object->getRootEdit();
@@ -647,10 +641,10 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 			gViewerWindow->setCursor(cursor);
 			LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
 		}
-// [RLVa:KB] - Checked: 2010-03-11 (RLVa-1.2.0e) | Added: RLVa-1.1.0l
-		else if ( (object) && (RlvActions::isRlvEnabled()) && (!RlvActions::canTouch(object)) )
+// [RLVa:KB] - Checked: RLVa-1.1.0
+		else if ( (object) && (RlvActions::isRlvEnabled()) && (!RlvActions::canTouch(object, mHoverPick.mObjectOffset)) )
 		{
-			// Block showing the "grab" or "touch" cursor if we can't touch the object (@fartouch=n is handled above)
+			// Block showing the "grab" or "touch" cursor if we can't touch/grab the object
 			gViewerWindow->setCursor(UI_CURSOR_ARROW);
 		}
 // [/RLVa:KB]
@@ -1122,10 +1116,10 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 			LLAvatarName av_name;
 			if (LLAvatarNameCache::get(hover_object->getID(), &av_name))
 			{
-//				final_name = av_name.getCompleteName();
 // [RLVa:KB] - Checked: RLVa-1.2.2
 				final_name = (RlvActions::canShowName(RlvActions::SNC_DEFAULT, hover_object->getID())) ? av_name.getCompleteName() : RlvStrings::getAnonym(av_name);
 // [/RLVa:KB]
+//				final_name = av_name.getCompleteName();
 			}
 			else
 			{
@@ -1135,8 +1129,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 			// *HACK: We may select this object, so pretend it was clicked
 			mPick = mHoverPick;
 // [RLVa:KB] - Checked: RLVa-1.2.0
-			if ( (!RlvActions::isRlvEnabled()) || 
-			     ( (RlvActions::canTouch(hover_object, mHoverPick.mObjectOffset)) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, hover_object->getID())) ) )
+			if ( (!RlvActions::isRlvEnabled()) ||
+			     ( (RlvActions::canInteract(hover_object, mHoverPick.mObjectOffset)) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, hover_object->getID())) ) )
 			{
 // [/RLVa:KB]
 				LLInspector::Params p;
@@ -1150,7 +1144,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 				p.wrap(false);
 				
 				LLToolTipMgr::instance().show(p);
-// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.2a) | Added: RLVa-1.2.0e
+// [RLVa:KB] - Checked: RLVa-1.2.0
 			}
 			else
 			{
@@ -1259,9 +1253,8 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 			{
 				// We may select this object, so pretend it was clicked
 				mPick = mHoverPick;
-// [RLVa:KB] - Checked: 2010-11-12 (RLVa-1.2.1g) | Modified: RLVa-1.2.1g
-				if ( (!RlvActions::isRlvEnabled()) || (!gRlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) ||
-					 (RlvActions::canTouch(hover_object, mHoverPick.mObjectOffset)) )
+// [RLVa:KB] - Checked: RLVa-1.2.1
+				if ( (!RlvActions::isRlvEnabled()) || (RlvActions::canInteract(hover_object, mHoverPick.mObjectOffset)) )
 				{
 // [/RLVa:KB]
 					LLInspector::Params p;
@@ -1280,7 +1273,7 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 					p.wrap(false);
 					
 					LLToolTipMgr::instance().show(p);
-// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e
+// [RLVa:KB] - Checked: RLVa-1.2.0
 				}
 				else
 				{
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index 9b39175ab2d82526cc9e29ab53f99d6e455e9cc7..9fe3572e4ac8af976e049cfa45e71ce8dde10582 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -332,20 +332,34 @@ bool RlvActions::canBuild()
 		(!gRlvHandler.hasBehaviour(RLV_BHVR_REZ));
 }
 
-bool RlvActions::canEdit()
-{
-	return (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT));
-}
-
+// Handles: @edit and @editobj
 bool RlvActions::canEdit(const LLViewerObject* pObj)
 {
 	// User can edit the specified object if:
 	//   - not generally restricted from editing (or the object's root is an exception)
 	//   - not specifically restricted from editing this object's root
+
+	// NOTE-RLVa: edit checks should *never* be subject to @fartouch distance checks since we don't have the pick offset so
+	//            instead just implicitly rely on the presence of a (transient) selection
 	return
 		(pObj) &&
-		((!hasBehaviour(RLV_BHVR_EDIT)) || (gRlvHandler.isException(RLV_BHVR_EDIT, pObj->getRootEdit()->getID()))) &&
-		((!hasBehaviour(RLV_BHVR_EDITOBJ)) || (!gRlvHandler.isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())));
+		( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDIT)) || (RlvHandler::instance().isException(RLV_BHVR_EDIT, pObj->getRootEdit()->getID())) ) &&
+		( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDITOBJ)) || (!RlvHandler::instance().isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())) );
+}
+
+// Handles: @fartouch and @interact
+bool RlvActions::canInteract(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/)
+{
+	static RlvCachedBehaviourModifier<float> s_nFartouchDist(RLV_MODIFIER_FARTOUCHDIST);
+
+	// User can interact with the specified object if:
+	//   - not interaction restricted (or the specified object is a HUD attachment)
+	//   - not prevented from touching faraway objects (or the object's center + pick offset is within range)
+	RlvHandler& rlvHandler = RlvHandler::instance();
+	return
+		(!pObj) ||
+		( ( (!rlvHandler.hasBehaviour(RLV_BHVR_INTERACT)) || (pObj->isHUDAttachment())) &&
+		  ( (!rlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (pObj->isHUDAttachment()) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= s_nFartouchDist * s_nFartouchDist)) );
 }
 
 bool RlvActions::canRez()
@@ -353,7 +367,7 @@ bool RlvActions::canRez()
 	return (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ));
 }
 
-bool RlvActions::canSit(const LLViewerObject* pObj, const LLVector3& posOffset /*= LLVector3::zero*/)
+bool RlvActions::canSit(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/)
 {
 	// User can sit on the specified object if:
 	//   - not prevented from sitting
@@ -401,21 +415,21 @@ bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset
 	//        - a) not prevented from touching any object
 	//        - b) not specifically prevented from touching that object
 	//        - c) not prevented from touching world objects (or the object is an exception)
-	//        - h) not prevented from touching faraway objects (or the object's root + pick offset is within range)
+	//        - h) not prevented from touching faraway objects (or the object's center + pick offset is within range)
 	//        - i) specifically allowed to touch that object (overrides all restrictions)
 	//  (2) Attachment (on another avatar)
 	//        - a) not prevented from touching any object
 	//        - b) not specifically prevented from touching that object
 	//        - d) not prevented from touching attachments (or the attachment is an exception)
 	//        - e) not prevented from touching other avatar's attachments (or the attachment is an exception)
-	//        - h) not prevented from touching faraway objects (or the attachment's root + pick offset is within range)
+	//        - h) not prevented from touching faraway objects (or the attachment's center + pick offset is within range)
 	//        - i) specifically allowed to touch that object (overrides all restrictions)
 	//  (3) Attachment (on own avatar)
 	//        - a) not prevented from touching any object
 	//        - b) not specifically prevented from touching that object
 	//        - d) not prevented from touching attachments (or the attachment is an exception)
 	//        - f) not prevented from touching their own avatar's attachments (or the attachment is an exception)
-	//        - h) not prevented from touching faraway objects (or the attachment's root + pick offset is within range)
+	//        - h) not prevented from touching faraway objects (or the attachment's center + pick offset is within range)
 	//        - i) specifically allowed to touch that object (overrides all restrictions)
 	//  (4) Attachment (on HUD)
 	//        - b) not specifically prevented from touching that object
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index 0f06c41428965fd0e35e5e8e4a3f20bf19c87924..0bdfed2058b8c5c377acd05066e09ff755ee77a5 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -194,6 +194,12 @@ public:
 	// =================
 	// World interaction
 	// =================
+	// Terminology:
+	//   - build    : <todo>
+	//   - edit     : ability to get access an object from the build floater, or being able to look at its contents (i.e. open)
+	//   - interact : ability to interact with an object/avatar in any way or shape (i.e. touch, edit, click, grab, move, ...)
+	//   - rez      : ability to rez new objects (from either inventory or through the create tool)
+	//   - touch    : singularly refers to the ability to either invoke the scripted touch handler, or perform a physical grab
 public:
 	/*
 	 * Returns true if the user can build (= access the build tools)
@@ -201,25 +207,21 @@ public:
 	static bool canBuild();
 
 	/*
-	 * Returns true if the user can edit existing objects (generic check not based on specific object type)
+	 * Returns true if the user can edit the specified object (with an optional relative offset)
 	 */
-	static bool canEdit();
+	static bool canEdit(const LLViewerObject* pObj);
 
 	/*
-	 * Returns true if the user can edit the specified object
+	 * Returns true if the user can interact with the specified object (with an optional relative offset)
+	 * (returns true if pObj == nullptr to not short circuit calling code)
 	 */
-	static bool canEdit(const LLViewerObject* pObj);
+	static bool canInteract(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
 
 	/*
 	 * Returns true if the user can rez new objects (from inventory or through the create tool)
 	 */
 	static bool canRez();
 
-	/*
-	 * Returns true if the user can sit up on the specified object
-	 */
-	static bool canSit(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
-
 	/*
 	 * Returns true if the user can see the hovertext associated with the specified object
 	 */
@@ -231,15 +233,20 @@ public:
 	static bool canTouch(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
 
 	/*
-	 * Returns true if the user can stand up (returns true if the user isn't currently sitting)
+	 * Returns true if the user can see their in-world location
 	 */
-	static bool canStand();
-	static bool canStand(const LLUUID& idRlvObjExcept);
+	static bool canShowLocation();
 
 	/*
-	 * Returns true if the user can see their in-world location
+	 * Returns true if the user can sit up on the specified object
 	 */
-	static bool canShowLocation();
+	static bool canSit(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero);
+
+	/*
+	 * Returns true if the user can stand up (returns true if the user isn't currently sitting)
+	 */
+	static bool canStand();
+	static bool canStand(const LLUUID& idRlvObjExcept);
 
 	// ================
 	// Helper functions