diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index 2dc4cc086fae4f3e3a2d47b68702aba1222f8658..22d1b63d5a652a3932282fcf78cf571d1c5862d9 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -57,9 +57,9 @@
 #include "llviewerjoystick.h"
 #include "llviewermenu.h"
 #include "llviewerparcelmgr.h"
-// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e)
-#include "rlvhandler.h"
-#include "rlvui.h"
+// [RLVa:KB] - Checked: RLVa-2.1.0
+#include "llfloatertools.h"
+#include "rlvactions.h"
 // [/RLVa:KB]
 
 // Used when app not active to avoid processing hover.
@@ -85,14 +85,9 @@ LLToolMgr::LLToolMgr()
 {
 	// Not a panel, register these callbacks globally.
 	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Active", boost::bind(&LLToolMgr::inEdit, this));
-//	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&LLToolMgr::canEdit, this));
-//	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.EnabledOrActive", boost::bind(&LLToolMgr::buildEnabledOrActive, this));
-//	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this, _2));
-// [RLVa:KB] - Checked: 2010-09-11 (RLVa-1.2.1d) | Added: RLVa-1.2.1d
-	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&RlvUIEnabler::isBuildEnabled));
-	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.EnabledOrActive", boost::bind(&RlvUIEnabler::isBuildEnabledOrActive));
-	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this));
-// [/RLVa:KB]
+	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.Enabled", boost::bind(&LLToolMgr::canEdit, this));
+	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Build.EnabledOrActive", boost::bind(&LLToolMgr::buildEnabledOrActive, this));
+	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Build.Toggle", boost::bind(&LLToolMgr::toggleBuildMode, this, _2));
 	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Marketplace.Enabled", boost::bind(&LLToolMgr::canAccessMarketplace, this));
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Marketplace.Toggle", boost::bind(&LLToolMgr::toggleMarketplace, this, _2));
 	
@@ -270,18 +265,18 @@ bool LLToolMgr::inEdit()
 
 bool LLToolMgr::canEdit()
 {
-	return LLViewerParcelMgr::getInstance()->allowAgentBuild();
+// [RLVa:KB] - Patch: RLVa-2.1.0
+	return LLViewerParcelMgr::getInstance()->allowAgentBuild() && RlvActions::canBuild();
+// [/RLVa:KB]
+//	return LLViewerParcelMgr::getInstance()->allowAgentBuild();
 }
 
-//bool LLToolMgr::buildEnabledOrActive()
-//{
-//	return inEdit() || canEdit();
-//}
+bool LLToolMgr::buildEnabledOrActive()
+{
+	return inEdit() || canEdit();
+}
 
-//void LLToolMgr::toggleBuildMode(const LLSD& sdname)
-// [RLVa:KB] - Checked: 2012-04-26 (RLVa-1.4.6) | Added: RLVa-1.4.6
-void LLToolMgr::toggleBuildMode()
-// [/RLVa:KB]
+void LLToolMgr::toggleBuildMode(const LLSD& sdname)
 {
 //	const std::string& param = sdname.asString();
 //
@@ -290,10 +285,36 @@ void LLToolMgr::toggleBuildMode()
 //	{
 //		return;
 //	}
+//
+//	bool build_visible = LLFloaterReg::instanceVisible("build");
+//	if (build_visible)
+//	{
+// [RLVa:KB] - Checked: RLVa-2.1.0
+	if (gFloaterTools)
+	{
+		if (gFloaterTools->isShown())
+			leaveBuildMode();
+		else
+			enterBuildMode("build" == sdname.asString());
+	}
+}
+
+void LLToolMgr::enterBuildMode(bool verify_canedit /*=false*/)
+{
+	if (!gFloaterTools)
+		return;
+	if (!gFloaterTools->isShown())
+		gFloaterTools->openFloater();
+	if (!gFloaterTools->isFrontmost())
+		gFloaterTools->setVisibleAndFrontmost(true);
 
-	bool build_visible = LLFloaterReg::instanceVisible("build");
-	if (build_visible)
+	if (verify_canedit && !canEdit())
 	{
+		return;
+	}
+
+	{
+// [/RLVa:KB]
 		ECameraMode camMode = gAgentCamera.getCameraMode();
 		if (CAMERA_MODE_MOUSELOOK == camMode ||	CAMERA_MODE_CUSTOMIZE_AVATAR == camMode)
 		{
@@ -332,7 +353,20 @@ void LLToolMgr::toggleBuildMode()
 		LLViewerJoystick::getInstance()->setNeedsReset();
 
 	}
-	else
+// [RLVa:KB] - Checked: RLVa-2.1.0
+}
+// [/RLVa:KB]
+//	else
+// [RLVa:KB] - Checked: RLVa-2.1.0
+void LLToolMgr::leaveBuildMode()
+{
+	if ( (!gFloaterTools) || (!gFloaterTools->getVisible()) )
+	{
+		return;
+	}
+
+	gFloaterTools->closeFloater();
+// [/RLVa:KB]
 	{
 		if (gSavedSettings.getBOOL("EditCameraMovement"))
 		{
diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h
index 4944c6ed71c3d423d23a4b58e783a3a98d921d74..5a64723b336150b6fad8b79db5c8055bcaa30766 100644
--- a/indra/newview/lltoolmgr.h
+++ b/indra/newview/lltoolmgr.h
@@ -56,10 +56,11 @@ public:
 	bool			canEdit();
 	bool 			buildEnabledOrActive();
     bool            canAccessMarketplace();
-// [RLVa:KB] - Checked: 2012-04-26 (RLVa-1.4.6) | Added: RLVa-1.4.6
-	void			toggleBuildMode();
+	void			toggleBuildMode(const LLSD& sdname);
+// [RLVa:KB] - Checked: RLVa-2.1.0
+	void			enterBuildMode(bool verify_canedit = false);
+	void			leaveBuildMode();
 // [/RLVa:KB]
-//	void			toggleBuildMode(const LLSD& sdname);
 	void			toggleMarketplace(const LLSD& sdname);
 	
 	/* Determines if we are in Build mode or not. */
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 2cd221c351b9340098ff23cfec9e6d8cd823647d..92f8db9ddba332c0c1b10ebcc555731d6895df5c 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -86,7 +86,7 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
 		object = object->getRootEdit();
 	}
 
-// [RLVa:KB] - Checked: 2010-11-29 (RLVa-1.3.0c) | Modified: RLVa-1.3.0c
+// [RLVa:KB] - Checked: RLVa-2.1.0
 	if ( (object) && (RlvActions::isRlvEnabled()) )
 	{
 		if (!RlvActions::canEdit(object))
@@ -94,23 +94,31 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
 			if (!temp_select)
 				return LLSelectMgr::getInstance()->getSelection();
 			else if (LLToolMgr::instance().inBuildMode())
-				LLToolMgr::instance().toggleBuildMode();
+				LLToolMgr::instance().leaveBuildMode();
 		}
 
-		if ( (RlvActions::hasBehaviour(RLV_BHVR_FARTOUCH)) && ((!object->isAttachment()) || (!object->permYouOwner())) )
+		if ( (RlvActions::hasBehaviour(RLV_BHVR_FARTOUCH)) && ( (!object->isAttachment()) || (!object->permYouOwner())) )
 		{
 			static RlvCachedBehaviourModifier<float> s_nFartouchDist(RLV_MODIFIER_FARTOUCHDIST);
 			float nFartouchDistSq = s_nFartouchDist * s_nFartouchDist;
-			// NOTE: recheck why we did it this way, might be able to simplify
-			if ( (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion()) > nFartouchDistSq) &&
-			     (dist_vec_squared(gAgent.getPositionAgent(), pick.mIntersection) > nFartouchDistSq) )
+
+			// User is allowed to edit/select this object if it's within their current fartouch distance
+			if (dist_vec_squared(gAgent.getPositionAgent(), object->getPositionRegion()) > nFartouchDistSq)
 			{
-				if ( (LLFloaterReg::instanceVisible("build")) && (pick.mKeyMask != MASK_SHIFT) && (pick.mKeyMask != MASK_CONTROL) )
-					LLSelectMgr::getInstance()->deselectAll();
-				return LLSelectMgr::getInstance()->getSelection();
+				// The object is out of range but we'll still allow them a temporary select (e.g. context menu) if the surface point is within range
+				if (dist_vec_squared(gAgent.getPositionAgent(), pick.mIntersection) > 1.5f * 1.5f)
+				{
+					// Even the surface point is out of range so deny them the hit
+					if ( (LLFloaterReg::instanceVisible("build")) && (pick.mKeyMask != MASK_SHIFT) && (pick.mKeyMask != MASK_CONTROL) )
+						LLSelectMgr::getInstance()->deselectAll();
+					return LLSelectMgr::getInstance()->getSelection();
+				}
+				else if (LLToolMgr::instance().inBuildMode())
+				{
+					// Allow the selection but keep it temporary by pulling them out of build mode when they click too far
+					LLToolMgr::instance().leaveBuildMode();
+				}
 			}
-			else if (LLToolMgr::instance().inBuildMode())
-				LLToolMgr::instance().toggleBuildMode();
 		}
 	}
 // [/RLVa:KB]
diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp
index 913ded899cb48f47d7cefb0f0a255730f5b08335..b41302b5bfefc1ae4636b86bed2f229b637ee221 100644
--- a/indra/newview/rlvactions.cpp
+++ b/indra/newview/rlvactions.cpp
@@ -282,6 +282,21 @@ bool RlvActions::isLocalTp(const LLVector3d& posGlobal)
 // World interaction
 //
 
+bool RlvActions::canBuild()
+{
+	// User can access the build floater if:
+	//    - allowed to edit existing objects OR
+	//    - allowed to rez/create objects
+	return
+		(!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) ||
+		(!gRlvHandler.hasBehaviour(RLV_BHVR_REZ));
+}
+
+bool RlvActions::canEdit()
+{
+	return (!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT));
+}
+
 bool RlvActions::canEdit(const LLViewerObject* pObj)
 {
 	// User can edit the specified object if:
@@ -293,6 +308,10 @@ bool RlvActions::canEdit(const LLViewerObject* pObj)
 		((!hasBehaviour(RLV_BHVR_EDITOBJ)) || (!gRlvHandler.isException(RLV_BHVR_EDITOBJ, pObj->getRootEdit()->getID())));
 }
 
+bool RlvActions::canRez()
+{
+	return (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ));
+}
 
 bool RlvActions::canSit(const LLViewerObject* pObj, const LLVector3& posOffset /*= LLVector3::zero*/)
 {
diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h
index c034e829a1a960b178975f5eeed6403497fd5cd5..6b2108763598ab4f261bba5aba9ec6c3b25fda57 100644
--- a/indra/newview/rlvactions.h
+++ b/indra/newview/rlvactions.h
@@ -171,11 +171,26 @@ public:
 	// World interaction
 	// =================
 public:
+	/*
+	 * Returns true if the user can build (= access the build tools)
+	 */
+	static bool canBuild();
+
+	/*
+	 * Returns true if the user can edit existing objects (generic check not based on specific object type)
+	 */
+	static bool canEdit();
+
 	/*
 	 * Returns true if the user can edit the specified object
 	 */
 	static bool canEdit(const LLViewerObject* pObj);
 
+	/*
+	 * 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
 	 */
diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index 3500252033bffcc9bcfc58eaf6dbbd30902960b8..bb3bc4e34fe8bd20b9e210bedf39e6a74d32b1b3 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -1623,9 +1623,8 @@ void RlvBehaviourToggleHandler<RLV_BHVR_EDIT>::onCommandToggle(ERlvBehaviour eBh
 		if (LLFloaterReg::instanceVisible("beacons"))
 			LLFloaterReg::hideInstance("beacons");
 
-		// Hide the build floater if it's currently visible
-		if (LLFloaterReg::instanceVisible("build"))
-			LLToolMgr::instance().toggleBuildMode();
+		// Hide the build floater
+		LLToolMgr::instance().leaveBuildMode();
 	}
 
 	// Start or stop filtering opening the beacons floater
diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp
index 01d01a061d785471be359dd2d0527f28c917a8b9..5ed9d74dc2c4b601af122e027c7dcc01da330546 100644
--- a/indra/newview/rlvui.cpp
+++ b/indra/newview/rlvui.cpp
@@ -427,15 +427,4 @@ bool RlvUIEnabler::hasOpenProfile(const LLUUID& idAgent)
 	return LLAvatarActions::profileVisible(idAgent);
 }
 
-// Checked: 2010-09-11 (RLVa-1.2.1d) | Added: RLVa-1.2.1d
-bool RlvUIEnabler::isBuildEnabled()
-{
-	return (gAgent.canEditParcel()) && ((!gRlvHandler.hasBehaviour(RLV_BHVR_EDIT)) || (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ)));
-}
-
-bool RlvUIEnabler::isBuildEnabledOrActive()
-{
-	return LLToolMgr::instance().inEdit() || isBuildEnabled();
-}
-
 // ============================================================================
diff --git a/indra/newview/rlvui.h b/indra/newview/rlvui.h
index 841904a86096138640d8167bca7e2539637869b6..81926974ee83e25759f2286120009129131085bc 100644
--- a/indra/newview/rlvui.h
+++ b/indra/newview/rlvui.h
@@ -79,8 +79,6 @@ public:
 	static bool canViewRegionProperties();								// showloc
 	static bool hasOpenIM(const LLUUID& idAgent);						// shownames
 	static bool hasOpenProfile(const LLUUID& idAgent);					// shownames
-	static bool isBuildEnabled();										// edit and rez
-	static bool isBuildEnabledOrActive();								// edit and rez
 
 	/*
 	 * Member variables