Newer
Older
* Copyright (c) 2009-2016, Kitty Barnett
*
* The source code in this file is provided to you under the terms of the
* GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt
* in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt
* By copying, modifying or distributing this software, you acknowledge that
* you have read and understood your obligations described above, and agree to
* abide by those obligations.
*/
#include "llviewerprecompiledheaders.h"
Kitty Barnett
committed
#include "llagent.h"
#include "llviewercamera.h"
#include "llvoavatarself.h"
#include "llworld.h"
Kitty Barnett
committed
#include "rlvhelper.h"
Kitty Barnett
committed
#include "rlvinventory.h"
#include "rlvmodifiers.h"
// ============================================================================
// Camera
//
Kitty Barnett
committed
bool RlvActions::canChangeCameraFOV(const LLUUID& idRlvObject)
{
// NOTE: if an object has exclusive camera control then all other objects are locked out
return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM)) || (RlvHandler::instance().hasBehaviour(idRlvObject, RLV_BHVR_SETCAM));
Kitty Barnett
committed
}
bool RlvActions::canChangeCameraPreset(const LLUUID& idRlvObject)
{
// NOTE: if an object has exclusive camera control then all other objects are locked out
( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM)) || (RlvHandler::instance().hasBehaviour(idRlvObject, RLV_BHVR_SETCAM)) ) &&
(!RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) && (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET));
bool RlvActions::canChangeToMouselook()
{
// User can switch to mouselook if:
// - not specifically prevented from going into mouselook (NOTE: if an object has exclusive camera control only that object can prevent mouselook)
// - there is no minimum camera distance defined (or it's higher than > 0m)
const RlvBehaviourModifier* pCamDistMinModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMIN);
return
( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM)) ? !RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_MOUSELOOK) : !RlvHandler::instance().hasBehaviour(pCamDistMinModifier->getPrimaryObject(), RLV_BHVR_SETCAM_MOUSELOOK) ) &&
( (!pCamDistMinModifier->hasValue()) || (pCamDistMinModifier->getValue<float>() == 0.f) );
}
Kitty Barnett
committed
bool RlvActions::isCameraDistanceClamped()
Kitty Barnett
committed
return
(RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_AVDISTMIN)) || (RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_AVDISTMAX)) ||
(RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_ORIGINDISTMIN)) || (RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_ORIGINDISTMAX));
Kitty Barnett
committed
}
bool RlvActions::isCameraFOVClamped()
{
return (RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_FOVMIN)) || (RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_FOVMAX));
}
bool RlvActions::isCameraPresetLocked()
{
return (RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM)) || (RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) || (RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET));
Kitty Barnett
committed
bool RlvActions::getCameraAvatarDistanceLimits(float& nDistMin, float& nDistMax)
bool fDistMin = RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_AVDISTMIN), fDistMax = RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_AVDISTMAX);
Kitty Barnett
committed
if ( (fDistMin) || (fDistMax) )
{
static RlvCachedBehaviourModifier<float> sCamDistMin(RLV_MODIFIER_SETCAM_AVDISTMIN);
static RlvCachedBehaviourModifier<float> sCamDistMax(RLV_MODIFIER_SETCAM_AVDISTMAX);
nDistMax = (fDistMax) ? sCamDistMax : F32_MAX;
nDistMin = (fDistMin) ? sCamDistMin : 0.0;
return true;
}
return false;
bool RlvActions::getCameraOriginDistanceLimits(float& nDistMin, float& nDistMax)
bool fDistMin = RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_ORIGINDISTMIN), fDistMax = RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_ORIGINDISTMAX);
Kitty Barnett
committed
if ( (fDistMin) || (fDistMax) )
{
static RlvCachedBehaviourModifier<float> sCamDistMin(RLV_MODIFIER_SETCAM_ORIGINDISTMIN);
static RlvCachedBehaviourModifier<float> sCamDistMax(RLV_MODIFIER_SETCAM_ORIGINDISTMAX);
Kitty Barnett
committed
nDistMax = (fDistMax) ? sCamDistMax : F32_MAX;
nDistMin = (fDistMin) ? sCamDistMin : 0.0;
return true;
}
return false;
}
Kitty Barnett
committed
bool RlvActions::getCameraFOVLimits(F32& nFOVMin, F32& nFOVMax)
{
bool fClampMin = RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_FOVMIN), fClampMax = RlvHandler::instance().hasBehaviour(RLV_BHVR_SETCAM_FOVMAX);
Kitty Barnett
committed
if ( (fClampMin) || (fClampMax) )
{
static RlvCachedBehaviourModifier<float> sCamFovMin(RLV_MODIFIER_SETCAM_FOVMIN);
static RlvCachedBehaviourModifier<float> sCamFovMax(RLV_MODIFIER_SETCAM_FOVMAX);
Kitty Barnett
committed
nFOVMin = (fClampMin) ? sCamFovMin : LLViewerCamera::getInstance()->getMinView();
nFOVMax = (fClampMax) ? sCamFovMax : LLViewerCamera::getInstance()->getMaxView();
return true;
}
return false;
// ============================================================================
Kitty Barnett
committed
// Communication/Avatar interaction
Kitty Barnett
committed
bool RlvActions::s_BlockNamesContexts[SNC_COUNT] = { 0 };
bool RlvActions::canChangeActiveGroup(const LLUUID& idRlvObject)
{
// User can change their active group if:
// - not specifically restricted (by another object that the one specified) from changing their active group
return (idRlvObject.isNull()) ? !RlvHandler::instance().hasBehaviour(RLV_BHVR_SETGROUP) : !RlvHandler::instance().hasBehaviourExcept(RLV_BHVR_SETGROUP, idRlvObject);
}
// Little helper function to check the IM exclusion range for @recvim, @sendim and @startim (returns: min_dist <= (pos user - pos target) <= max_dist)
static bool rlvCheckAvatarIMDistance(const LLUUID& idAvatar, ERlvBehaviourModifier eModDistMin, ERlvBehaviourModifier eModDistMax)
{
// | no limits | minimum set | min+max set | !fHasMin | !fHasMax = INF | fHasMax
// -------------------------------------------------------------- ------------------------------------
// dist <= min <= max | block | block | block | F | F | F
// min <= dist <= max | block | allow | allow | F | T | T
// min <= max <= dist | block | allow | block | F | ^ (see above) | F
// off-region | block | allow | block | F | ^ (see above) | F
const RlvBehaviourModifier *pBhvrModDistMin = RlvBehaviourDictionary::instance().getModifier(eModDistMin), *pBhvrModDistMax = RlvBehaviourDictionary::instance().getModifier(eModDistMax);
if (pBhvrModDistMin->hasValue())
LLVector3d posAgent; bool fHasMax = pBhvrModDistMax->hasValue();
float nMinDist = pBhvrModDistMin->getValue<float>(), nMaxDist = (fHasMax) ? pBhvrModDistMax->getValue<float>() : std::numeric_limits<float>::max();
float nDist = (LLWorld::getInstance()->getAvatar(idAvatar, posAgent)) ? llabs(dist_vec_squared(gAgent.getPositionGlobal(), posAgent)) : std::numeric_limits<float>::max();
return (nMinDist < nMaxDist) && (nMinDist <= nDist) && (nDist <= nMaxDist);
}
return false;
}
bool RlvActions::canReceiveIM(const LLUUID& idSender)
{
// User can receive an IM from "sender" (could be an agent or a group) if:
// - not generally restricted from receiving IMs (or the sender is an exception or inside the exclusion range)
// - not specifically restricted from receiving an IM from the sender
return
(!isRlvEnabled()) ||
( ( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_RECVIM)) || (RlvHandler::instance().isException(RLV_BHVR_RECVIM, idSender)) || (rlvCheckAvatarIMDistance(idSender, RLV_MODIFIER_RECVIMDISTMIN, RLV_MODIFIER_RECVIMDISTMAX)) ) &&
( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_RECVIMFROM)) || (!RlvHandler::instance().isException(RLV_BHVR_RECVIMFROM, idSender)) ) );
bool RlvActions::canPlayGestures()
{
return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SENDGESTURE));
}
bool RlvActions::canSendChannel(int nChannel)
{
return
( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SENDCHANNEL)) || (RlvHandler::instance().isException(RLV_BHVR_SENDCHANNEL, nChannel)) ) &&
( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SENDCHANNELEXCEPT)) || (!RlvHandler::instance().isException(RLV_BHVR_SENDCHANNELEXCEPT, nChannel)) );
bool RlvActions::canSendIM(const LLUUID& idRecipient)
{
// User can send an IM to "recipient" (could be an agent or a group) if:
// - not generally restricted from sending IMs (or the recipient is an exception or inside the exclusion range)
// - not specifically restricted from sending an IM to the recipient
return
(!isRlvEnabled()) ||
( ( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SENDIM)) || (RlvHandler::instance().isException(RLV_BHVR_SENDIM, idRecipient)) || (rlvCheckAvatarIMDistance(idRecipient, RLV_MODIFIER_SENDIMDISTMIN, RLV_MODIFIER_SENDIMDISTMAX)) ) &&
( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_SENDIMTO)) || (!RlvHandler::instance().isException(RLV_BHVR_SENDIMTO, idRecipient)) ) );
Kitty Barnett
committed
bool RlvActions::canStartIM(const LLUUID& idRecipient, bool fIgnoreOpen)
{
// User can start an IM session with "recipient" (could be an agent or a group) if:
// - not generally restricted from starting IM sessions (or the recipient is an exception or inside the exclusion range)
// - not specifically restricted from starting an IM session with the recipient
// - the session already exists
return
(!isRlvEnabled()) ||
( ( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_STARTIM)) || (RlvHandler::instance().isException(RLV_BHVR_STARTIM, idRecipient)) || (rlvCheckAvatarIMDistance(idRecipient, RLV_MODIFIER_STARTIMDISTMIN, RLV_MODIFIER_STARTIMDISTMAX)) ) &&
( (!RlvHandler::instance().hasBehaviour(RLV_BHVR_STARTIMTO)) || (!RlvHandler::instance().isException(RLV_BHVR_STARTIMTO, idRecipient)) ) ) ||
Kitty Barnett
committed
( (!fIgnoreOpen) && ((hasOpenP2PSession(idRecipient)) || (hasOpenGroupSession(idRecipient))) );
bool RlvActions::canShowName(EShowNamesContext eContext, const LLUUID& idAgent)
{
// Handle most common case upfront
if (!s_BlockNamesContexts[eContext])
return true;
if (idAgent.notNull())
{
switch (eContext)
{
// Show/hide avatar nametag
case SNC_NAMETAG:
return (RlvHandler::instance().isException(RLV_BHVR_SHOWNAMETAGS, idAgent)) || (gAgentID == idAgent);
// Show/hide avatar name
case SNC_DEFAULT:
case SNC_TELEPORTOFFER:
case SNC_TELEPORTREQUEST:
return RlvHandler::instance().isException(RLV_BHVR_SHOWNAMES, idAgent) || (gAgentID == idAgent);
}
}
return false;
}
return !RlvHandler::instance().hasBehaviour(RLV_BHVR_SHOWNEARBY);
// Handles: @chatwhisper, @chatnormal and @chatshout
EChatType RlvActions::checkChatVolume(EChatType chatType)
{
// In vs Bhvr | whisper | normal | shout | n+w | n+s | s+w | s+n+w |
// ---------------------------------------------------------------------------------
// whisper | normal | - | - | normal | - | normal | normal |
// normal | - | whisper | - | whisper | whisper | - | whisper |
// shout | - | whisper | normal | whisper | whisper | normal | whisper |
RlvHandler& rlvHandler = RlvHandler::instance();
if ( ((CHAT_TYPE_SHOUT == chatType) || (CHAT_TYPE_NORMAL == chatType)) && (rlvHandler.hasBehaviour(RLV_BHVR_CHATNORMAL)) )
chatType = CHAT_TYPE_WHISPER;
else if ( (CHAT_TYPE_SHOUT == chatType) && (rlvHandler.hasBehaviour(RLV_BHVR_CHATSHOUT)) )
chatType = CHAT_TYPE_NORMAL;
else if ( (CHAT_TYPE_WHISPER == chatType) && (rlvHandler.hasBehaviour(RLV_BHVR_CHATWHISPER)) )
chatType = CHAT_TYPE_NORMAL;
return chatType;
}
Kitty Barnett
committed
// ============================================================================
// Inventory
//
Kitty Barnett
committed
bool RlvActions::canPasteInventory(const LLInventoryCategory* pSourceCat, const LLInventoryCategory* pDestCat)
Kitty Barnett
committed
{
// The user can paste the specified object into the destination if:
// - the source and destination are subject to the same lock type (or none at all) => NOTE: this happens to be the same logic we use for moving
return (!isRlvEnabled()) ||
( (pSourceCat) && (pDestCat) && ((!RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().canMoveFolder(pSourceCat->getUUID(), pDestCat->getUUID()))) );
Kitty Barnett
committed
}
Kitty Barnett
committed
bool RlvActions::canPasteInventory(const LLInventoryItem* pSourceItem, const LLInventoryCategory* pDestCat)
Kitty Barnett
committed
{
// The user can paste the specified object into the destination if:
// - the source and destination are subject to the same lock type (or none at all) => NOTE: this happens to be the same logic we use for moving
return (!isRlvEnabled()) ||
( (pSourceItem) && (pDestCat) && ((!RlvFolderLocks::instance().hasLockedFolder(RLV_LOCK_ANY)) || (RlvFolderLocks::instance().canMoveItem(pSourceItem->getUUID(), pDestCat->getUUID()))) );
Kitty Barnett
committed
}
Kitty Barnett
committed
bool RlvActions::canPreviewTextures()
{
return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_VIEWTEXTURE));
Kitty Barnett
committed
}
Kitty Barnett
committed
// ============================================================================
// Movement
Kitty Barnett
committed
bool RlvActions::canAcceptTpOffer(const LLUUID& idSender)
{
return ((!RlvHandler::instance().hasBehaviour(RLV_BHVR_TPLURE)) || (RlvHandler::instance().isException(RLV_BHVR_TPLURE, idSender))) && (canStand());
}
bool RlvActions::autoAcceptTeleportOffer(const LLUUID& idSender)
{
return ((idSender.notNull()) && (RlvHandler::instance().isException(RLV_BHVR_ACCEPTTP, idSender))) || (RlvHandler::instance().hasBehaviour(RLV_BHVR_ACCEPTTP));
}
bool RlvActions::canAcceptTpRequest(const LLUUID& idSender)
{
return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_TPREQUEST)) || (RlvHandler::instance().isException(RLV_BHVR_TPREQUEST, idSender));
}
bool RlvActions::autoAcceptTeleportRequest(const LLUUID& idRequester)
{
return ((idRequester.notNull()) && (RlvHandler::instance().isException(RLV_BHVR_ACCEPTTPREQUEST, idRequester))) || (RlvHandler::instance().hasBehaviour(RLV_BHVR_ACCEPTTPREQUEST));
bool RlvActions::canFly()
{
return (!RlvHandler::instance().getCurrentCommand()) ? !RlvHandler::instance().hasBehaviour(RLV_BHVR_FLY) : !RlvHandler::instance().hasBehaviourExcept(RLV_BHVR_FLY, RlvHandler::instance().getCurrentObject());
}
bool RlvActions::canFly(const LLUUID& idRlvObjExcept)
{
return !RlvHandler::instance().hasBehaviourExcept(RLV_BHVR_FLY, idRlvObjExcept);
}
bool RlvActions::canJump()
{
return !RlvHandler::instance().hasBehaviour(RLV_BHVR_JUMP);
}
Kitty Barnett
committed
// ============================================================================
// Teleporting
//
Kitty Barnett
committed
bool RlvActions::canTeleportToLocal(const LLVector3d& posGlobal)
Kitty Barnett
committed
{
Kitty Barnett
committed
// User can initiate a local teleport if:
// - can stand up (or isn't sitting)
Kitty Barnett
committed
// - not restricted from "sit teleporting" (or the destination is within the allowed xyz-radius)
// - not restricted from teleporting locally (or the destination is within the allowed xy-radius)
Kitty Barnett
committed
// NOTE: if we're teleporting due to an active command we should disregard any restrictions from the same object
const LLUUID& idRlvObjExcept = RlvHandler::instance().getCurrentObject();
Kitty Barnett
committed
bool fCanTeleport = RlvActions::canStand(idRlvObjExcept);
if ( (fCanTeleport) && (RlvHandler::instance().hasBehaviourExcept(RLV_BHVR_SITTP, idRlvObjExcept)) )
Kitty Barnett
committed
{
const F32 nDistSq = (posGlobal - gAgent.getPositionGlobal()).lengthSquared();
const F32 nSitTpDist = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SITTPDIST)->getValue<F32>();
fCanTeleport = nDistSq < nSitTpDist * nSitTpDist;
}
if ( (fCanTeleport) && (RlvHandler::instance().hasBehaviourExcept(RLV_BHVR_TPLOCAL, idRlvObjExcept)) )
Kitty Barnett
committed
{
const F32 nDistSq = (LLVector2(posGlobal.mdV[0], posGlobal.mdV[1]) - LLVector2(gAgent.getPositionGlobal().mdV[0], gAgent.getPositionGlobal().mdV[1])).lengthSquared();
Kitty Barnett
committed
const F32 nTpLocalDist = llmin(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_TPLOCALDIST)->getValue<float>(), RLV_MODIFIER_TPLOCAL_DEFAULT);
fCanTeleport = nDistSq < nTpLocalDist * nTpLocalDist;
Kitty Barnett
committed
}
Kitty Barnett
committed
return fCanTeleport;
Kitty Barnett
committed
}
bool RlvActions::canTeleportToLocation()
{
// NOTE: if we're teleporting due to an active command we should disregard any restrictions from the same object
const LLUUID& idRlvObjExcept = RlvHandler::instance().getCurrentObject();
return (!RlvHandler::instance().hasBehaviourExcept(RLV_BHVR_TPLOC, idRlvObjExcept)) && (RlvActions::canStand(idRlvObjExcept));
Kitty Barnett
committed
}
bool RlvActions::isLocalTp(const LLVector3d& posGlobal)
{
Kitty Barnett
committed
const F32 nDistSq = (LLVector2(posGlobal.mdV[0], posGlobal.mdV[1]) - LLVector2(gAgent.getPositionGlobal().mdV[0], gAgent.getPositionGlobal().mdV[1])).lengthSquared();
return nDistSq < RLV_MODIFIER_TPLOCAL_DEFAULT * RLV_MODIFIER_TPLOCAL_DEFAULT;
Kitty Barnett
committed
}
Kitty Barnett
committed
// ============================================================================
// World interaction
Kitty Barnett
committed
//
Kitty Barnett
committed
bool RlvActions::canBuild()
{
// User can access the build floater if:
// - allowed to edit existing objects OR
// - allowed to rez/create objects
return
(!RlvHandler::instance().hasBehaviour(RLV_BHVR_EDIT)) ||
(!RlvHandler::instance().hasBehaviour(RLV_BHVR_REZ));
}
Kitty Barnett
committed
// Handles: @edit and @editobj
bool RlvActions::canEdit(const LLViewerObject* pObj)
Kitty Barnett
committed
{
// 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
Kitty Barnett
committed
// 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) &&
Kitty Barnett
committed
( (!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()
{
return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_REZ));
}
bool RlvActions::canGroundSit()
{
// User can sit on the ground if:
// - not prevented from sitting
// - not prevented from standing up or not currently sitting
return (!hasBehaviour(RLV_BHVR_SIT)) && (canStand());
}
Kitty Barnett
committed
bool RlvActions::canSit(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/)
{
// User can sit on the specified object if:
Kitty Barnett
committed
// - not prevented from sitting
// - not prevented from standing up or not currently sitting
// - not standtp restricted or not currently sitting (if the user is sitting and tried to sit elsewhere the tp would just kick in)
// - not a regular sit (i.e. due to @sit:<uuid>=force)
// - not @sittp=n or @fartouch=n restricted or if they clicked on a point within the allowed radius
static RlvCachedBehaviourModifier<float> s_nFarTouchDist(RLV_MODIFIER_FARTOUCHDIST);
Kitty Barnett
committed
static RlvCachedBehaviourModifier<float> s_nSitTpDist(RLV_MODIFIER_SITTPDIST);
return
( (pObj) && (LL_PCODE_VOLUME == pObj->getPCode()) ) &&
(!hasBehaviour(RLV_BHVR_SIT)) &&
( ((!hasBehaviour(RLV_BHVR_UNSIT)) && (!hasBehaviour(RLV_BHVR_STANDTP))) ||
((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting())) ) &&
( ( (NULL != RlvHandler::instance().getCurrentCommand()) && (RLV_BHVR_SIT == RlvHandler::instance().getCurrentCommand()->getBehaviourType()) ) ||
Kitty Barnett
committed
( ((!hasBehaviour(RLV_BHVR_SITTP)) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) < s_nSitTpDist * s_nSitTpDist)) &&
((!hasBehaviour(RLV_BHVR_FARTOUCH)) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) < s_nFarTouchDist * s_nFarTouchDist)) ) );
Kitty Barnett
committed
}
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
// Handles: @showhovertextall, @showhovertextworld, @showhovertexthud and @showhovertext
bool RlvActions::canShowHoverText(const LLViewerObject *pObj)
{
// User cannot see this object's hover text if:
// - prevented from seeing any hover text
// - prevented from seeing hover text on world objects (= non-HUD attachments)
// - prevented from seeing hover text on HUD objects
// - specifically prevented from seeing that object's hover text)
// -> NOTE-RLVa: this is object-specific (as opposed to touch restricts which are linkset-wide)
RlvHandler& rlvHandler = RlvHandler::instance();
return
( (!pObj) || (LL_PCODE_VOLUME != pObj->getPCode()) ||
!( (rlvHandler.hasBehaviour(RLV_BHVR_SHOWHOVERTEXTALL)) ||
( (rlvHandler.hasBehaviour(RLV_BHVR_SHOWHOVERTEXTWORLD)) && (!pObj->isHUDAttachment()) ) ||
( (rlvHandler.hasBehaviour(RLV_BHVR_SHOWHOVERTEXTHUD)) && (pObj->isHUDAttachment()) ) ||
(rlvHandler.isException(RLV_BHVR_SHOWHOVERTEXT, pObj->getID(), RLV_CHECK_PERMISSIVE)) ) );
}
// Handles: @touchall, @touchthis, @touchworld, @touchattach, @touchattachself, @touchattachother, @touchhud, @touchme and @fartouch
bool RlvActions::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/)
{
static RlvCachedBehaviourModifier<float> s_nFartouchDist(RLV_MODIFIER_FARTOUCHDIST);
// User can touch a
// (1) World object if
// - 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)
Kitty Barnett
committed
// - 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)
Kitty Barnett
committed
// - 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)
Kitty Barnett
committed
// - h) not prevented from touching faraway objects (or the attachment's center + pick offset is within range)
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
// - i) specifically allowed to touch that object (overrides all restrictions)
// (4) Attachment (on HUD)
// - b) not specifically prevented from touching that object
// - g) not prevented from touching their own HUD attachments (or the attachment is an exception)
// - i) specifically allowed to touch that object (overrides all restrictions)
// NOTE-RLVa: * touch restrictions apply linkset-wide (as opposed to, for instance, hover text which is object-specific) but only the root object's restrictions are tested
// * @touchall affects world objects and world attachments (self and others') but >not< HUD attachments
// * @fartouch distance matches against the specified object + pick offset (so >not< the linkset root)
// * @touchattachother exceptions are only checked under the general @touchattach exceptions
// * @touchattachself exceptions are only checked under the general @touchattach exceptions
// * @touchme in any object of a linkset affects that entire linkset (= if you can specifically touch one prim in a linkset you can touch that entire linkset)
const LLUUID& idRoot = (pObj) ? pObj->getRootEdit()->getID() : LLUUID::null;
RlvHandler& rlvHandler = RlvHandler::instance();
// Short circuit test for (1/2/3/4.a) and (1/2/3/4.b)
bool fCanTouch =
(idRoot.notNull()) &&
( (pObj->isHUDAttachment()) || (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHALL)) ) &&
( (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHTHIS)) || (!rlvHandler.isException(RLV_BHVR_TOUCHTHIS, idRoot, RLV_CHECK_PERMISSIVE)) );
if (fCanTouch)
{
if ( (!pObj->isAttachment()) || (!pObj->permYouOwner()) )
{
// Rezzed or attachment worn by other - test for (1.c), (2.d), (2.e) and (1/2.h)
fCanTouch =
( (!pObj->isAttachment()) ? (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHWORLD)) || (rlvHandler.isException(RLV_BHVR_TOUCHWORLD, idRoot, RLV_CHECK_PERMISSIVE))
: ((!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACH)) && (!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACHOTHER))) || (rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idRoot, RLV_CHECK_PERMISSIVE)) ) &&
( (!rlvHandler.hasBehaviour(RLV_BHVR_FARTOUCH)) || (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) <= s_nFartouchDist * s_nFartouchDist) );
}
else if (!pObj->isHUDAttachment())
{
// Regular attachment worn by this avie - test for (3.d), (3.e) and (3.h)
fCanTouch =
((!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACH)) || (rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idRoot, RLV_CHECK_PERMISSIVE))) &&
((!rlvHandler.hasBehaviour(RLV_BHVR_TOUCHATTACHSELF)) || (rlvHandler.isException(RLV_BHVR_TOUCHATTACH, idRoot, RLV_CHECK_PERMISSIVE)));
}
else
{
// HUD attachment - test for (4.g)
fCanTouch = (!hasBehaviour(RLV_BHVR_TOUCHHUD)) || (rlvHandler.isException(RLV_BHVR_TOUCHHUD, idRoot, RLV_CHECK_PERMISSIVE));
}
}
// Post-check for (1/2/3/4i)
if ( (!fCanTouch) && (hasBehaviour(RLV_BHVR_TOUCHME)) )
fCanTouch = rlvHandler.hasBehaviourRoot(idRoot, RLV_BHVR_TOUCHME);
return fCanTouch;
}
bool RlvActions::canStand()
{
// NOTE: return FALSE only if we're @unsit=n restricted and the avie is currently sitting on something and TRUE for everything else
return (!RlvHandler::instance().hasBehaviour(RLV_BHVR_UNSIT)) || ((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting()));
Kitty Barnett
committed
}
bool RlvActions::canStand(const LLUUID& idRlvObjExcept)
{
// NOTE: must match generic function above
return (!RlvHandler::instance().hasBehaviourExcept(RLV_BHVR_UNSIT, idRlvObjExcept)) || ((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting()));
Kitty Barnett
committed
// Checked: 2014-02-24 (RLVa-1.4.10)
bool RlvActions::canShowLocation()
{
return !RlvHandler::instance().hasBehaviour(RLV_BHVR_SHOWLOC);
Kitty Barnett
committed
}
Kitty Barnett
committed
// ============================================================================
// Helper functions
//
template<>
const float& RlvActions::getModifierValue<float>(ERlvBehaviourModifier eBhvrMod)
{
return RlvBehaviourDictionary::instance().getModifier(eBhvrMod)->getValue<float>();
}
Kitty Barnett
committed
// Checked: 2013-05-10 (RLVa-1.4.9)
bool RlvActions::hasBehaviour(ERlvBehaviour eBhvr)
{
return RlvHandler::instance().hasBehaviour(eBhvr);
// Checked: 2013-05-09 (RLVa-1.4.9)
bool RlvActions::hasOpenP2PSession(const LLUUID& idAgent)
{
const LLUUID idSession = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, idAgent);
return (idSession.notNull()) && (LLIMMgr::instance().hasSession(idSession));
}
// Checked: 2013-05-09 (RLVa-1.4.9)
bool RlvActions::hasOpenGroupSession(const LLUUID& idGroup)
{
return (idGroup.notNull()) && (LLIMMgr::instance().hasSession(idGroup));
}
// Checked: 2013-11-08 (RLVa-1.4.9)
bool RlvActions::isRlvEnabled()
{
return RlvHandler::isEnabled();
}
Kitty Barnett
committed
void RlvActions::notifyBlocked(const std::string& strNotifcation, const LLSD& sdArgs)
{
RlvUtil::notifyBlocked(strNotifcation, sdArgs);
}
// ============================================================================