From 36913120e5956e437f1f214ff74af0e26ead4b3d Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Sun, 10 Jan 2021 23:34:01 +0100 Subject: [PATCH] Clear local modifiers when their base restriction is removed (after some feedback) --- indra/newview/rlvcommon.cpp | 2 ++ indra/newview/rlvdefines.h | 1 + indra/newview/rlveffects.cpp | 44 ----------------------------------- indra/newview/rlvfloaters.cpp | 2 +- indra/newview/rlvhandler.cpp | 4 +++- indra/newview/rlvhelper.cpp | 31 +++++++++++++++++++++--- indra/newview/rlvhelper.h | 8 +++++-- 7 files changed, 41 insertions(+), 51 deletions(-) diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index 0eee08d0a6..d4b9e30232 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -399,6 +399,8 @@ const char* RlvStrings::getStringFromReturnCode(ERlvCmdRet eRet) return "deprecated and disabled"; case RLV_RET_FAILED_NOBEHAVIOUR: return "no active behaviours"; + case RLV_RET_FAILED_UNHELDBEHAVIOUR: + return "base behaviour not held"; case RLV_RET_FAILED_BLOCKED: return "blocked object"; case RLV_RET_FAILED_THROTTLED: diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h index 690bda54fc..c1d2959ed9 100644 --- a/indra/newview/rlvdefines.h +++ b/indra/newview/rlvdefines.h @@ -335,6 +335,7 @@ enum ERlvCmdRet { RLV_RET_FAILED_NOSHAREDROOT, // Command failed (missing #RLV) RLV_RET_FAILED_DEPRECATED, // Command failed (deprecated and no longer supported) RLV_RET_FAILED_NOBEHAVIOUR, // Command failed (force modifier on an object with no active restrictions) + RLV_RET_FAILED_UNHELDBEHAVIOUR, // Command failed (local modifier on an object that doesn't hold the base behaviour) RLV_RET_FAILED_BLOCKED, // Command failed (object is blocked) RLV_RET_FAILED_THROTTLED, // Command failed (throttled) RLV_RET_NO_PROCESSOR // Command doesn't have a template processor define (legacy code) diff --git a/indra/newview/rlveffects.cpp b/indra/newview/rlveffects.cpp index 454a9db38c..9a14f848e7 100644 --- a/indra/newview/rlveffects.cpp +++ b/indra/newview/rlveffects.cpp @@ -42,22 +42,6 @@ RlvOverlayEffect::RlvOverlayEffect(const LLUUID& idRlvObj) , m_fBlockTouch(false) , m_Color(LLColor3(c_DefaultColor)) { - if (RlvObject* pRlvObj = gRlvHandler.getObject(idRlvObj)) - { - float nAlpha; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::OverlayAlpha, nAlpha)) - m_nAlpha = nAlpha; - - pRlvObj->getModifierValue(ERlvLocalBhvrModifier::OverlayTouch, m_fBlockTouch); - - LLVector3 vecColor; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::OverlayTint, vecColor)) - m_Color = LLColor3(vecColor.mV); - - LLUUID idTexture; - if ( (pRlvObj) && (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::OverlayTexture, idTexture)) ) - setImage(idTexture); - } } RlvOverlayEffect::~RlvOverlayEffect() @@ -198,34 +182,6 @@ RlvSphereEffect::RlvSphereEffect(const LLUUID& idRlvObj) , m_nValueMin(c_SphereDefaultAlpha), m_nValueMax(c_SphereDefaultAlpha) , m_nTweenDuration(0.f) { - if (RlvObject* pRlvObj = gRlvHandler.getObject(idRlvObj)) - { - int nNumber; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereMode, nNumber)) - m_eMode = (ESphereMode)nNumber; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereOrigin, nNumber)) - m_eOrigin = (ESphereOrigin)nNumber; - - LLVector3 vecColor; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereColor, vecColor)) - m_Params = LLVector4(vecColor.mV[VX], vecColor.mV[VY], vecColor.mV[VZ], 1.0f); - LLVector4 vecParams; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereParams, vecParams)) - m_Params = vecParams; - - float nFloat; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereDistMin, nFloat)) - m_nDistanceMin = nFloat; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereDistMax, nFloat)) - m_nDistanceMax = nFloat; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereDistExtend, nNumber)) - m_eDistExtend = (ESphereDistExtend)nNumber; - - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereValueMin, nFloat)) - m_nValueMin = nFloat; - if (pRlvObj->getModifierValue(ERlvLocalBhvrModifier::SphereValueMax, nFloat)) - m_nValueMax = nFloat; - } } RlvSphereEffect::~RlvSphereEffect() diff --git a/indra/newview/rlvfloaters.cpp b/indra/newview/rlvfloaters.cpp index 5f90fa1259..b0b089e138 100644 --- a/indra/newview/rlvfloaters.cpp +++ b/indra/newview/rlvfloaters.cpp @@ -813,7 +813,7 @@ void RlvFloaterConsole::onInput(LLUICtrl* pCtrl, const LLSD& sdParam) strCmd.clear(); // Only show feedback on successful commands when there's an informational notice if (!pstr->empty()) - pstr->push_back(','); + pstr->append(", "); pstr->append(strCmd); } diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index e0acc3c279..5d9e16fac6 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -1717,6 +1717,8 @@ ERlvCmdRet RlvCommandHandlerBaseImpl::processCommand(const RlvC { if (rlvCmd.isStrict()) gRlvHandler.removeException(rlvCmd.getObjectID(), RLV_BHVR_PERMISSIVE, eBhvr); + if (RlvObject* pRlvObj = gRlvHandler.getObject(rlvCmd.getObjectID())) + pRlvObj->clearModifiers(eBhvr); gRlvHandler.m_Behaviours[eBhvr]--; } @@ -2085,7 +2087,7 @@ ERlvCmdRet RlvBehaviourHandler::onCommand(const RlvCommand& else LLVfxManager::instance().removeEffect(gRlvHandler.getCurrentObject()); } - return RLV_RET_SUCCESS; + return eRet; } // Handles: @sendchannel[:]=n|y and @sendchannel_except[:]=n|y diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp index d56f0898f4..3b369cd7a5 100644 --- a/indra/newview/rlvhelper.cpp +++ b/indra/newview/rlvhelper.cpp @@ -406,6 +406,20 @@ void RlvBehaviourDictionary::clearModifiers(const LLUUID& idRlvObj) } } +const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(ERlvBehaviour eBhvr, ERlvParamType eParamType) const +{ + const RlvBehaviourInfo* pBhvrInfo = nullptr; + for (auto itBhvrLower = m_Bhvr2InfoMap.lower_bound(eBhvr), itBhvrUpper = m_Bhvr2InfoMap.upper_bound(eBhvr); + std::find_if(itBhvrLower, itBhvrUpper, [eBhvr, eParamType](const rlv_bhvr2info_map_t::value_type& bhvrEntry) { return bhvrEntry.second->getParamTypeMask() == eParamType; }) != itBhvrUpper; + ++itBhvrLower) + { + if (pBhvrInfo) + return nullptr; + pBhvrInfo = itBhvrLower->second; + } + return pBhvrInfo; +} + const RlvBehaviourInfo* RlvBehaviourDictionary::getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict, ERlvLocalBhvrModifier* peBhvrModifier) const { size_t idxBhvrLastPart = strBhvr.find_last_of('_'); @@ -491,9 +505,9 @@ void RlvBehaviourDictionary::toggleBehaviourFlag(const std::string& strBhvr, ERl // virtual ERlvCmdRet RlvBehaviourInfo::processModifier(const RlvCommand& rlvCmd) const { - // The object should be holding at least one active behaviour - if (!gRlvHandler.hasBehaviour(rlvCmd.getObjectID())) - return RLV_RET_FAILED_NOBEHAVIOUR; + // The object should have the base behaviour set (or else there's nothing to modify) + if (!gRlvHandler.hasBehaviour(rlvCmd.getObjectID(), rlvCmd.getBehaviourType())) + return RLV_RET_FAILED_UNHELDBEHAVIOUR; auto itBhvrModifier = std::find_if(m_BhvrModifiers.begin(), m_BhvrModifiers.end(), [&rlvCmd](const modifier_lookup_t::value_type& entry) { return std::get<0>(entry.second) == rlvCmd.getBehaviourModifier(); }); if (m_BhvrModifiers.end() == itBhvrModifier) @@ -1147,6 +1161,17 @@ std::string RlvObject::getStatusString(const std::string& strFilter, const std:: return strStatus; } +void RlvObject::clearModifiers(ERlvBehaviour eBhvr) +{ + if (const RlvBehaviourInfo* pBhvrInfo = RlvBehaviourDictionary::instance().getBehaviourInfo(eBhvr, RLV_TYPE_ADDREM)) + { + for (const auto& modifierEntry : pBhvrInfo->getModifiers()) + { + clearModifierValue(std::get<0>(modifierEntry.second)); + } + } +} + void RlvObject::clearModifierValue(ERlvLocalBhvrModifier eBhvrModifier) { m_Modifiers.erase(eBhvrModifier); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index f5e9c7c6d2..f3a758d215 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -40,6 +40,8 @@ class RlvBehaviourInfo { typedef std::function)> modifier_handler_func_t; public: + typedef std::map> modifier_lookup_t; + enum EBehaviourFlags { // General behaviour flags @@ -71,6 +73,7 @@ public: ERlvBehaviour getBehaviourType() const { return m_eBhvr; } U32 getBehaviourFlags() const { return m_nBhvrFlags; } U32 getParamTypeMask() const { return m_maskParamType; } + const modifier_lookup_t& getModifiers() const { return m_BhvrModifiers; } bool hasStrict() const { return m_nBhvrFlags & BHVR_STRICT; } bool isBlocked() const { return m_nBhvrFlags & BHVR_BLOCKED; } bool isExperimental() const { return m_nBhvrFlags & BHVR_EXPERIMENTAL; } @@ -87,7 +90,6 @@ protected: ERlvBehaviour m_eBhvr; U32 m_nBhvrFlags; U32 m_maskParamType; - typedef std::map> modifier_lookup_t; modifier_lookup_t m_BhvrModifiers; }; @@ -112,7 +114,8 @@ public: public: void clearModifiers(const LLUUID& idRlvObj); ERlvBehaviour getBehaviourFromString(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = NULL) const; - const RlvBehaviourInfo* getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = nullptr, ERlvLocalBhvrModifier* peBhvrModifier = nullptr) const; + const RlvBehaviourInfo* getBehaviourInfo(ERlvBehaviour eBhvr, ERlvParamType eParamType) const; + const RlvBehaviourInfo* getBehaviourInfo(const std::string& strBhvr, ERlvParamType eParamType, bool* pfStrict = nullptr, ERlvLocalBhvrModifier* peBhvrModifier = nullptr) const; bool getCommands(const std::string& strMatch, ERlvParamType eParamType, std::list& cmdList) const; bool getHasStrict(ERlvBehaviour eBhvr) const; RlvBehaviourModifier* getModifier(ERlvBehaviourModifier eBhvrMod) const { return (eBhvrMod < RLV_MODIFIER_COUNT) ? m_BehaviourModifiers[eBhvrMod] : nullptr; } @@ -467,6 +470,7 @@ public: * Local-scope modifiers */ public: + void clearModifiers(ERlvBehaviour eBhvr); void clearModifierValue(ERlvLocalBhvrModifier eBhvrMod); template bool getModifierValue(ERlvLocalBhvrModifier eBhvrModifier, T& value) const; void setModifierValue(ERlvLocalBhvrModifier eBhvrMod, const RlvBehaviourModifierValue& modValue);