From 00ffbb0c0f868ac607aec354043609d03385a970 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 10 Apr 2016 10:51:34 +0200 Subject: [PATCH 01/28] [FIXED] Can't buy objects when @edit restricted --HG-- branch : RLVa --- indra/newview/llfloaterbuy.cpp | 5 ++++- indra/newview/llfloaterbuycontents.cpp | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 5a9cdbba44..fa1667de73 100755 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -104,7 +104,10 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) // Clean up the lists... floater->reset(); floater->mSaleInfo = sale_info; - floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); +// [RLVa:KB] - Checked: RLVa-2.0.0 + floater->mObjectSelection = LLSelectMgr::getInstance()->getSelection(); +// [/RLVa:KB] +// floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); LLSelectNode* node = selection->getFirstRootNode(); if (!node) diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index b32ac860aa..9d0682d251 100755 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -104,7 +104,10 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info) if (list) list->deleteAllItems(); - floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); +// [RLVa:KB] - Checked: RLVa-2.0.0 + floater->mObjectSelection = LLSelectMgr::getInstance()->getSelection(); +// [/RLVa:KB] +// floater->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection(); LLUUID owner_id; std::string owner_name; From 66e293345b10d86e9b91c68233c9af9a7d6caa7e Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 23 Apr 2016 23:33:59 +0200 Subject: [PATCH 02/28] Incremented RLV spec version to 3.1.4 cause pie is delicious --HG-- branch : RLVa --- indra/newview/rlvdefines.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 27f591e7ce..0c3d05f444 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -22,9 +22,9 @@ // // Version of the specifcation we support -const S32 RLV_VERSION_MAJOR = 2; -const S32 RLV_VERSION_MINOR = 8; -const S32 RLV_VERSION_PATCH = 0; +const S32 RLV_VERSION_MAJOR = 3; +const S32 RLV_VERSION_MINOR = 1; +const S32 RLV_VERSION_PATCH = 4; const S32 RLV_VERSION_BUILD = 0; // Implementation version From 3f498c46d52b018add61815bff4eff0ce28a2370 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 14 May 2016 10:46:00 +0200 Subject: [PATCH 03/28] Added @sendgesture=n to block sending/playing gestures (requested) --HG-- branch : RLVa --- indra/newview/llgesturemgr.cpp | 9 +++++++++ indra/newview/rlvactions.cpp | 7 ++++++- indra/newview/rlvactions.h | 7 ++++++- indra/newview/rlvdefines.h | 1 + indra/newview/rlvhelper.cpp | 1 + 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 950a6cfaef..d22c40922a 100755 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -56,6 +56,10 @@ #include "llappearancemgr.h" #include "llgesturelistener.h" +// [RLVa:KB] - Checked: RLVa-2.0.0 +#include "rlvactions.h" +// [/RLVa:KB] + // Longest time, in seconds, to wait for all animations to stop playing const F32 MAX_WAIT_ANIM_SECS = 30.f; @@ -527,6 +531,11 @@ void LLGestureMgr::playGesture(LLMultiGesture* gesture) { if (!gesture) return; +// [RLVa:KB] - Checked: RLVa-2.0.0 | Handles: @sendgesture + if (!RlvActions::canPlayGestures()) + return; +// [/RLVa:KB] + // Reset gesture to first step gesture->mCurrentStep = 0; diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index b97e060de3..bf30e8305c 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2013, Kitty Barnett + * 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; @@ -38,6 +38,11 @@ bool RlvActions::canReceiveIM(const LLUUID& idSender) ( (!gRlvHandler.hasBehaviour(RLV_BHVR_RECVIMFROM)) || (!gRlvHandler.isException(RLV_BHVR_RECVIMFROM, idSender)) ) ); } +bool RlvActions::canPlayGestures() +{ + return (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDGESTURE)); +} + // Checked: 2010-11-30 (RLVa-1.3.0) bool RlvActions::canSendIM(const LLUUID& idRecipient) { diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index fbc8ab12ba..9aa729e0df 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2009-2013, Kitty Barnett + * 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; @@ -34,6 +34,11 @@ public: */ static bool canReceiveIM(const LLUUID& idSender); + /* + * Returns true if the user is allowed to send/play gestures (whether active ones from the chat bar or using the gesture preview floater) + */ + static bool canPlayGestures(); + /* * Returns true if the user is allowed to send IMs to the specified recipient (can be an avatar or a group) */ diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 3e45ff3398..898880d7ad 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -143,6 +143,7 @@ enum ERlvBehaviour { RLV_BHVR_RECVIMFROM, // "recvimfrom" RLV_BHVR_STARTIM, // "startim" RLV_BHVR_STARTIMTO, // "startimto" + RLV_BHVR_SENDGESTURE, RLV_BHVR_PERMISSIVE, // "permissive" RLV_BHVR_NOTIFY, // "notify" RLV_BHVR_SHOWINV, // "showinv" diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index ff05df400c..71e782feb9 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -79,6 +79,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("sendchat", RLV_BHVR_SENDCHAT)); addEntry(new RlvBehaviourToggleProcessor("sendim", RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("sendimto", RLV_BHVR_SENDIMTO, RlvBehaviourInfo::BHVR_STRICT)); + addEntry(new RlvBehaviourGenericProcessor("sendgesture", RLV_BHVR_SENDGESTURE, RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvBehaviourGenericProcessor("setdebug", RLV_BHVR_SETDEBUG)); addEntry(new RlvBehaviourGenericProcessor("setenv", RLV_BHVR_SETENV)); addEntry(new RlvBehaviourGenericProcessor("setgroup", RLV_BHVR_SETGROUP)); From f2b05ea2e4161b68ba92c40ea783a3f62fa7285c Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 15 May 2016 16:15:09 +0200 Subject: [PATCH 04/28] [FIXED] RlvAttachmentLocks::updateLockedHUD() isn't disabling wireframe mode properly --HG-- branch : RLVa --- indra/newview/llviewermenu.cpp | 21 +++++++++++++++------ indra/newview/llviewermenu.h | 4 ++++ indra/newview/rlvlocks.cpp | 5 +++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 505c01076e..70a6718206 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -1249,13 +1249,22 @@ class LLAdvancedToggleWireframe : public view_listener_t { bool handleEvent(const LLSD& userdata) { -// [RLVa:KB] - Checked: 2013-05-11 (RLVa-1.4.9) +// [RLVa:KB] - Checked: RLVa-2.0.0 bool fRlvBlockWireframe = gRlvAttachmentLocks.hasLockedHUD(); if ( (!gUseWireframe) && (fRlvBlockWireframe) ) - { RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_WIREFRAME); - } - gUseWireframe = (!gUseWireframe) && (!fRlvBlockWireframe); + set_use_wireframe( (!gUseWireframe) && (!fRlvBlockWireframe) ); + return true; + } +}; + +// Called from rlvhandler.cpp +void set_use_wireframe(BOOL useWireframe) + { + if (gUseWireframe == useWireframe) + return; + + gUseWireframe = useWireframe; // [/RLVa:KB] // gUseWireframe = !(gUseWireframe); @@ -1276,9 +1285,9 @@ class LLAdvancedToggleWireframe : public view_listener_t LLViewerShaderMgr::instance()->setShaders(); } - return true; +// return true; } -}; +//}; class LLAdvancedCheckWireframe : public view_listener_t { diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index b7bdf00157..36bf472cad 100755 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -38,6 +38,10 @@ class LLParcelSelection; class LLObjectSelection; class LLSelectNode; +// [RLVa:KB] - Checked: RLVa-2.0.0 +void set_use_wireframe(BOOL useWireframe); +// [/RLVa:KB] + void initialize_edit_menu(); void initialize_spellcheck_menu(); void init_menus(); diff --git a/indra/newview/rlvlocks.cpp b/indra/newview/rlvlocks.cpp index 520a0ee959..d7f86b81b7 100644 --- a/indra/newview/rlvlocks.cpp +++ b/indra/newview/rlvlocks.cpp @@ -20,12 +20,14 @@ #include "llattachmentsmgr.h" #include "lloutfitobserver.h" #include "llviewerobjectlist.h" +#include "llviewermenu.h" #include "pipeline.h" #include "rlvlocks.h" #include "rlvhelper.h" #include "rlvinventory.h" + // ============================================================================ // RlvAttachPtLookup member functions // @@ -401,8 +403,7 @@ void RlvAttachmentLocks::updateLockedHUD() // Reset HUD visibility and wireframe options if at least one HUD attachment is locked if (m_fHasLockedHUD) { - LLPipeline::sShowHUDAttachments = TRUE; - gUseWireframe = FALSE; + set_use_wireframe(false); } } From 2a18eb7d7151da1910e4ae1ab5930fc3a2d76648 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 15 May 2016 21:04:42 +0200 Subject: [PATCH 05/28] Added @camfocus:[;[;]]=force (WIP - first iteration) --HG-- branch : RLVa --- indra/newview/rlvdefines.h | 1 + indra/newview/rlvhandler.cpp | 65 ++++++++++++++++++++++++++++++++++++ indra/newview/rlvhelper.cpp | 5 +-- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 0c3d05f444..d79833430a 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -164,6 +164,7 @@ enum ERlvBehaviour { RLV_BHVR_DETACHTHISEXCEPT, // "detachthis_except" RLV_BHVR_ADJUSTHEIGHT, // "adjustheight" RLV_BHVR_TPTO, // "tpto" + RLV_BHVR_CAMFOCUS, RLV_BHVR_VERSION, // "version" RLV_BHVR_VERSIONNEW, // "versionnew" RLV_BHVR_VERSIONNUM, // "versionnum" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 8fc3b851c2..fdb92ab5d3 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -36,6 +36,7 @@ #include "llsidepanelappearance.h" // @showinv - "Appearance / Edit appearance" panel #include "lltabcontainer.h" // @showinv - Tab container control for inventory tabs #include "lltoolmgr.h" // @edit +#include "llviewercamera.h" // @camfocus // RLVa includes #include "rlvfloaters.h" @@ -463,6 +464,70 @@ bool RlvHandler::handleEvent(LLPointer event, const LLSD& return false; } +// Handles: @camfocus:[;[;]]=force +template<> template<> +ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) +{ + std::vector optionList; + if (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) + return RLV_RET_FAILED_OPTION; + + LLVector3 posAgent; + LLVector3d posGlobal; + F32 camDistance; + + // Get the focus position/object (and verify it is known) + LLUUID idObject; LLVector3 posRegion; + if (RlvCommandOptionHelper::parseOption(optionList[0], idObject)) + { + const LLViewerObject* pObj = gObjectList.findObject(idObject); + if (!pObj) + return RLV_RET_FAILED_OPTION; + posAgent = pObj->getPositionAgent(); + posGlobal = pObj->getPositionGlobal(); + camDistance = pObj->getScale().magVec(); + } + else if (RlvCommandOptionHelper::parseOption(optionList[0], posRegion)) + { + const LLViewerRegion* pRegion = gAgent.getRegion(); + if (!pRegion) + return RLV_RET_FAILED_UNKNOWN; + posAgent = pRegion->getPosAgentFromRegion(posRegion); + posGlobal = pRegion->getPosGlobalFromRegion(posRegion); + camDistance = 0.0f; + } + else + { + return RLV_RET_FAILED_OPTION; + } + + // Get the camera distance + if ( (optionList.size() > 1) && (!optionList[1].empty()) ) + { + if (!RlvCommandOptionHelper::parseOption(optionList[1], camDistance)) + return RLV_RET_FAILED_OPTION; + } + + // Get the directional vector (or calculate it from the current camera position) + LLVector3 camDirection; + if ( (optionList.size() > 2) && (!optionList[2].empty()) ) + { + if (!RlvCommandOptionHelper::parseOption(optionList[2], camDirection)) + return RLV_RET_FAILED_OPTION; + } + else + { + camDirection = LLViewerCamera::getInstance()->getOrigin() - posAgent; + } + camDirection.normVec(); + + // Move the camera in place + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setCameraPosAndFocusGlobal(posGlobal + LLVector3d(camDirection * llmax(F_APPROXIMATELY_ZERO, camDistance)), posGlobal, idObject); + + return RLV_RET_SUCCESS; +} + // Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c void RlvHandler::onSitOrStand(bool fSitting) { diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 862e31c1f4..3d5182669c 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -199,6 +199,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() // Force-only // addEntry(new RlvBehaviourInfo("adjustheight", RLV_BHVR_ADJUSTHEIGHT, RLV_TYPE_FORCE)); + addEntry(new RlvForceProcessor("camfocus", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor("detachme")); addEntry(new RlvForceProcessor("setgroup")); addEntry(new RlvForceProcessor("sit")); @@ -413,12 +414,12 @@ bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, Rl { if (typeid(float) == m_DefaultValue.type()) { - modValue = std::stof(optionValue.c_str()); + modValue = std::stof(optionValue); return true; } else if (typeid(int) == m_DefaultValue.type()) { - modValue = std::stoi(optionValue.c_str()); + modValue = std::stoi(optionValue); return true; } return false; From 9d7c376390b75a9dd770bb1e5c41b53de4caf45a Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 15 May 2016 22:57:24 +0200 Subject: [PATCH 06/28] Added @camunlock=n --HG-- branch : RLVa --- indra/newview/llagentcamera.cpp | 8 ++++++++ indra/newview/rlvdefines.h | 1 + indra/newview/rlvhandler.cpp | 12 ++++++++++++ indra/newview/rlvhelper.cpp | 1 + 4 files changed, 22 insertions(+) diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index a67de190ae..a02ddccb6b 100755 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1145,6 +1145,14 @@ void LLAgentCamera::updateCamera() mCameraUpVector = LLVector3::z_axis; //LLVector3 camera_skyward(0.f, 0.f, 1.f); +// [RLVa:KB] - Checked: RLVa-2.0.0 + // Set focus back on our avie if something changed it + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_CAMUNLOCK)) && (cameraThirdPerson()) && (!getFocusOnAvatar()) ) + { + setFocusOnAvatar(TRUE, FALSE); + } +// [/RLVa:KB] + U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode; validateFocusObject(); diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index d79833430a..c136c9921d 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -157,6 +157,7 @@ enum ERlvBehaviour { RLV_BHVR_SETENV, // "setenv" RLV_BHVR_ALWAYSRUN, // "alwaysrun" RLV_BHVR_TEMPRUN, // "temprun" + RLV_BHVR_CAMUNLOCK, RLV_BHVR_DETACHME, // "detachme" RLV_BHVR_ATTACHTHIS, // "attachthis" RLV_BHVR_ATTACHTHISEXCEPT, // "attachthis_except" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index fdb92ab5d3..be4bdb39c2 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -24,11 +24,13 @@ #include "llmoveview.h" #include "llstartup.h" #include "llviewermessage.h" +#include "llviewermenu.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" // Command specific includes +#include "llagentcamera.h" // @camfocus #include "llenvmanager.h" // @setenv #include "lloutfitslist.h" // @showinv - "Appearance / My Outfits" panel #include "llpaneloutfitsinventory.h" // @showinv - "Appearance" floater @@ -1497,6 +1499,16 @@ ERlvCmdRet RlvBehaviourAddRemAttachHandler::onCommand(const RlvCommand& rlvCmd, return RLV_RET_SUCCESS; } +// Handles: @sendim=n|y toggles +template<> template<> +void RlvBehaviourHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + if (fHasBhvr) + { + handle_reset_view(); + } +} + // Handles: @detach[:]=n|y template<> template<> ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 3d5182669c..3c9ee3408b 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -91,6 +91,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourInfo("attachallthis", RLV_BHVR_ATTACHTHIS, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE)); addEntry(new RlvBehaviourInfo("attachthis_except", RLV_BHVR_ATTACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_NODE)); addEntry(new RlvBehaviourInfo("attachallthis_except", RLV_BHVR_ATTACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE)); + addEntry(new RlvBehaviourToggleProcessor("camunlock")); addEntry(new RlvBehaviourGenericProcessor("chatwhisper", RLV_BHVR_CHATWHISPER)); addEntry(new RlvBehaviourGenericProcessor("chatnormal", RLV_BHVR_CHATNORMAL)); addEntry(new RlvBehaviourGenericProcessor("chatshout", RLV_BHVR_CHATSHOUT)); From 056d8cff552f80550ec277e8f0afcc019e1dec42 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Mon, 16 May 2016 01:32:12 +0200 Subject: [PATCH 07/28] Added @setcam=n|y, @setcam_eyeoffset[:]=n|y, @setcam_focusoffset[:]=n|y, @setcam_fov[:]=n|y, @setcam_fovmin[:]=n|y and @setcam_fovmax[:]=n|y --HG-- branch : RLVa --- indra/newview/llagentcamera.cpp | 30 ++- indra/newview/llagentcamera.h | 7 +- indra/newview/llviewercamera.cpp | 7 + indra/newview/rlvactions.cpp | 61 +++++- indra/newview/rlvactions.h | 33 ++- indra/newview/rlvcommon.h | 2 +- indra/newview/rlvdefines.h | 17 +- indra/newview/rlvhandler.cpp | 334 +++++++++++++++++++++++-------- indra/newview/rlvhandler.h | 5 + indra/newview/rlvhelper.cpp | 51 ++++- indra/newview/rlvhelper.h | 23 ++- 11 files changed, 459 insertions(+), 111 deletions(-) diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index a02ddccb6b..637326acd0 100755 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -212,10 +212,18 @@ void LLAgentCamera::init() mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("CameraOffsetRearView"); mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("CameraOffsetFrontView"); mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("CameraOffsetGroupView"); +// [RLVa:KB] - Checked: RLVa-2.0.0 + mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW] = gSavedSettings.declareVec3("CameraOffsetRLVaView", LLVector3(mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW]->getDefault()), "Declared in code", LLControlVariable::PERSIST_NO); + mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->setHiddenFromSettingsEditor(true); +// [/RLVa:KB] mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getControl("FocusOffsetRearView"); mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getControl("FocusOffsetFrontView"); mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getControl("FocusOffsetGroupView"); +// [RLVa:KB] - Checked: RLVa-2.0.0 + mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW] = gSavedSettings.declareVec3("FocusOffsetRLVaView", LLVector3(mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW]->getDefault()), "Declared in code", LLControlVariable::PERSIST_NO); + mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->setHiddenFromSettingsEditor(true); +// [/RLVa:KB] mCameraCollidePlane.clearVec(); mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"); @@ -1147,7 +1155,7 @@ void LLAgentCamera::updateCamera() // [RLVa:KB] - Checked: RLVa-2.0.0 // Set focus back on our avie if something changed it - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_CAMUNLOCK)) && (cameraThirdPerson()) && (!getFocusOnAvatar()) ) + if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_UNLOCK)) && (cameraThirdPerson()) && (!getFocusOnAvatar()) ) { setFocusOnAvatar(TRUE, FALSE); } @@ -2333,6 +2341,26 @@ void LLAgentCamera::changeCameraToCustomizeAvatar() void LLAgentCamera::switchCameraPreset(ECameraPreset preset) { +// [RLVa:KB] - Checked: RLVa-2.0.0 + if (RlvActions::isRlvEnabled()) + { + // Don't allow changing away from the our view if an object is restricting it + if (RlvActions::isCameraPresetLocked()) + preset = CAMERA_RLV_SETCAM_VIEW; + + // Don't reset anything if our view is already current + if ( (CAMERA_RLV_SETCAM_VIEW == preset) && (CAMERA_RLV_SETCAM_VIEW == mCameraPreset) ) + return; + + // Reset our view when switching away + if (CAMERA_RLV_SETCAM_VIEW != preset) + { + mCameraOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->resetToDefault(); + mFocusOffsetInitial[CAMERA_RLV_SETCAM_VIEW]->resetToDefault(); + } + } +// [/RLVa:KB] + //zoom is supposed to be reset for the front and group views mCameraZoomFraction = 1.f; diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index ab793ff316..3a448de783 100755 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -56,7 +56,12 @@ enum ECameraPreset CAMERA_PRESET_FRONT_VIEW, /** "Above and to the left, over the shoulder, pulled back a little on the zoom" */ - CAMERA_PRESET_GROUP_VIEW + CAMERA_PRESET_GROUP_VIEW, + +// [RLVa:KB] - Checked: RLVa-2.0.0 + /* Used by RLVa */ + CAMERA_RLV_SETCAM_VIEW +// [/RLVa:KB] }; //------------------------------------------------------------------------ diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index ac09961402..314f6417de 100755 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -42,6 +42,7 @@ #include "lltoolmgr.h" #include "llviewerjoystick.h" // [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) +#include "rlvactions.h" #include "rlvhandler.h" // [/RLVa:KB] @@ -882,6 +883,12 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) { +// [RLVa:KB] - Checked: RLVa-2.0.0 + F32 nCamFOVMin, nCamFOVMax; + if ( (RlvActions::isRlvEnabled()) && (RlvActions::getCameraFOVLimits(nCamFOVMin, nCamFOVMax)) ) + vertical_fov_rads = llclamp(vertical_fov_rads, nCamFOVMin, nCamFOVMax); +// [/RLVa:KB] + vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView()); setView(vertical_fov_rads); mCameraFOVDefault = vertical_fov_rads; diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 102729a68b..89bba202fd 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -1,27 +1,70 @@ -/** +/** * - * Copyright (c) 2009-2013, Kitty Barnett - * - * The source code in this file is provided to you under the terms of the + * 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 + * 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 + * you have read and understood your obligations described above, and agree to * abide by those obligations. - * + * */ #include "llviewerprecompiledheaders.h" #include "llagent.h" #include "llimview.h" +#include "llviewercamera.h" #include "llvoavatarself.h" #include "rlvactions.h" #include "rlvhelper.h" #include "rlvhandler.h" +// ============================================================================ +// Camera +// + +bool RlvActions::canChangeCameraPreset(const LLUUID& idRlvObject) +{ + // NOTE: if an object has exclusive camera controls then all other objects are locked out + return + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM)) || (gRlvHandler.hasBehaviour(idRlvObject, RLV_BHVR_SETCAM)) ) && + (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET)); +} + +bool RlvActions::canChangeCameraFOV(const LLUUID& idRlvObject) +{ + // NOTE: if an object has exclusive camera controls then all other objects are locked out + return (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM)) || (gRlvHandler.hasBehaviour(idRlvObject, RLV_BHVR_SETCAM)); +} + +bool RlvActions::isCameraPresetLocked() +{ + return (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_EYEOFFSET)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOCUSOFFSET)); +} + +bool RlvActions::isCameraFOVClamped() +{ + return (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMIN)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMAX)); +} + +bool RlvActions::getCameraFOVLimits(F32& nFOVMin, F32& nFOVMax) +{ + static RlvCachedBehaviourModifier sCamFovMin(RLV_MODIFIER_SETCAM_FOVMIN); + static RlvCachedBehaviourModifier sCamFovMax(RLV_MODIFIER_SETCAM_FOVMAX); + + bool fClampMax = gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMAX); + nFOVMax = (fClampMax) ? sCamFovMax : LLViewerCamera::getInstance()->getMaxView(); + + bool fClampMin = gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_FOVMIN); + nFOVMin = (fClampMin) ? sCamFovMin : LLViewerCamera::getInstance()->getMinView(); + + return (fClampMin) || (fClampMax); +} + // ============================================================================ // Communication/Avatar interaction // diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index 9d616f0925..e93060f384 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -25,6 +25,35 @@ class RlvActions { + // ====== + // Camera + // ====== +public: + /* + * Returns true if the specified object can manipulate the camera offset and/or focus offset values + */ + static bool canChangeCameraPreset(const LLUUID& idRlvObject); + + /* + * Returns true if the specified object cannot manipulate the camera FOV + */ + static bool canChangeCameraFOV(const LLUUID& idRlvObject); + + /* + * Returns true if the camera offset and focus offset are locked (prevents changing the current camera preset) + */ + static bool isCameraPresetLocked(); + + /* + * Returns true if the camera's FOV is currently restricted/clamped + */ + static bool isCameraFOVClamped(); + + /* + * Retrieves the current camera FOV limits - returns isCameraFOVClamped() + */ + static bool getCameraFOVLimits(F32& nFOVMin, F32& nFOVMax); + // ================================ // Communication/Avatar interaction // ================================ @@ -122,13 +151,13 @@ public: // ================ public: /* - * Convenience function to check for a behaviour without having to include rlvhandler.h. + * Convenience function to check for a behaviour without having to include rlvhandler.h * Do NOT call this function if speed is important (i.e. per-frame) */ static bool hasBehaviour(ERlvBehaviour eBhvr); /* - * Returns true if a - P2P or group - IM session is open with the specified UUID. + * Returns true if a - P2P or group - IM session is open with the specified UUID */ static bool hasOpenP2PSession(const LLUUID& idAgent); static bool hasOpenGroupSession(const LLUUID& idGroup); diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index 89da91c9d0..4dde21887d 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -56,7 +56,7 @@ class RlvObject; struct RlvException; typedef boost::variant RlvExceptionOption; -typedef boost::variant RlvBehaviourModifierValue; +typedef boost::variant RlvBehaviourModifierValue; class RlvGCTimer; diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index c136c9921d..7814545bd0 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -157,7 +157,6 @@ enum ERlvBehaviour { RLV_BHVR_SETENV, // "setenv" RLV_BHVR_ALWAYSRUN, // "alwaysrun" RLV_BHVR_TEMPRUN, // "temprun" - RLV_BHVR_CAMUNLOCK, RLV_BHVR_DETACHME, // "detachme" RLV_BHVR_ATTACHTHIS, // "attachthis" RLV_BHVR_ATTACHTHISEXCEPT, // "attachthis_except" @@ -165,7 +164,6 @@ enum ERlvBehaviour { RLV_BHVR_DETACHTHISEXCEPT, // "detachthis_except" RLV_BHVR_ADJUSTHEIGHT, // "adjustheight" RLV_BHVR_TPTO, // "tpto" - RLV_BHVR_CAMFOCUS, RLV_BHVR_VERSION, // "version" RLV_BHVR_VERSIONNEW, // "versionnew" RLV_BHVR_VERSIONNUM, // "versionnum" @@ -190,12 +188,27 @@ enum ERlvBehaviour { RLV_BHVR_GETSTATUSALL, // "getstatusall" RLV_CMD_FORCEWEAR, // Internal representation of all force wear commands + // Camera + RLV_BHVR_SETCAM, // Gives an object exclusive control of the user's camera + RLV_BHVR_SETCAM_EYEOFFSET, // Changes the default camera offset + RLV_BHVR_SETCAM_FOCUSOFFSET, // Changes the default camera focus offset + RLV_BHVR_SETCAM_FOCUS, // Forces the camera focus and/or position to a specific object, avatar or position + RLV_BHVR_SETCAM_FOV, // Changes the current (vertical) field of view + RLV_BHVR_SETCAM_FOVMIN, // Enforces a minimum (vertical) FOV + RLV_BHVR_SETCAM_FOVMAX, // Enforces a maximum (vertical) FOV + RLV_BHVR_SETCAM_UNLOCK, // Forces the camera focus to the user's avatar + RLV_BHVR_COUNT, RLV_BHVR_UNKNOWN }; enum ERlvBehaviourModifier { + RLV_MODIFIER_SETCAM_EYEOFFSET, + RLV_MODIFIER_SETCAM_FOCUSOFFSET, + RLV_MODIFIER_SETCAM_FOVMIN, + RLV_MODIFIER_SETCAM_FOVMAX, + RLV_MODIFIER_COUNT, RLV_MODIFIER_UNKNOWN }; diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index be4bdb39c2..5309c8d79b 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -30,7 +30,7 @@ #include "llviewerregion.h" // Command specific includes -#include "llagentcamera.h" // @camfocus +#include "llagentcamera.h" // @setcam and related #include "llenvmanager.h" // @setenv #include "lloutfitslist.h" // @showinv - "Appearance / My Outfits" panel #include "llpaneloutfitsinventory.h" // @showinv - "Appearance" floater @@ -38,9 +38,10 @@ #include "llsidepanelappearance.h" // @showinv - "Appearance / Edit appearance" panel #include "lltabcontainer.h" // @showinv - Tab container control for inventory tabs #include "lltoolmgr.h" // @edit -#include "llviewercamera.h" // @camfocus +#include "llviewercamera.h" // @setcam and related // RLVa includes +#include "rlvactions.h" #include "rlvfloaters.h" #include "rlvhandler.h" #include "rlvhelper.h" @@ -138,6 +139,23 @@ RlvHandler::~RlvHandler() // Behaviour related functions // +bool RlvHandler::findBehaviour(ERlvBehaviour eBhvr, std::list& lObjects) const +{ + lObjects.clear(); + for (const auto& objEntry : m_Objects) + if (objEntry.second.hasBehaviour(eBhvr, false)) + lObjects.push_back(&objEntry.second); + return !lObjects.empty(); +} + +bool RlvHandler::hasBehaviour(const LLUUID& idRlvObj, ERlvBehaviour eBhvr, const std::string& strOption) const +{ + rlv_object_map_t::const_iterator itObj = m_Objects.find(idRlvObj); + if (m_Objects.end() != itObj) + return itObj->second.hasBehaviour(eBhvr, strOption, false); + return false; +} + bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBhvr, const std::string& strOption, const LLUUID& idObj) const { for (rlv_object_map_t::const_iterator itObj = m_Objects.begin(); itObj != m_Objects.end(); ++itObj) @@ -296,7 +314,7 @@ ERlvCmdRet RlvHandler::processCommand(const RlvCommand& rlvCmd, bool fFromObj) case RLV_TYPE_ADD: // Checked: 2009-11-26 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f { if ( (m_Behaviours[rlvCmd.getBehaviourType()]) && - ( (RLV_BHVR_SETDEBUG == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETENV == rlvCmd.getBehaviourType()) ) ) + ( (RLV_BHVR_SETCAM == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETDEBUG == rlvCmd.getBehaviourType()) || (RLV_BHVR_SETENV == rlvCmd.getBehaviourType()) ) ) { // Some restrictions can only be held by one single object to avoid deadlocks RLV_DEBUGS << "\t- " << rlvCmd.getBehaviour() << " is already set by another object => discarding" << RLV_ENDL; @@ -466,70 +484,6 @@ bool RlvHandler::handleEvent(LLPointer event, const LLSD& return false; } -// Handles: @camfocus:[;[;]]=force -template<> template<> -ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) -{ - std::vector optionList; - if (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) - return RLV_RET_FAILED_OPTION; - - LLVector3 posAgent; - LLVector3d posGlobal; - F32 camDistance; - - // Get the focus position/object (and verify it is known) - LLUUID idObject; LLVector3 posRegion; - if (RlvCommandOptionHelper::parseOption(optionList[0], idObject)) - { - const LLViewerObject* pObj = gObjectList.findObject(idObject); - if (!pObj) - return RLV_RET_FAILED_OPTION; - posAgent = pObj->getPositionAgent(); - posGlobal = pObj->getPositionGlobal(); - camDistance = pObj->getScale().magVec(); - } - else if (RlvCommandOptionHelper::parseOption(optionList[0], posRegion)) - { - const LLViewerRegion* pRegion = gAgent.getRegion(); - if (!pRegion) - return RLV_RET_FAILED_UNKNOWN; - posAgent = pRegion->getPosAgentFromRegion(posRegion); - posGlobal = pRegion->getPosGlobalFromRegion(posRegion); - camDistance = 0.0f; - } - else - { - return RLV_RET_FAILED_OPTION; - } - - // Get the camera distance - if ( (optionList.size() > 1) && (!optionList[1].empty()) ) - { - if (!RlvCommandOptionHelper::parseOption(optionList[1], camDistance)) - return RLV_RET_FAILED_OPTION; - } - - // Get the directional vector (or calculate it from the current camera position) - LLVector3 camDirection; - if ( (optionList.size() > 2) && (!optionList[2].empty()) ) - { - if (!RlvCommandOptionHelper::parseOption(optionList[2], camDirection)) - return RLV_RET_FAILED_OPTION; - } - else - { - camDirection = LLViewerCamera::getInstance()->getOrigin() - posAgent; - } - camDirection.normVec(); - - // Move the camera in place - gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); - gAgentCamera.setCameraPosAndFocusGlobal(posGlobal + LLVector3d(camDirection * llmax(F_APPROXIMATELY_ZERO, camDistance)), posGlobal, idObject); - - return RLV_RET_SUCCESS; -} - // Checked: 2010-08-29 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c void RlvHandler::onSitOrStand(bool fSitting) { @@ -1436,10 +1390,19 @@ ERlvCmdRet RlvBehaviourGenericHandler::onCommand(const RlvC if ( (!rlvCmd.hasOption()) || (!pBhvrModifier) || (!pBhvrModifier->convertOptionValue(rlvCmd.getOption(), modValue)) ) return RLV_RET_FAILED_OPTION; + // HACK-RLVa: reference counting doesn't happen until control returns to our caller but the modifier callbacks will happen now so we need to adjust the reference counts here if (RLV_TYPE_ADD == rlvCmd.getParamType()) + { + gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]++; pBhvrModifier->addValue(modValue, rlvCmd.getObjectID()); + gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]--; + } else + { + gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]--; pBhvrModifier->removeValue(modValue, rlvCmd.getObjectID()); + gRlvHandler.m_Behaviours[rlvCmd.getBehaviourType()]++; + } fRefCount = true; return RLV_RET_SUCCESS; @@ -1499,16 +1462,6 @@ ERlvCmdRet RlvBehaviourAddRemAttachHandler::onCommand(const RlvCommand& rlvCmd, return RLV_RET_SUCCESS; } -// Handles: @sendim=n|y toggles -template<> template<> -void RlvBehaviourHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) -{ - if (fHasBhvr) - { - handle_reset_view(); - } -} - // Handles: @detach[:]=n|y template<> template<> ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) @@ -1676,7 +1629,114 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour e gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->setHiddenFromSettingsEditor(fHasBhvr); } -// Handles: @edit=n|y toggles +// Handles: @setcam_unlock=n|y toggles +template<> template<> +void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + if (fHasBhvr) + handle_reset_view(); +} + +// Handles: @setcam_eyeoffset:=n|y and @setcam_focusoffset:=n|y toggles +template<> template<> +void RlvBehaviourCamEyeFocusOffsetHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + if (fHasBhvr) + { + gAgentCamera.switchCameraPreset(CAMERA_RLV_SETCAM_VIEW); + } + else + { + const RlvBehaviourModifier* pBhvrEyeModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET); + const RlvBehaviourModifier* pBhvrOffsetModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET); + if ( (!pBhvrEyeModifier->hasValue()) && (!pBhvrOffsetModifier->hasValue()) ) + gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW); + } +} + +// Handles: @setcam_eyeoffset:=n|y changes +template<> +void RlvBehaviourModifierHandler::onValueChange() const +{ + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET)) + { + LLControlVariable* pControl = gSavedSettings.getControl("CameraOffsetRLVaView"); + if (pBhvrModifier->hasValue()) + pControl->setValue(pBhvrModifier->getValue().getValue()); + else + pControl->resetToDefault(); + } +} + +// Handles: @setcam_focusoffset:=n|y changes +template<> +void RlvBehaviourModifierHandler::onValueChange() const +{ + if (RlvBehaviourModifier* pBhvrModifier = RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET)) + { + LLControlVariable* pControl = gSavedSettings.getControl("FocusOffsetRLVaView"); + if (pBhvrModifier->hasValue()) + pControl->setValue(pBhvrModifier->getValue().getValue()); + else + pControl->resetToDefault(); + } +} + +// Handles: @setcam_fovmin:=n|y changes +template<> +void RlvBehaviourModifierHandler::onValueChange() const +{ + LLViewerCamera::instance().setDefaultFOV(LLViewerCamera::instance().getDefaultFOV()); +} + +// Handles: @setcam_fovmax:=n|y changes +template<> +void RlvBehaviourModifierHandler::onValueChange() const +{ + LLViewerCamera::instance().setDefaultFOV(LLViewerCamera::instance().getDefaultFOV()); +} + +// Handles: @setcam=n|y toggles +template<> template<> +void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) +{ + // Once an object has exclusive control over the camera only its behaviours should be active. This affects: + // - RLV_BHVR_SETCAM_EYEOFFSET => behaviour modifiers handle this for us + // - RLV_BHVR_SETCAM_FOCUSOFFSET => behaviour modifiers handle this for us + // - RLV_BHVR_SETCAM_FOVMIN => behaviour modifiers handle this for us + // - RLV_BHVR_SETCAM_FOVMAX => behaviour modifiers handle this for us + // - RLV_BHVR_SETCAM_UNLOCK => manually (re)set the reference count (and possibly invoke the toggle handler) + + LLUUID idRlvObject; bool fHasCamUnlock = gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_UNLOCK); + if (fHasBhvr) + { + // Get the UUID of the primary object + std::list lObjects; + gRlvHandler.findBehaviour(RLV_BHVR_SETCAM, lObjects); + idRlvObject = lObjects.front()->getObjectID(); + // Reset the @setcam_unlock reference count + gRlvHandler.m_Behaviours[RLV_BHVR_SETCAM_UNLOCK] = (lObjects.front()->hasBehaviour(RLV_BHVR_SETCAM_UNLOCK, false)) ? 1 : 0; + } + else + { + std::list lObjects; + // Restore the @setcam_unlock reference count + gRlvHandler.findBehaviour(RLV_BHVR_SETCAM_UNLOCK, lObjects); + gRlvHandler.m_Behaviours[RLV_BHVR_SETCAM_UNLOCK] = lObjects.size(); + } + + // Manually invoke the @setcam_unlock toggle handler if we toggled it on/off + if (fHasCamUnlock != gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_UNLOCK)) + RlvBehaviourToggleHandler::onCommandToggle(RLV_BHVR_SETCAM_UNLOCK, !fHasCamUnlock); + + gAgentCamera.switchCameraPreset( (fHasBhvr) ? CAMERA_RLV_SETCAM_VIEW : CAMERA_PRESET_REAR_VIEW ); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_EYEOFFSET)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOCUSOFFSET)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOVMIN)->setPrimaryObject(idRlvObject); + RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_FOVMAX)->setPrimaryObject(idRlvObject); +} + +// Handles: @setdebug=n|y toggles template<> template<> void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBhvr, bool fHasBhvr) { @@ -1954,6 +2014,124 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvC return RLV_RET_SUCCESS; } +// Handles: @setcam_eyeoffset[:]=force and @setcam_focusoffset[:]=force +template<> template<> +ERlvCmdRet RlvForceCamEyeFocusOffsetHandler::onCommand(const RlvCommand& rlvCmd) +{ + // Enforce exclusive camera locks + if (!RlvActions::canChangeCameraPreset(rlvCmd.getObjectID())) + return RLV_RET_FAILED_LOCK; + + LLControlVariable* pOffsetControl = gSavedSettings.getControl("CameraOffsetRLVaView"); + LLControlVariable* pFocusControl = gSavedSettings.getControl("FocusOffsetRLVaView"); + LLControlVariable* pControl = (rlvCmd.getBehaviourType() == RLV_BHVR_SETCAM_EYEOFFSET) ? pOffsetControl : pFocusControl; + if (rlvCmd.hasOption()) + { + LLVector3 vecOffset; + if (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), vecOffset)) + return RLV_RET_FAILED_OPTION; + pControl->setValue(vecOffset.getValue()); + } + else + { + pControl->resetToDefault(); + } + + gAgentCamera.switchCameraPreset( ((pOffsetControl->isDefault()) && (pFocusControl->isDefault())) ? CAMERA_PRESET_REAR_VIEW : CAMERA_RLV_SETCAM_VIEW); + return RLV_RET_SUCCESS; +} + +// Handles: @setcam_focus:[;[;]]=force +template<> template<> +ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) +{ + std::vector optionList; + if (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) + return RLV_RET_FAILED_OPTION; + + LLVector3 posAgent; + LLVector3d posGlobal; + F32 camDistance; + + // Get the focus position/object (and verify it is known) + LLUUID idObject; LLVector3 posRegion; + if (RlvCommandOptionHelper::parseOption(optionList[0], idObject)) + { + const LLViewerObject* pObj = gObjectList.findObject(idObject); + if (!pObj) + return RLV_RET_FAILED_OPTION; + if (!pObj->isAvatar()) + { + posAgent = pObj->getPositionAgent(); + posGlobal = pObj->getPositionGlobal(); + } + else + { + /*const*/ LLVOAvatar* pAvatar = (/*const*/ LLVOAvatar*)pObj; + if (pAvatar->mHeadp) + { + posAgent = pAvatar->mHeadp->getWorldPosition(); + posGlobal = pAvatar->getPosGlobalFromAgent(posAgent); + } + } + camDistance = pObj->getScale().magVec(); + } + else if (RlvCommandOptionHelper::parseOption(optionList[0], posRegion)) + { + const LLViewerRegion* pRegion = gAgent.getRegion(); + if (!pRegion) + return RLV_RET_FAILED_UNKNOWN; + posAgent = pRegion->getPosAgentFromRegion(posRegion); + posGlobal = pRegion->getPosGlobalFromRegion(posRegion); + camDistance = 0.0f; + } + else + { + return RLV_RET_FAILED_OPTION; + } + + // Get the camera distance + if ( (optionList.size() > 1) && (!optionList[1].empty()) ) + { + if (!RlvCommandOptionHelper::parseOption(optionList[1], camDistance)) + return RLV_RET_FAILED_OPTION; + } + + // Get the directional vector (or calculate it from the current camera position) + LLVector3 camDirection; + if ( (optionList.size() > 2) && (!optionList[2].empty()) ) + { + if (!RlvCommandOptionHelper::parseOption(optionList[2], camDirection)) + return RLV_RET_FAILED_OPTION; + } + else + { + camDirection = LLViewerCamera::getInstance()->getOrigin() - posAgent; + } + camDirection.normVec(); + + // Move the camera in place + gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); + gAgentCamera.setCameraPosAndFocusGlobal(posGlobal + LLVector3d(camDirection * llmax(F_APPROXIMATELY_ZERO, camDistance)), posGlobal, idObject); + + return RLV_RET_SUCCESS; +} + +// Handles: @setcam_fov[:]=force +template<> template<> +ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) +{ + if (!RlvActions::canChangeCameraFOV(rlvCmd.getObjectID())) + return RLV_RET_FAILED_LOCK; + + F32 nFOV = DEFAULT_FIELD_OF_VIEW; + if ( (rlvCmd.hasOption()) && (!RlvCommandOptionHelper::parseOption(rlvCmd.getOption(), nFOV)) ) + return RLV_RET_FAILED_OPTION; + + LLViewerCamera::getInstance()->setDefaultFOV(nFOV); + return RLV_RET_SUCCESS; +} + // Checked: 2010-08-30 (RLVa-1.2.1c) | Modified: RLVa-1.2.1c ERlvCmdRet RlvHandler::onForceWear(const LLViewerInventoryCategory* pFolder, U32 nFlags) const { diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index c389d9ca3f..35d9160b5d 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -44,9 +44,13 @@ public: // - to check @remoutfit=n -> (see RlvWearableLocks) // - to check exceptions -> isException() public: + // Returns a list of all objects containing the specified behaviour + bool findBehaviour(ERlvBehaviour eBhvr, std::list& lObjects) const; // Returns TRUE is at least one object contains the specified behaviour (and optional option) bool hasBehaviour(ERlvBehaviour eBhvr) const { return (eBhvr < RLV_BHVR_COUNT) ? (0 != m_Behaviours[eBhvr]) : false; } bool hasBehaviour(ERlvBehaviour eBhvr, const std::string& strOption) const; + // Returns TRUE if the specified object contains the specified behaviour (and optional option) + bool hasBehaviour(const LLUUID& idObj, ERlvBehaviour eBhvr, const std::string& strOption = LLStringUtil::null) const; // Returns TRUE if at least one object (except the specified one) contains the specified behaviour (and optional option) bool hasBehaviourExcept(ERlvBehaviour eBhvr, const LLUUID& idObj) const; bool hasBehaviourExcept(ERlvBehaviour eBhvr, const std::string& strOption, const LLUUID& idObj) const; @@ -207,6 +211,7 @@ protected: friend class RlvSharedRootFetcher; // Fetcher needs access to m_fFetchComplete friend class RlvGCTimer; // Timer clear its own point at destruction + template friend struct RlvBehaviourGenericHandler; template friend struct RlvCommandHandlerBaseImpl; template friend struct RlvCommandHandler; diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 3c9ee3408b..6237653cbe 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -32,9 +32,6 @@ // RlvBehaviourDictionary // -static RlvBehaviourModifier_CompMin s_RlvBehaviourModifier_CompMin; -static RlvBehaviourModifier_CompMax s_RlvBehaviourModifier_CompMax; - /* * Processing of RLVa commands used to be a big switch/case loop with one function for each command type(addrem, reply * and force). This is slowly being replaced with templated command handling which might be more confusing intially @@ -91,7 +88,6 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourInfo("attachallthis", RLV_BHVR_ATTACHTHIS, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE)); addEntry(new RlvBehaviourInfo("attachthis_except", RLV_BHVR_ATTACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_NODE)); addEntry(new RlvBehaviourInfo("attachallthis_except", RLV_BHVR_ATTACHTHISEXCEPT, RLV_TYPE_ADDREM, RlvBehaviourInfo::FORCEWEAR_SUBTREE)); - addEntry(new RlvBehaviourToggleProcessor("camunlock")); addEntry(new RlvBehaviourGenericProcessor("chatwhisper", RLV_BHVR_CHATWHISPER)); addEntry(new RlvBehaviourGenericProcessor("chatnormal", RLV_BHVR_CHATNORMAL)); addEntry(new RlvBehaviourGenericProcessor("chatshout", RLV_BHVR_CHATSHOUT)); @@ -163,6 +159,17 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("viewnote", RLV_BHVR_VIEWNOTE)); addEntry(new RlvBehaviourGenericProcessor("viewscript", RLV_BHVR_VIEWSCRIPT)); addEntry(new RlvBehaviourGenericProcessor("viewtexture", RLV_BHVR_VIEWTEXTURE)); + // Camera + addEntry(new RlvBehaviourToggleProcessor("setcam")); + addEntry(new RlvBehaviourToggleProcessor("setcam_eyeoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addModifier(RLV_BHVR_SETCAM_EYEOFFSET, RLV_MODIFIER_SETCAM_EYEOFFSET, new RlvBehaviourModifierHandler(LLVector3::zero, true, nullptr)); + addEntry(new RlvBehaviourToggleProcessor("setcam_focusoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addModifier(RLV_BHVR_SETCAM_FOCUSOFFSET, RLV_MODIFIER_SETCAM_FOCUSOFFSET, new RlvBehaviourModifierHandler(LLVector3::zero, true, nullptr)); + addEntry(new RlvBehaviourGenericProcessor("setcam_fovmin", RLV_BHVR_SETCAM_FOVMIN)); + addModifier(RLV_BHVR_SETCAM_FOVMIN, RLV_MODIFIER_SETCAM_FOVMIN, new RlvBehaviourModifierHandler(DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifier_CompMax())); + addEntry(new RlvBehaviourGenericProcessor("setcam_fovmax", RLV_BHVR_SETCAM_FOVMAX)); + addModifier(RLV_BHVR_SETCAM_FOVMAX, RLV_MODIFIER_SETCAM_FOVMAX, new RlvBehaviourModifierHandler(DEFAULT_FIELD_OF_VIEW, true, new RlvBehaviourModifier_CompMin())); + addEntry(new RlvBehaviourToggleProcessor("setcam_unlock")); // // Force-wear @@ -200,8 +207,11 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() // Force-only // addEntry(new RlvBehaviourInfo("adjustheight", RLV_BHVR_ADJUSTHEIGHT, RLV_TYPE_FORCE)); - addEntry(new RlvForceProcessor("camfocus", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor("detachme")); + addEntry(new RlvForceProcessor("setcam_focus", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addEntry(new RlvForceProcessor("setcam_eyeoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addEntry(new RlvForceProcessor("setcam_focusoffset", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); + addEntry(new RlvForceProcessor("setcam_fov", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor("setgroup")); addEntry(new RlvForceProcessor("sit")); addEntry(new RlvForceProcessor("tpto")); @@ -368,8 +378,18 @@ void RlvBehaviourDictionary::toggleBehaviourFlag(const std::string& strBhvr, ERl // RlvBehaviourModifier::RlvBehaviourModifier(const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifier_Comp* pValueComparator) - : m_DefaultValue(defaultValue), m_fAddDefaultOnEmpty(fAddDefaultOnEmpty), m_pValueComparator(pValueComparator) + : m_DefaultValue(defaultValue), m_fAddDefaultOnEmpty(fAddDefaultOnEmpty) { + m_pValueComparator = (pValueComparator) ? pValueComparator : new RlvBehaviourModifier_Comp(); +} + +RlvBehaviourModifier::~RlvBehaviourModifier() +{ + if (m_pValueComparator) + { + delete m_pValueComparator; + m_pValueComparator = NULL; + } } bool RlvBehaviourModifier::addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject) @@ -377,13 +397,21 @@ bool RlvBehaviourModifier::addValue(const RlvBehaviourModifierValue& modValue, c if (modValue.which() == m_DefaultValue.which()) { m_Values.insert((m_pValueComparator) ? std::lower_bound(m_Values.begin(), m_Values.end(), std::make_pair(modValue, idObject), boost::bind(&RlvBehaviourModifier_Comp::operator(), m_pValueComparator, _1, _2)) : m_Values.end(), std::make_pair(modValue, idObject)); - onValueChange(); + // NOTE: change signal needs to trigger before modifier handlers so cached values have a chance to update properly m_ChangeSignal(getValue()); + onValueChange(); return true; } return false; } +bool RlvBehaviourModifier::hasValue() const { + // If no primary object is set this returns "any value set"; otherwise it returns "any value set by the primary object" + if ( (!m_pValueComparator) || (m_pValueComparator->m_idPrimaryObject.isNull()) ) + return !m_Values.empty(); + return (!m_Values.empty()) ? m_Values.front().second == m_pValueComparator->m_idPrimaryObject : false; +} + void RlvBehaviourModifier::removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject) { if ( (modValue.which() == m_DefaultValue.which()) ) @@ -423,6 +451,15 @@ bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, Rl modValue = std::stoi(optionValue); return true; } + else if (typeid(LLVector3) == m_DefaultValue.type()) + { + LLVector3 vecOption; + if (3 == sscanf(optionValue.c_str(), "%f/%f/%f", vecOption.mV + 0, vecOption.mV + 1, vecOption.mV + 2)) + { + modValue = vecOption; + return true; + } + } return false; } catch (const std::invalid_argument&) diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 50b2850776..f8e94468dd 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -114,8 +114,10 @@ template using RlvForceHandler = RlvCommandHandler using RlvReplyHandler = RlvCommandHandler; // List of shared handlers -typedef RlvBehaviourHandler RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach -typedef RlvForceHandler RlvForceRemAttachHandler; // Shared between @remattach and @detach +typedef RlvBehaviourToggleHandler RlvBehaviourCamEyeFocusOffsetHandler; // Shared between @setcam_eyeoffset and @setcam_focusoffset +typedef RlvBehaviourHandler RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach +typedef RlvForceHandler RlvForceRemAttachHandler; // Shared between @remattach and @detach +typedef RlvForceHandler RlvForceCamEyeFocusOffsetHandler; // Shared between @setcam_eyeoffset and @setcam_focusoffset // // RlvCommandProcessor - Templated glue class that brings RlvBehaviourInfo, RlvCommandHandlerBaseImpl and RlvCommandHandler together @@ -197,8 +199,8 @@ struct RlvBehaviourModifier_CompMax : public RlvBehaviourModifier_Comp class RlvBehaviourModifier { public: - RlvBehaviourModifier(const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifier_Comp* pValueComparator); - virtual ~RlvBehaviourModifier() {} + RlvBehaviourModifier(const RlvBehaviourModifierValue& defaultValue, bool fAddDefaultOnEmpty, RlvBehaviourModifier_Comp* pValueComparator = nullptr); + virtual ~RlvBehaviourModifier(); /* * Member functions @@ -206,14 +208,15 @@ public: protected: virtual void onValueChange() const {} public: - bool addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject); - bool convertOptionValue(const std::string& optionValue, RlvBehaviourModifierValue& modValue) const; - bool getAddDefault() const { return m_fAddDefaultOnEmpty; } + bool addValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject); + bool convertOptionValue(const std::string& optionValue, RlvBehaviourModifierValue& modValue) const; + bool getAddDefault() const { return m_fAddDefaultOnEmpty; } const RlvBehaviourModifierValue& getDefaultValue() const { return m_DefaultValue; } - const RlvBehaviourModifierValue& getValue() const { return (!m_Values.empty()) ? m_Values.front().first : m_DefaultValue; } + const RlvBehaviourModifierValue& getValue() const { return (hasValue()) ? m_Values.front().first : m_DefaultValue; } template const T& getValue() const { return boost::get(getValue()); } - void removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject); - void setPrimaryObject(const LLUUID& idPrimaryObject); + bool hasValue() const; + void removeValue(const RlvBehaviourModifierValue& modValue, const LLUUID& idObject); + void setPrimaryObject(const LLUUID& idPrimaryObject); typedef boost::signals2::signal change_signal_t; change_signal_t& getSignal() { return m_ChangeSignal; } From c0fa9eda0ff7b2b1adfe049d4b3d2a81b4ca0df4 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 29 May 2016 23:08:55 +0200 Subject: [PATCH 08/28] Allow @tpto position to be specified as /// --HG-- branch : RLVa --- indra/newview/rlvcommon.cpp | 13 ++++++++++++ indra/newview/rlvcommon.h | 1 + indra/newview/rlvhandler.cpp | 41 ++++++++++++++++++++++++------------ 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index ae8d1e380c..a7922041f4 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -20,6 +20,7 @@ #include "llavatarnamecache.h" #include "llinstantmessage.h" #include "llnotificationsutil.h" +#include "llregionhandle.h" #include "llsdserialize.h" #include "lltrans.h" #include "llviewerparcelmgr.h" @@ -529,6 +530,18 @@ bool RlvUtil::sendChatReply(S32 nChannel, const std::string& strUTF8Text) return true; } +void RlvUtil::teleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt) +{ + if (hRegion) + { + const LLVector3d posGlobal = from_region_handle(hRegion) + (LLVector3d)posRegion; + if (vecLookAt.isExactlyZero()) + gAgent.teleportViaLocation(posGlobal); + else + gAgent.teleportViaLocationLookAt(posGlobal, vecLookAt); + } +} + // ============================================================================ // Generic menu enablers // diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h index fd52640290..7b7ca22b0b 100644 --- a/indra/newview/rlvcommon.h +++ b/indra/newview/rlvcommon.h @@ -173,6 +173,7 @@ public: static bool sendChatReply(S32 nChannel, const std::string& strUTF8Text); static bool sendChatReply(const std::string& strChannel, const std::string& strUTF8Text); + static void teleportCallback(U64 hRegion, const LLVector3& posRegion, const LLVector3& vecLookAt); protected: static bool m_fForceTp; // @standtp }; diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 0da5daeee2..900325bc15 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -36,6 +36,7 @@ #include "llsidepanelappearance.h" // @showinv - "Appearance / Edit appearance" panel #include "lltabcontainer.h" // @showinv - Tab container control for inventory tabs #include "lltoolmgr.h" // @edit +#include "llworldmapmessage.h" // @tpto // RLVa includes #include "rlvfloaters.h" @@ -1929,35 +1930,49 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) return RLV_RET_SUCCESS; } -// Handles: @tpto:[;]=force +// Handles: @tpto:[;]=force and @tpto:;[;]=force template<> template<> ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) { std::vector optionList; if (!RlvCommandOptionHelper::parseStringList(rlvCmd.getOption(), optionList)) - return RLV_RET_FAILED; - - // First option specifies the destination - LLVector3d posGlobal; - if (!RlvCommandOptionHelper::parseOption(optionList[0], posGlobal)) return RLV_RET_FAILED_OPTION; - if (optionList.size() == 1) + // We need the look-at first + LLVector3 vecLookAt = LLVector3::zero; + if (optionList.size() > 1) { - gAgent.teleportViaLocation(posGlobal); - } - else - { - // Second option specifies the angle float nAngle = 0.0f; if (!RlvCommandOptionHelper::parseOption(optionList[1], nAngle)) return RLV_RET_FAILED_OPTION; - LLVector3 vecLookAt(LLVector3::x_axis); + vecLookAt = LLVector3::x_axis; vecLookAt.rotVec(nAngle, LLVector3::z_axis); vecLookAt.normalize(); + } + + // Next figure out the destination + LLVector3d posGlobal; + if (RlvCommandOptionHelper::parseOption(optionList[0], posGlobal)) + { + if (optionList.size() == 1) + gAgent.teleportViaLocation(posGlobal); + else gAgent.teleportViaLocationLookAt(posGlobal, vecLookAt); } + else + { + std::vector posList; LLVector3 posRegion; + if ( (!RlvCommandOptionHelper::parseStringList(optionList[0], posList, std::string("/"))) || (4 != posList.size()) || + (!RlvCommandOptionHelper::parseOption(optionList[0].substr(posList[0].size() + 1), posRegion)) ) + { + return RLV_RET_FAILED_OPTION; + } + + LLWorldMapMessage::url_callback_t cb = boost::bind(&RlvUtil::teleportCallback, _1, posRegion, vecLookAt); + LLWorldMapMessage::getInstance()->sendNamedRegionRequest(posList[0], cb, std::string(""), true); + } + return RLV_RET_SUCCESS; } From 2864442dd64c8819841e57738d31f34f456915f4 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 2 Jun 2016 22:18:59 +0200 Subject: [PATCH 09/28] Added @sendchannel_except[:]=n|y (requested) --HG-- branch : RLVa --- indra/newview/llfloaterimnearbychat.cpp | 3 ++- indra/newview/rlvactions.cpp | 7 +++++++ indra/newview/rlvactions.h | 5 +++++ indra/newview/rlvdefines.h | 3 ++- indra/newview/rlvhandler.cpp | 9 +++++---- indra/newview/rlvhelper.cpp | 3 ++- indra/newview/rlvhelper.h | 1 + 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index f1b07abbc5..5f9ecbd30c 100755 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -69,6 +69,7 @@ #include "llautoreplace.h" // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0b) #include "rlvhandler.h" +#include "rlvactions.h" // [/RLVa:KB] S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0; @@ -874,7 +875,7 @@ void send_chat_from_viewer(std::string utf8_out_text, EChatType type, S32 channe else { // Don't allow chat on a non-public channel if sendchannel restricted (unless the channel is an exception) - if ( (gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHANNEL)) && (!gRlvHandler.isException(RLV_BHVR_SENDCHANNEL, channel)) ) + if (!RlvActions::canSendChannel(channel)) return; // Don't allow chat on debug channel if @sendchat, @redirchat or @rediremote restricted (shows as public chat on viewers) diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index fc53801275..c000fe27f0 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -45,6 +45,13 @@ bool RlvActions::canPlayGestures() return (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDGESTURE)); } +bool RlvActions::canSendChannel(int nChannel) +{ + return + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHANNEL)) || (gRlvHandler.isException(RLV_BHVR_SENDCHANNEL, nChannel)) ) && + ( (!gRlvHandler.hasBehaviour(RLV_BHVR_SENDCHANNELEXCEPT)) || (!gRlvHandler.isException(RLV_BHVR_SENDCHANNELEXCEPT, nChannel)) ); +} + // Checked: 2010-11-30 (RLVa-1.3.0) bool RlvActions::canSendIM(const LLUUID& idRecipient) { diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index a3fe248d2f..dc67527e9b 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -39,6 +39,11 @@ public: */ static bool canPlayGestures(); + /* + * Returns true if the user is allowed to chat on the specified channel + */ + static bool canSendChannel(int nChannel); + /* * Returns true if the user is allowed to send IMs to the specified recipient (can be an avatar or a group) */ diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 3e5335415c..3358a4f6ec 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -104,7 +104,8 @@ enum ERlvBehaviour { RLV_BHVR_CHATWHISPER, // "chatwhisper" RLV_BHVR_CHATNORMAL, // "chatnormal" RLV_BHVR_CHATSHOUT, // "chatshout" - RLV_BHVR_SENDCHANNEL, // "sendchannel" + RLV_BHVR_SENDCHANNEL, + RLV_BHVR_SENDCHANNELEXCEPT, RLV_BHVR_SENDIM, // "sendim" RLV_BHVR_SENDIMTO, // "sendimto" RLV_BHVR_RECVIM, // "recvim" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 900325bc15..c748a4de27 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -40,6 +40,7 @@ // RLVa includes #include "rlvfloaters.h" +#include "rlvactions.h" #include "rlvhandler.h" #include "rlvhelper.h" #include "rlvinventory.h" @@ -833,7 +834,7 @@ bool RlvHandler::redirectChatOrEmote(const std::string& strUTF8Text) const endRedir = m_Exceptions.upper_bound(eBhvr); itRedir != endRedir; ++itRedir) { S32 nChannel = boost::get(itRedir->second.varOption); - if ( (!hasBehaviour(RLV_BHVR_SENDCHANNEL)) || (isException(RLV_BHVR_SENDCHANNEL, nChannel)) ) + if (RlvActions::canSendChannel(nChannel)) RlvUtil::sendChatReply(nChannel, strUTF8Text); } @@ -1531,9 +1532,9 @@ void RlvBehaviourToggleHandler::onCommandToggle(ERlvBehaviour eBh RlvUIEnabler::instance().removeGenericFloaterFilter("beacons"); } -// Handles: @sendchannel[:]=n|y +// Handles: @sendchannel[:]=n|y and @sendchannel_except[:]=n|y template<> template<> -ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) +ERlvCmdRet RlvBehaviourSendChannelHandler::onCommand(const RlvCommand& rlvCmd, bool& fRefCount) { // If there's an option then it should be a valid (= positive and non-zero) chat channel if (rlvCmd.hasOption()) @@ -1930,7 +1931,7 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) return RLV_RET_SUCCESS; } -// Handles: @tpto:[;]=force and @tpto:;[;]=force +// Handles: @tpto:[;]=force and @tpto:/[;]=force template<> template<> ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) { diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index f9f15f77df..ccc3b433a6 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -75,7 +75,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourProcessor("remattach")); addEntry(new RlvBehaviourInfo("remoutfit", RLV_BHVR_REMOUTFIT, RLV_TYPE_ADDREM)); addEntry(new RlvBehaviourGenericProcessor("rez", RLV_BHVR_REZ)); - addEntry(new RlvBehaviourProcessor("sendchannel", RlvBehaviourInfo::BHVR_STRICT)); + addEntry(new RlvBehaviourProcessor("sendchannel", RlvBehaviourInfo::BHVR_STRICT)); + addEntry(new RlvBehaviourProcessor("sendchannel_except", RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("sendchat", RLV_BHVR_SENDCHAT)); addEntry(new RlvBehaviourToggleProcessor("sendim", RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("sendimto", RLV_BHVR_SENDIMTO, RlvBehaviourInfo::BHVR_STRICT)); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index f3deb05cc6..c75cc1fb9c 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -115,6 +115,7 @@ template using RlvReplyHandler = RlvCommandHandler RlvBehaviourAddRemAttachHandler; // Shared between @addattach and @remattach +typedef RlvBehaviourHandler RlvBehaviourSendChannelHandler; // Shared between @addattach and @remattach typedef RlvForceHandler RlvForceRemAttachHandler; // Shared between @remattach and @detach // From f7c69ca8f9d66bb71dcaa246d1dc40c6cec7c984 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 2 Jun 2016 23:00:23 +0200 Subject: [PATCH 10/28] [FIXED] Exception shows an avatar's UUID rather than their name if they're nearby --HG-- branch : RLVa --- indra/newview/rlvfloaters.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index b1dac2cf37..5e7cbc25af 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -74,20 +74,26 @@ std::string rlvGetItemType(const LLViewerInventoryItem* pItem) return "Unknown"; } -// Checked: 2010-03-11 (RLVa-1.2.0a) | Modified: RLVa-1.2.0g std::string rlvGetItemNameFromObjID(const LLUUID& idObj, bool fIncludeAttachPt = true) { const LLViewerObject* pObj = gObjectList.findObject(idObj); + if ( (pObj) && (pObj->isAvatar()) ) + { + LLAvatarName avName; + if (LLAvatarNameCache::get(pObj->getID(), &avName)) + return avName.getCompleteName(); + return ((LLVOAvatar*)pObj)->getFullname(); + } + const LLViewerObject* pObjRoot = (pObj) ? pObj->getRootEdit() : NULL; const LLViewerInventoryItem* pItem = ((pObjRoot) && (pObjRoot->isAttachment())) ? gInventory.getItem(pObjRoot->getAttachmentItemID()) : NULL; - std::string strItemName = (pItem) ? pItem->getName() : idObj.asString(); + const std::string strItemName = (pItem) ? pItem->getName() : idObj.asString(); if ( (!fIncludeAttachPt) || (!pObj) || (!pObj->isAttachment()) || (!isAgentAvatarValid()) ) return strItemName; - const LLViewerJointAttachment* pAttachPt = - get_if_there(gAgentAvatarp->mAttachmentPoints, RlvAttachPtLookup::getAttachPointIndex(pObjRoot), (LLViewerJointAttachment*)NULL); - std::string strAttachPtName = (pAttachPt) ? pAttachPt->getName() : std::string("Unknown"); + const LLViewerJointAttachment* pAttachPt = get_if_there(gAgentAvatarp->mAttachmentPoints, RlvAttachPtLookup::getAttachPointIndex(pObjRoot), (LLViewerJointAttachment*)NULL); + const std::string strAttachPtName = (pAttachPt) ? pAttachPt->getName() : std::string("Unknown"); return llformat("%s (%s%s)", strItemName.c_str(), strAttachPtName.c_str(), (pObj == pObjRoot) ? "" : ", child"); } From 651b53944cf8ea971029ed6e79b20959277d0aec Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 2 Jun 2016 23:00:36 +0200 Subject: [PATCH 11/28] Clear all self-owned restrictions when closing the RLVa console --HG-- branch : RLVa --- indra/newview/rlvfloaters.cpp | 5 +++++ indra/newview/rlvfloaters.h | 1 + 2 files changed, 6 insertions(+) diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index 5e7cbc25af..c09213bbaa 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -709,6 +709,11 @@ BOOL RlvFloaterConsole::postBuild() return TRUE; } +void RlvFloaterConsole::onClose(bool fQuitting) +{ + gRlvHandler.processCommand(gAgent.getID(), "clear", true); +} + void RlvFloaterConsole::addCommandReply(const std::string& strCommand, const std::string& strReply) { m_pOutputText->appendText(llformat("%s: ", strCommand.c_str()), true); diff --git a/indra/newview/rlvfloaters.h b/indra/newview/rlvfloaters.h index 683464694f..8238aa6888 100644 --- a/indra/newview/rlvfloaters.h +++ b/indra/newview/rlvfloaters.h @@ -142,6 +142,7 @@ private: */ public: BOOL postBuild() override; + void onClose(bool fQuitting) override; /* * Member functions From 958922998bcd83521d4ce4e093da1230dd65930c Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Thu, 2 Jun 2016 23:10:23 +0200 Subject: [PATCH 12/28] [FIXED] Commands implemented as extensions (@setev, @setdebug and @setdebug) fail with unknown command --HG-- branch : RLVa --- indra/newview/rlvhelper.cpp | 7 +++---- indra/newview/rlvhelper.h | 5 +++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index ccc3b433a6..f87485c56f 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -305,15 +305,14 @@ void RlvBehaviourDictionary::toggleBehaviourFlag(const std::string& strBhvr, ERl RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand) : m_fValid(false), m_idObj(idObj), m_pBhvrInfo(NULL), m_eParamType(RLV_TYPE_UNKNOWN), m_fStrict(false), m_eRet(RLV_RET_UNKNOWN) { - std::string strBehaviour; - if (m_fValid = parseCommand(strCommand, strBehaviour, m_strOption, m_strParam)) + if (m_fValid = parseCommand(strCommand, m_strBehaviour, m_strOption, m_strParam)) { S32 nTemp = 0; if ( ("n" == m_strParam) || ("add" == m_strParam) ) m_eParamType = RLV_TYPE_ADD; else if ( ("y" == m_strParam) || ("rem" == m_strParam) ) m_eParamType = RLV_TYPE_REMOVE; - else if (strBehaviour == "clear") // clear is the odd one out so just make it its own type + else if (m_strBehaviour == "clear") // clear is the odd one out so just make it its own type m_eParamType = RLV_TYPE_CLEAR; else if ("force" == m_strParam) m_eParamType = RLV_TYPE_FORCE; @@ -332,7 +331,7 @@ RlvCommand::RlvCommand(const LLUUID& idObj, const std::string& strCommand) return; } - m_pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(strBehaviour, m_eParamType, &m_fStrict); + m_pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(m_strBehaviour, m_eParamType, &m_fStrict); } bool RlvCommand::parseCommand(const std::string& strCommand, std::string& strBehaviour, std::string& strOption, std::string& strParam) diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index c75cc1fb9c..00feabc1b4 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -208,7 +208,7 @@ public: */ public: std::string asString() const; - const std::string& getBehaviour() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviour() : LLStringUtil::null; } + const std::string& getBehaviour() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviour() : m_strBehaviour; } ERlvBehaviour getBehaviourType() const { return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourType() : RLV_BHVR_UNKNOWN; } U32 getBehaviourFlags() const{ return (m_pBhvrInfo) ? m_pBhvrInfo->getBehaviourFlags() : 0; } const LLUUID& getObjectID() const { return m_idObj; } @@ -220,7 +220,7 @@ public: bool isBlocked() const { return (m_pBhvrInfo) ? m_pBhvrInfo->isBlocked() : false; } bool isStrict() const { return m_fStrict; } bool isValid() const { return m_fValid; } - ERlvCmdRet processCommand() const { return (m_pBhvrInfo) ? m_pBhvrInfo->processCommand(*this) : RLV_RET_FAILED_UNKNOWN; } + ERlvCmdRet processCommand() const { return (m_pBhvrInfo) ? m_pBhvrInfo->processCommand(*this) : RLV_RET_NO_PROCESSOR; } protected: static bool parseCommand(const std::string& strCommand, std::string& strBehaviour, std::string& strOption, std::string& strParam); @@ -237,6 +237,7 @@ public: protected: bool m_fValid; LLUUID m_idObj; + std::string m_strBehaviour; const RlvBehaviourInfo* m_pBhvrInfo; ERlvParamType m_eParamType; bool m_fStrict; From d36c0de9e622ddd6ce56578ea20766abcf326aa0 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 4 Jun 2016 13:50:58 +0200 Subject: [PATCH 13/28] Added variable sittp/tplocal distances (@sittp[:]=n|y and @tplocal[:]=n|y) --HG-- branch : RLVa --- indra/newview/llagent.cpp | 4 +-- indra/newview/llagentlistener.cpp | 2 +- indra/newview/llinspectobject.cpp | 3 ++- indra/newview/lltoolpie.cpp | 3 ++- indra/newview/llviewermenu.cpp | 6 ++--- indra/newview/rlvactions.cpp | 45 +++++++++++++++++++++++++++---- indra/newview/rlvactions.h | 7 ++++- indra/newview/rlvdefines.h | 7 ++++- indra/newview/rlvhandler.cpp | 21 +-------------- indra/newview/rlvhandler.h | 1 - indra/newview/rlvhelper.cpp | 6 +++-- 11 files changed, 67 insertions(+), 38 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 26683ae700..bd4513714f 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4158,7 +4158,7 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) // [RLVa:KB] - Checked: RLVa-2.0.0 if ( (RlvActions::isRlvEnabled()) && (!RlvUtil::isForceTp()) ) { - if ( (RlvActions::isLocalTp(pos_global)) ? !RlvActions::canTeleportToLocal() : !RlvActions::canTeleportToLocation() ) + if ( (RlvActions::isLocalTp(pos_global)) ? !RlvActions::canTeleportToLocal(pos_global) : !RlvActions::canTeleportToLocation() ) { RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_TELEPORT); return; @@ -4228,7 +4228,7 @@ void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global, const LLVe { if ( (RlvActions::isRlvEnabled()) && (!RlvUtil::isForceTp()) ) { - if ( (RlvActions::isLocalTp(pos_global)) ? !RlvActions::canTeleportToLocal() : !RlvActions::canTeleportToLocation() ) + if ( (RlvActions::isLocalTp(pos_global)) ? !RlvActions::canTeleportToLocal(pos_global) : !RlvActions::canTeleportToLocation() ) { RlvUtil::notifyBlocked(RLV_STRING_BLOCKED_TELEPORT); return; diff --git a/indra/newview/llagentlistener.cpp b/indra/newview/llagentlistener.cpp index ff3d4e6ce2..85bae5cd75 100755 --- a/indra/newview/llagentlistener.cpp +++ b/indra/newview/llagentlistener.cpp @@ -186,7 +186,7 @@ void LLAgentListener::requestSit(LLSD const & event_data) const // [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) | Modified: RLVa-1.1.0j // TODO-RLVa: [RLVa-1.2.1] Figure out how to call this? - if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canSit(object)) ) + if ( (rlv_handler_t::isEnabled()) && (!RlvActions::canSit(object)) ) { return; } diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index a2d3a15b5b..ff8fa24f68 100755 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -39,6 +39,7 @@ #include "llviewermediafocus.h" #include "llviewerobjectlist.h" // to select the requested object // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0c) +#include "rlvactions.h" #include "rlvhandler.h" #include "lltoolpie.h" // [/RLVa:KB] @@ -401,7 +402,7 @@ void LLInspectObject::updateSitLabel(LLSelectNode* nodep) if (rlv_handler_t::isEnabled()) { const LLPickInfo& pick = LLToolPie::getInstance()->getPick(); - sit_btn->setEnabled( (pick.mObjectID.notNull()) && (gRlvHandler.canSit(pick.getObject(), pick.mObjectOffset)) ); + sit_btn->setEnabled( (pick.mObjectID.notNull()) && (RlvActions::canSit(pick.getObject(), pick.mObjectOffset)) ); } // [/RLVa:KB] } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 532d902e5c..0a18faed12 100755 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -71,6 +71,7 @@ #include "llweb.h" #include "pipeline.h" // setHighlightObject // [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) +#include "rlvactions.h" #include "rlvhandler.h" // [/RLVa:KB] @@ -461,7 +462,7 @@ ECursorType LLToolPie::cursorFromObject(LLViewerObject* object) // if (isAgentAvatarValid() && !gAgentAvatarp->isSitting()) // not already sitting? // [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) | Modified: RLVa-1.2.0g if ( (isAgentAvatarValid() && !gAgentAvatarp->isSitting()) && - ((!rlv_handler_t::isEnabled()) || (gRlvHandler.canSit(object, LLToolPie::getInstance()->getHoverPick().mObjectOffset))) ) + ((!rlv_handler_t::isEnabled()) || (RlvActions::canSit(object, LLToolPie::getInstance()->getHoverPick().mObjectOffset))) ) // [/RLVa:KB] { cursor = UI_CURSOR_TOOLSIT; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 70a6718206..82945af320 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4093,7 +4093,7 @@ bool is_object_sittable() if (rlv_handler_t::isEnabled()) { const LLPickInfo& pick = LLToolPie::getInstance()->getPick(); - if ( (pick.mObjectID.notNull()) && (!gRlvHandler.canSit(pick.getObject(), pick.mObjectOffset)) ) + if ( (pick.mObjectID.notNull()) && (!RlvActions::canSit(pick.getObject(), pick.mObjectOffset)) ) return false; } // [/RLVa:KB] @@ -4132,7 +4132,7 @@ void handle_object_sit_or_stand() // if (object && object->getPCode() == LL_PCODE_VOLUME) // [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) | Modified: RLVa-1.2.0c if ( (object && object->getPCode() == LL_PCODE_VOLUME) && - ((!rlv_handler_t::isEnabled()) || (gRlvHandler.canSit(object, pick.mObjectOffset))) ) + ((!rlv_handler_t::isEnabled()) || (RlvActions::canSit(object, pick.mObjectOffset))) ) // [/RLVa:KB] { // [RLVa:KB] - Checked: 2010-08-29 (RLVa-1.2.1c) | Added: RLVa-1.2.1c @@ -6338,7 +6338,7 @@ bool enable_object_sit(LLUICtrl* ctrl) { const LLPickInfo& pick = LLToolPie::getInstance()->getPick(); if (pick.mObjectID.notNull()) - sitting_on_sel = !gRlvHandler.canSit(pick.getObject(), pick.mObjectOffset); + sitting_on_sel = !RlvActions::canSit(pick.getObject(), pick.mObjectOffset); } // [/RLVa:KB] diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index c000fe27f0..cd8c32b369 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -105,28 +105,63 @@ bool RlvActions::autoAcceptTeleportRequest(const LLUUID& idRequester) // Teleporting // -bool RlvActions::canTeleportToLocal() +bool RlvActions::canTeleportToLocal(const LLVector3d& posGlobal) { - return (!gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_TPLOCAL)) && (RlvActions::canStand()); + // User can initiate a local teleport if: + // - not restricted from "sit teleporting" (or the destination is within the allowed xy-radius) + // - not restricted from teleporting locally (or the destination is within the allowed xy-radius) + // - can stand up (or isn't sitting) + // NOTE: if we're teleporting due to an active command we should disregard any restrictions from the same object + const LLUUID& idRlvObjExcept = gRlvHandler.getCurrentObject(); + bool fCanStand = RlvActions::canStand(idRlvObjExcept); + if ( (fCanStand) && ((gRlvHandler.hasBehaviourExcept(RLV_BHVR_SITTP, gRlvHandler.getCurrentObject())) || (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, gRlvHandler.getCurrentObject()))) ) + { + // User can stand up but is either @sittp or @tplocal restricted so we need to distance check + const F32 nDistSq = (LLVector2(posGlobal.mdV[0], posGlobal.mdV[1]) - LLVector2(gAgent.getPositionGlobal().mdV[0], gAgent.getPositionGlobal().mdV[1])).lengthSquared(); + F32 nMaxDist = llmin(RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_TPLOCALDIST)->getValue(), RLV_MODIFIER_TPLOCAL_DEFAULT); + if (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP)) + nMaxDist = llmin(nMaxDist, RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SITTPDIST)->getValue()); + return (nDistSq < nMaxDist * nMaxDist); + } + return fCanStand; } 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 = gRlvHandler.getCurrentObject(); - return (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, idRlvObjExcept)) && (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, idRlvObjExcept)) && (RlvActions::canStand(idRlvObjExcept)); + return (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, idRlvObjExcept)) && (RlvActions::canStand(idRlvObjExcept)); } bool RlvActions::isLocalTp(const LLVector3d& posGlobal) { - F32 nDistSq = (LLVector2(posGlobal.mdV[0], posGlobal.mdV[1]) - LLVector2(gAgent.getPositionGlobal().mdV[0], gAgent.getPositionGlobal().mdV[1])).lengthSquared(); - return nDistSq < RLV_TELEPORT_LOCAL_RADIUS * RLV_TELEPORT_LOCAL_RADIUS; + 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; } // ============================================================================ // World interaction // +bool RlvActions::canSit(LLViewerObject* pObj, const LLVector3& posOffset /*= LLVector3::zero*/) +{ + // The user can sit on the specified object if: + // - 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:=force) + // - not @sittp=n or @fartouch=n restricted or if they clicked on a point within the allowed radius + static RlvCachedBehaviourModifier 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 != gRlvHandler.getCurrentCommand()) && (RLV_BHVR_SIT == gRlvHandler.getCurrentCommand()->getBehaviourType()) ) || + ( ((!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)) < RLV_MODIFIER_FARTOUCH_DEFAULT * RLV_MODIFIER_FARTOUCH_DEFAULT)) ) ); +} + 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 diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index dc67527e9b..4857ead416 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -100,7 +100,7 @@ public: /* * Returns true if the user can teleport locally (short distances) */ - static bool canTeleportToLocal(); + static bool canTeleportToLocal(const LLVector3d& posGlobal); /* * Returns true if the user can teleport to a (remote) location @@ -116,6 +116,11 @@ public: // World interaction // ================= public: + /* + * Returns true if the user can sit up on the specified object + */ + static bool canSit(LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero); + /* * Returns true if the user can stand up (returns true if the user isn't currently sitting) */ diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 7b21e8bb51..3d90218d77 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -66,13 +66,15 @@ const S32 RLVa_VERSION_BUILD = 0; #define RLV_ROOT_FOLDER "#RLV" #define RLV_CMD_PREFIX '@' +#define RLV_MODIFIER_TPLOCAL_DEFAULT 256.f // Any teleport that's more than a region away is non-local +#define RLV_MODIFIER_FARTOUCH_DEFAULT 1.5f // Specifies the default @fartouch distance +#define RLV_MODIFIER_SITTP_DEFAULT 1.5f // Specifies the default @sittp distance #define RLV_OPTION_SEPARATOR ";" // Default separator used in command options #define RLV_PUTINV_PREFIX "#RLV/~" #define RLV_PUTINV_SEPARATOR "/" #define RLV_PUTINV_MAXDEPTH 4 #define RLV_SETROT_OFFSET F_PI_BY_TWO // @setrot is off by 90° with the rest of SL #define RLV_STRINGS_FILE "rlva_strings.xml" -#define RLV_TELEPORT_LOCAL_RADIUS 256 // Any teleport that's more than a region away is non-local #define RLV_FOLDER_FLAG_NOSTRIP "nostrip" #define RLV_FOLDER_PREFIX_HIDDEN '.' @@ -196,6 +198,9 @@ enum ERlvBehaviour { enum ERlvBehaviourModifier { + RLV_MODIFIER_SITTPDIST, + RLV_MODIFIER_TPLOCALDIST, + RLV_MODIFIER_COUNT, RLV_MODIFIER_UNKNOWN }; diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index 368f311595..c1c4b7d807 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -684,25 +684,6 @@ void RlvHandler::onTeleportFinished(const LLVector3d& posArrival) // String/chat censoring functions // -// Checked: 2010-03-06 (RLVa-1.2.0c) | Added: RLVa-1.1.0j -bool RlvHandler::canSit(LLViewerObject* pObj, const LLVector3& posOffset /*= LLVector3::zero*/) const -{ - // The user can sit on the specified object if: - // - 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:=force) - // - not @sittp=n or @fartouch=n restricted or if they clicked on a point within 1.5m of the avie's current position - return - ( (pObj) && (LL_PCODE_VOLUME == pObj->getPCode()) ) && - (!hasBehaviour(RLV_BHVR_SIT)) && - ( ((!hasBehaviour(RLV_BHVR_UNSIT)) && (!hasBehaviour(RLV_BHVR_STANDTP))) || - ((isAgentAvatarValid()) && (!gAgentAvatarp->isSitting())) ) && - ( ( (NULL != getCurrentCommand()) && (RLV_BHVR_SIT == getCurrentCommand()->getBehaviourType()) ) || - ( (!hasBehaviour(RLV_BHVR_SITTP)) && (!hasBehaviour(RLV_BHVR_FARTOUCH)) ) || - (dist_vec_squared(gAgent.getPositionGlobal(), pObj->getPositionGlobal() + LLVector3d(posOffset)) < 1.5f * 1.5f) ); -} - // Checked: 2010-04-11 (RLVa-1.3.0h) | Modified: RLVa-1.3.0h bool RlvHandler::canTouch(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/) const { @@ -1948,7 +1929,7 @@ ERlvCmdRet RlvForceHandler::onCommand(const RlvCommand& rlvCmd) if ( (idTarget.isNull()) || ((pObj = gObjectList.findObject(idTarget)) == NULL) || (LL_PCODE_VOLUME != pObj->getPCode()) ) return RLV_RET_FAILED_OPTION; - if (!gRlvHandler.canSit(pObj)) + if (!RlvActions::canSit(pObj)) return RLV_RET_FAILED_LOCK; else if ( (gRlvHandler.hasBehaviour(RLV_BHVR_STANDTP)) && (isAgentAvatarValid()) ) { diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index c389d9ca3f..64acf59c5d 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -96,7 +96,6 @@ public: // Command specific helper functions bool canEdit(const LLViewerObject* pObj) const; // @edit and @editobj bool canShowHoverText(const LLViewerObject* pObj) const; // @showhovertext* command family - bool canSit(LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero) const; bool canTouch(const LLViewerObject* pObj, const LLVector3& posOffset = LLVector3::zero) const; // @touch bool filterChat(std::string& strUTF8Text, bool fFilterEmote) const; // @sendchat, @recvchat and @redirchat bool redirectChatOrEmote(const std::string& strUTF8Test) const; // @redirchat and @rediremote diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index 7e78b05ec2..4a4d8356b3 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -139,7 +139,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("shownames", RLV_BHVR_SHOWNAMES)); addEntry(new RlvBehaviourGenericProcessor("showworldmap", RLV_BHVR_SHOWWORLDMAP)); addEntry(new RlvBehaviourGenericProcessor("sit", RLV_BHVR_SIT)); - addEntry(new RlvBehaviourGenericProcessor("sittp", RLV_BHVR_SITTP)); + addEntry(new RlvBehaviourGenericProcessor("sittp", RLV_BHVR_SITTP)); + addModifier(RLV_BHVR_SITTP, RLV_MODIFIER_SITTPDIST, new RlvBehaviourModifier(RLV_MODIFIER_SITTP_DEFAULT, true, &s_RlvBehaviourModifier_CompMin)); addEntry(new RlvBehaviourGenericProcessor("standtp", RLV_BHVR_STANDTP)); addEntry(new RlvBehaviourGenericProcessor("startim", RLV_BHVR_STARTIM, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("startimto", RLV_BHVR_STARTIMTO, RlvBehaviourInfo::BHVR_STRICT)); @@ -155,7 +156,8 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvBehaviourGenericProcessor("touchworld", RLV_BHVR_TOUCHWORLD)); addEntry(new RlvBehaviourGenericProcessor("tplm", RLV_BHVR_TPLM)); addEntry(new RlvBehaviourGenericProcessor("tploc", RLV_BHVR_TPLOC)); - addEntry(new RlvBehaviourGenericProcessor("tplocal", RLV_BHVR_TPLOCAL)); + addEntry(new RlvBehaviourGenericProcessor("tplocal", RLV_BHVR_TPLOCAL)); + addModifier(RLV_BHVR_TPLOCAL, RLV_MODIFIER_TPLOCALDIST, new RlvBehaviourModifier(RLV_MODIFIER_TPLOCAL_DEFAULT, true, &s_RlvBehaviourModifier_CompMin)); addEntry(new RlvBehaviourGenericProcessor("tplure", RLV_BHVR_TPLURE, RlvBehaviourInfo::BHVR_STRICT)); addEntry(new RlvBehaviourGenericProcessor("tprequest", RLV_BHVR_TPREQUEST, RlvBehaviourInfo::BHVR_STRICT | RlvBehaviourInfo::BHVR_EXTENDED)); addEntry(new RlvBehaviourInfo("unsharedunwear", RLV_BHVR_UNSHAREDUNWEAR, RLV_TYPE_ADDREM)); From 60f93645aa2d5bd5d29da158fd3d90c317c39a64 Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sat, 4 Jun 2016 14:58:00 +0200 Subject: [PATCH 14/28] [FIXED] RlvHandler::hasBehaviourExcept() returns FALSE on modifier commands -> Example: issue @tplocal:50=n -> gRlvHandler.hasBehaviour(RLV_BHVR_TPLOCAL) will return true but gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOCAL, LLUUID::null) will return FALSE => since it's a modifier command it will be reference counted but that fact is lost on manual matching (tplocal=n != tplocal: