diff --git a/indra/newview/rlvactions.cpp b/indra/newview/rlvactions.cpp index 0a2c8b5b587c1b5ef40d8b7f6501ea1d066b1e14..ee8ca58e8216f3d0ab687450a0643b8c85062d24 100644 --- a/indra/newview/rlvactions.cpp +++ b/indra/newview/rlvactions.cpp @@ -464,6 +464,12 @@ bool RlvActions::canGroundSit() return (!hasBehaviour(RLV_BHVR_SIT)) && (canStand()); } +bool RlvActions::canGroundSit(const LLUUID& idRlvObjExcept) +{ + // See canGroundSit() but disregard any restrictions held by the issuing object + return (!gRlvHandler.hasBehaviourExcept(RLV_BHVR_SIT, idRlvObjExcept)) && (canStand(idRlvObjExcept)); +} + bool RlvActions::canSit(const LLViewerObject* pObj, const LLVector3& posOffset /*=LLVector3::zero*/) { // User can sit on the specified object if: diff --git a/indra/newview/rlvactions.h b/indra/newview/rlvactions.h index 889da1e6458c906669dbf51e10f1411a95c0e30c..69d499280c0d0e83f5edf78028d88a9ffc2de345 100644 --- a/indra/newview/rlvactions.h +++ b/indra/newview/rlvactions.h @@ -254,6 +254,7 @@ class RlvActions * Returns true if the user can sit on the ground */ static bool canGroundSit(); + static bool canGroundSit(const LLUUID& idRlvObjExcept); /* * Returns true if the user can interact with the specified object (with an optional relative offset) diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 13631811d23152a3e95c0ab9fd1392bee968f213..a9b55b552324d210151d54267ecb41d64a31b713 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -176,6 +176,7 @@ enum ERlvBehaviour { RLV_BHVR_SETGROUP, // "setgroup" RLV_BHVR_UNSIT, // "unsit" RLV_BHVR_SIT, // "sit" + RLV_BHVR_SITGROUND, RLV_BHVR_SITTP, // "sittp" RLV_BHVR_STANDTP, // "standtp" RLV_BHVR_SETDEBUG, // "setdebug" diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index d2117cbeaf04a40036c09c47783f82aac60a150c..ba136231fb95364f7d104ee8873c2488e0e8ae35 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -902,6 +902,12 @@ void RlvHandler::onSitOrStand(bool fSitting) doOnIdleOneTime(boost::bind(RlvUtil::forceTp, m_posSitSource)); m_posSitSource.setZero(); } + else if ( (!fSitting) && (m_fPendingGroundSit) ) + { + m_fPendingGroundSit = false; + gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + send_agent_update(TRUE, TRUE); + } } // Checked: 2010-03-11 (RLVa-1.2.0a) | Modified: RLVa-1.2.0a @@ -3142,6 +3148,28 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SETGROUP>::onCommand(const RlvCommand& rlvCm return (fValid) ? RLV_RET_SUCCESS : RLV_RET_FAILED_OPTION; } +// Handles: @sitground=force +template<> template<> +ERlvCmdRet RlvForceHandler<RLV_BHVR_SITGROUND>::onCommand(const RlvCommand& rlvCmd) +{ + if ( (!RlvActions::canGroundSit(rlvCmd.getObjectID())) || (!isAgentAvatarValid()) ) + return RLV_RET_FAILED_LOCK; + + if (!gAgentAvatarp->isSitting()) + { + gRlvHandler.m_fPendingGroundSit = false; + gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + } + else if (gAgentAvatarp->getParent()) + { + gRlvHandler.m_fPendingGroundSit = true; + gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + } + send_agent_update(TRUE, TRUE); + + return RLV_RET_SUCCESS; +} + // Handles: @sit:<uuid>=force template<> template<> ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd) @@ -3153,10 +3181,7 @@ ERlvCmdRet RlvForceHandler<RLV_BHVR_SIT>::onCommand(const RlvCommand& rlvCmd) LLViewerObject* pObj = NULL; if (idTarget.isNull()) { - if ( (!RlvActions::canGroundSit()) || ((isAgentAvatarValid()) && (gAgentAvatarp->isSitting())) ) - return RLV_RET_FAILED_LOCK; - gAgent.sitDown(); - send_agent_update(TRUE, TRUE); + return RlvForceHandler<RLV_BHVR_SITGROUND>::onCommand(rlvCmd); } else if ( ((pObj = gObjectList.findObject(idTarget)) != NULL) && (LL_PCODE_VOLUME == pObj->getPCode())) { diff --git a/indra/newview/rlvhandler.h b/indra/newview/rlvhandler.h index 01da4b6269b0414c7d480a0bb8d2b52d7ba1eea9..e36782c52afb36f679b4b23f75ee4218071716c8 100644 --- a/indra/newview/rlvhandler.h +++ b/indra/newview/rlvhandler.h @@ -266,6 +266,7 @@ class RlvHandler : public LLOldEvents::LLSimpleListener, public LLParticularGrou bool m_fCanCancelTp; // @accepttp=n and @tpto=force mutable LLVector3d m_posSitSource; // @standtp=n (mutable because onForceXXX handles are all declared as const) + mutable bool m_fPendingGroundSit = false; // @sitground=force mutable LLUUID m_idAgentGroup; // @setgroup=n std::pair<LLUUID, std::string> m_PendingGroupChange; // @setgroup=force std::pair<LLTimer, LLUUID> m_GroupChangeExpiration; // @setgroup=force diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index dcef3f982747736ef4cce49dd447d32fce16f9c1..207ca5cebd410ba5a7b701b28a50cb7d22513614 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -287,6 +287,7 @@ RlvBehaviourDictionary::RlvBehaviourDictionary() addEntry(new RlvForceProcessor<RLV_BHVR_SETCAM_MODE>("setcam_mode", RlvBehaviourInfo::BHVR_EXPERIMENTAL)); addEntry(new RlvForceProcessor<RLV_BHVR_SETGROUP>("setgroup")); addEntry(new RlvForceProcessor<RLV_BHVR_SIT>("sit")); + addEntry(new RlvForceProcessor<RLV_BHVR_SITGROUND>("sitground")); addEntry(new RlvForceProcessor<RLV_BHVR_TPTO>("tpto")); addEntry(new RlvBehaviourInfo("unsit", RLV_BHVR_UNSIT, RLV_TYPE_FORCE));