diff options
Diffstat (limited to 'linden/indra/newview/rlvhandler.cpp')
-rw-r--r-- | linden/indra/newview/rlvhandler.cpp | 173 |
1 files changed, 79 insertions, 94 deletions
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp index 2915002..6044aa9 100644 --- a/linden/indra/newview/rlvhandler.cpp +++ b/linden/indra/newview/rlvhandler.cpp | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | 1 | #include "llviewerprecompiledheaders.h" |
2 | #include "llagent.h" | 2 | #include "llagent.h" |
3 | #include "lldrawpoolalpha.h" | 3 | #include "lldrawpoolalpha.h" |
4 | #include "llfirstuse.h" | ||
4 | #include "llfloaterbeacons.h" | 5 | #include "llfloaterbeacons.h" |
5 | #include "llfloaterchat.h" | 6 | #include "llfloaterchat.h" |
6 | #include "llfloaterdaycycle.h" | 7 | #include "llfloaterdaycycle.h" |
@@ -93,10 +94,10 @@ inline bool rlvIsWearingItem(const LLInventoryItem* pItem) | |||
93 | static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, std::string& strFilter) | 94 | static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, std::string& strFilter) |
94 | { | 95 | { |
95 | boost_tokenizer tokens(strOption, boost::char_separator<char>(";", "", boost::keep_empty_tokens)); | 96 | boost_tokenizer tokens(strOption, boost::char_separator<char>(";", "", boost::keep_empty_tokens)); |
96 | boost_tokenizer::iterator itTok = tokens.begin(); | 97 | boost_tokenizer::const_iterator itTok = tokens.begin(); |
97 | 98 | ||
98 | // Extract and sanity check the first token (required) which is the channel | 99 | // Extract and sanity check the first token (required) which is the channel |
99 | if ( (itTok == tokens.end()) || (!LLStringUtil::convertToS32(*itTok, nChannel)) || (!rlvIsValidChannel(nChannel)) ) | 100 | if ( (itTok == tokens.end()) || (!LLStringUtil::convertToS32(*itTok, nChannel)) || (!rlvIsValidReplyChannel(nChannel)) ) |
100 | return false; | 101 | return false; |
101 | 102 | ||
102 | // Second token (optional) is the filter | 103 | // Second token (optional) is the filter |
@@ -274,7 +275,7 @@ bool RlvHandler::isDetachableExcept(S32 idxAttachPt, LLViewerObject *pObj) const | |||
274 | return true; | 275 | return true; |
275 | } | 276 | } |
276 | 277 | ||
277 | // Checked: 2009-05-31 (RLVa-0.2.0e) | Modified: RLVa-0.2.0e | 278 | // Checked: 2009-09-06 (RLVa-1.0.2b) | Modified: RLVa-1.0.2b |
278 | bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable) | 279 | bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable) |
279 | { | 280 | { |
280 | // Sanity check - make sure it's an object we know about | 281 | // Sanity check - make sure it's an object we know about |
@@ -284,20 +285,16 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe | |||
284 | 285 | ||
285 | if (!fDetachable) | 286 | if (!fDetachable) |
286 | { | 287 | { |
287 | // Sanity check - make sure it's not already marked undetachable by this object (NOTE: m_Attachments is a *multimap*, not a map) | 288 | #ifdef RLV_EXPERIMENTAL_FIRSTUSE |
288 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | 289 | LLFirstUse::useRlvDetach(); |
289 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | 290 | #endif // RLV_EXPERIMENTAL_FIRSTUSE |
290 | { | ||
291 | if (itObj->second.m_UUID == itAttach->second) | ||
292 | return false; | ||
293 | } | ||
294 | 291 | ||
292 | // NOTE: m_Attachments can contain duplicate <idxAttachPt, idRlvObj> pairs (ie @detach:spine=n,detach=n from an attachment on spine) | ||
295 | m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID)); | 293 | m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID)); |
296 | return true; | 294 | return true; |
297 | } | 295 | } |
298 | else | 296 | else |
299 | { | 297 | { |
300 | // NOTE: m_Attachments is a *multimap*, not a map | ||
301 | for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | 298 | for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt), |
302 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | 299 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) |
303 | { | 300 | { |
@@ -325,11 +322,11 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe | |||
325 | LLViewerInventoryItem* pItem = gInventory.getItem(idItem); | 322 | LLViewerInventoryItem* pItem = gInventory.getItem(idItem); |
326 | if (pItem) | 323 | if (pItem) |
327 | { | 324 | { |
328 | if (-1 != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) | 325 | if (std::string::npos != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) |
329 | return false; | 326 | return false; |
330 | 327 | ||
331 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); | 328 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); |
332 | if ( (pFolder) && (-1 != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) | 329 | if ( (pFolder) && (std::string::npos != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) |
333 | return false; | 330 | return false; |
334 | } | 331 | } |
335 | } | 332 | } |
@@ -477,6 +474,10 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
477 | } | 474 | } |
478 | } | 475 | } |
479 | break; | 476 | break; |
477 | case RLV_TYPE_CLEAR: | ||
478 | fRet = processClearCommand(uuid, rlvCmd); | ||
479 | notifyBehaviourObservers(rlvCmd, !fFromObj); | ||
480 | break; | ||
480 | case RLV_TYPE_FORCE: // Checked: | 481 | case RLV_TYPE_FORCE: // Checked: |
481 | fRet = processForceCommand(uuid, rlvCmd); | 482 | fRet = processForceCommand(uuid, rlvCmd); |
482 | break; | 483 | break; |
@@ -484,32 +485,6 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
484 | fRet = processReplyCommand(uuid, rlvCmd); | 485 | fRet = processReplyCommand(uuid, rlvCmd); |
485 | break; | 486 | break; |
486 | case RLV_TYPE_UNKNOWN: // Checked: | 487 | case RLV_TYPE_UNKNOWN: // Checked: |
487 | { | ||
488 | if ("clear" == rlvCmd.getBehaviour()) | ||
489 | { | ||
490 | const std::string& strFilter = rlvCmd.getParam(); std::string strCmdRem; | ||
491 | |||
492 | rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid); | ||
493 | if (itObj != m_Objects.end()) // No sense in @clear'ing if we don't have any commands for this object | ||
494 | { | ||
495 | const RlvObject& rlvObj = itObj->second; bool fContinue = true; | ||
496 | for (rlv_command_list_t::const_iterator itCmd = rlvObj.m_Commands.begin(), itCurCmd; | ||
497 | ((fContinue) && (itCmd != rlvObj.m_Commands.end())); ) | ||
498 | { | ||
499 | itCurCmd = itCmd++; // Point itCmd ahead so it won't get invalidated if/when we erase a command | ||
500 | |||
501 | const RlvCommand& rlvCmdRem = *itCurCmd; | ||
502 | if ( (strFilter.empty()) || (-1 != rlvCmdRem.asString().find(strFilter)) ) | ||
503 | { | ||
504 | fContinue = (rlvObj.m_Commands.size() > 1); // rlvObj will become invalid once we remove the last command | ||
505 | strCmdRem = rlvCmdRem.getBehaviour() + ":" + rlvCmdRem.getOption() + "=y"; | ||
506 | processCommand(uuid, strCmdRem, false); | ||
507 | } | ||
508 | } | ||
509 | fRet = TRUE; | ||
510 | } | ||
511 | } | ||
512 | } | ||
513 | break; | 488 | break; |
514 | #ifdef LL_GNUC | 489 | #ifdef LL_GNUC |
515 | default: | 490 | default: |
@@ -671,6 +646,13 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) | |||
671 | LLFloaterChat::getInstance()->childSetVisible("active_speakers_panel", false); | 646 | LLFloaterChat::getInstance()->childSetVisible("active_speakers_panel", false); |
672 | } | 647 | } |
673 | break; | 648 | break; |
649 | case RLV_BHVR_FARTOUCH: | ||
650 | { | ||
651 | #ifdef RLV_EXPERIMENTAL_FIRSTUSE | ||
652 | LLFirstUse::useRlvFartouch(); | ||
653 | #endif // RLV_EXPERIMENTAL_FIRSTUSE | ||
654 | } | ||
655 | break; | ||
674 | case RLV_BHVR_FLY: // @fly=n - Checked: 2009-07-05 (RLVa-1.0.0c) | 656 | case RLV_BHVR_FLY: // @fly=n - Checked: 2009-07-05 (RLVa-1.0.0c) |
675 | { | 657 | { |
676 | // If currently flying, simulate clicking the Fly button [see LLToolBar::onClickFly()] | 658 | // If currently flying, simulate clicking the Fly button [see LLToolBar::onClickFly()] |
@@ -780,22 +762,15 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC | |||
780 | { | 762 | { |
781 | case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | 763 | case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d |
782 | { | 764 | { |
783 | S32 idxAttachPt; | 765 | S32 idxAttachPt = 0; |
784 | if (strOption.empty()) // @detach=y | 766 | if (strOption.empty()) // @detach=y |
785 | { | 767 | { |
786 | // The object may or may not (if it got detached) still exist so clean up the hard way | 768 | // The object may or may not (if it got detached) still exist |
787 | if (m_Objects.find(uuid) != m_Objects.end()) | 769 | rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid); |
788 | { | 770 | if (itObj != m_Objects.end()) |
789 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.begin(), endAttach = m_Attachments.end(); | 771 | idxAttachPt = itObj->second.m_idxAttachPt; |
790 | itAttach != endAttach; ++itAttach) | 772 | if (idxAttachPt) |
791 | { | 773 | setDetachable(idxAttachPt, uuid, true); |
792 | if (itAttach->second == uuid) | ||
793 | { | ||
794 | setDetachable(itAttach->first, uuid, true); // <- invalidates our iterators on return | ||
795 | break; | ||
796 | } | ||
797 | } | ||
798 | } | ||
799 | } | 774 | } |
800 | else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y | 775 | else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y |
801 | { | 776 | { |
@@ -915,6 +890,35 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC | |||
915 | return TRUE; // Remove commands don't fail, doesn't matter what we return here | 890 | return TRUE; // Remove commands don't fail, doesn't matter what we return here |
916 | } | 891 | } |
917 | 892 | ||
893 | BOOL RlvHandler::processClearCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) | ||
894 | { | ||
895 | const std::string& strFilter = rlvCmd.getParam(); std::string strCmdRem; | ||
896 | |||
897 | rlv_object_map_t::const_iterator itObj = m_Objects.find(idObj); | ||
898 | if (itObj != m_Objects.end()) // No sense in clearing if we don't have any commands for this object | ||
899 | { | ||
900 | const RlvObject& rlvObj = itObj->second; bool fContinue = true; | ||
901 | for (rlv_command_list_t::const_iterator itCmd = rlvObj.m_Commands.begin(), itCurCmd; | ||
902 | ((fContinue) && (itCmd != rlvObj.m_Commands.end())); ) | ||
903 | { | ||
904 | itCurCmd = itCmd++; // Point itCmd ahead so it won't get invalidated if/when we erase a command | ||
905 | |||
906 | const RlvCommand& rlvCmdRem = *itCurCmd; strCmdRem = rlvCmdRem.asString(); | ||
907 | if ( (strFilter.empty()) || (std::string::npos != strCmdRem.find(strFilter)) ) | ||
908 | { | ||
909 | fContinue = (rlvObj.m_Commands.size() > 1); // rlvObj will become invalid once we remove the last command | ||
910 | processCommand(idObj, strCmdRem.append("=y"), false); | ||
911 | } | ||
912 | } | ||
913 | } | ||
914 | |||
915 | // Let our observers know about clear commands | ||
916 | RlvEvent rlvEvent(idObj, rlvCmd); | ||
917 | m_Emitter.update(&RlvObserver::onClearCommand, rlvEvent); | ||
918 | |||
919 | return TRUE; // Don't fail clear commands even if the object didn't exist since it confuses people | ||
920 | } | ||
921 | |||
918 | BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const | 922 | BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) const |
919 | { | 923 | { |
920 | const std::string& strOption = rlvCmd.getOption(); | 924 | const std::string& strOption = rlvCmd.getOption(); |
@@ -946,10 +950,8 @@ BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvC | |||
946 | { | 950 | { |
947 | LLVector3d posGlobal; | 951 | LLVector3d posGlobal; |
948 | 952 | ||
949 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | 953 | boost_tokenizer tokens(strOption, boost::char_separator<char>("/", "", boost::keep_empty_tokens)); int idx = 0; |
950 | boost::char_separator<char> sep("/", "", boost::keep_empty_tokens); | 954 | for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) |
951 | tokenizer tokens(strOption, sep); int idx = 0; | ||
952 | for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) | ||
953 | { | 955 | { |
954 | if (idx < 3) | 956 | if (idx < 3) |
955 | LLStringUtil::convertToF64(*itToken, posGlobal[idx++]); | 957 | LLStringUtil::convertToF64(*itToken, posGlobal[idx++]); |
@@ -1165,7 +1167,7 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm | |||
1165 | case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked: | 1167 | case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked: |
1166 | onGetInvWorn(rlvCmd.getOption(), strReply); | 1168 | onGetInvWorn(rlvCmd.getOption(), strReply); |
1167 | break; | 1169 | break; |
1168 | case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | 1170 | case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-08-26 (RLVa-1.0.2a) | Modified: RLVa-1.0.2a |
1169 | { | 1171 | { |
1170 | // COMPAT-RLV: RLV 1.16.1 returns the first random folder it finds (probably tries to match "" to a folder name?) | 1172 | // COMPAT-RLV: RLV 1.16.1 returns the first random folder it finds (probably tries to match "" to a folder name?) |
1171 | // (just going to stick with what's there for now... no option => no folder) | 1173 | // (just going to stick with what's there for now... no option => no folder) |
@@ -1173,7 +1175,8 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm | |||
1173 | if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) ) | 1175 | if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) ) |
1174 | { | 1176 | { |
1175 | // We need to return an "in depth" result so whoever has the most '/' is our lucky winner | 1177 | // We need to return an "in depth" result so whoever has the most '/' is our lucky winner |
1176 | int maxSlashes = 0, curSlashes; std::string strFolderName; | 1178 | // (maxSlashes needs to be initialized to -1 since children of the #RLV folder won't have '/' in their shared path) |
1179 | int maxSlashes = -1, curSlashes; std::string strFolderName; | ||
1177 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) | 1180 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) |
1178 | { | 1181 | { |
1179 | strFolderName = getSharedPath(folders.get(idxFolder)); | 1182 | strFolderName = getSharedPath(folders.get(idxFolder)); |
@@ -1307,6 +1310,9 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1307 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); | 1310 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); |
1308 | if (itObj != m_Objects.end()) | 1311 | if (itObj != m_Objects.end()) |
1309 | { | 1312 | { |
1313 | // Save the attachment point index | ||
1314 | itObj->second.m_idxAttachPt = idxAttachPt; | ||
1315 | |||
1310 | // If it's an attachment we processed commands for but that only just rezzed in we need to mark it as existing in gObjectList | 1316 | // If it's an attachment we processed commands for but that only just rezzed in we need to mark it as existing in gObjectList |
1311 | if (!itObj->second.m_fLookup) | 1317 | if (!itObj->second.m_fLookup) |
1312 | itObj->second.m_fLookup = true; | 1318 | itObj->second.m_fLookup = true; |
@@ -1315,7 +1321,7 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1315 | if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) | 1321 | if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) |
1316 | { | 1322 | { |
1317 | // (Copy/paste from processAddCommand) | 1323 | // (Copy/paste from processAddCommand) |
1318 | setDetachable(pObj, pObj->getID(), false); | 1324 | setDetachable(idxAttachPt, pObj->getID(), false); |
1319 | 1325 | ||
1320 | if (pObj->isHUDAttachment()) | 1326 | if (pObj->isHUDAttachment()) |
1321 | LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments | 1327 | LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments |
@@ -1365,29 +1371,15 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1365 | (!getAttachPoint(pFolder, true)) ) | 1371 | (!getAttachPoint(pFolder, true)) ) |
1366 | { | 1372 | { |
1367 | // It's no mod and its parent folder doesn't contain an attach point | 1373 | // It's no mod and its parent folder doesn't contain an attach point |
1368 | LLInventoryModel::cat_array_t* pFolders; | 1374 | if ( (1 == rlvGetDirectDescendentsCount(pFolder, LLAssetType::AT_OBJECT)) && (NEW_CATEGORY_NAME == pFolder->getName()) ) |
1369 | LLInventoryModel::item_array_t* pItems; | ||
1370 | gInventory.getDirectDescendentsOf(pFolder->getUUID(), pFolders, pItems); | ||
1371 | |||
1372 | if (pItems) | ||
1373 | { | 1375 | { |
1374 | int cntObjects = 0; | ||
1375 | for (S32 idxItem = 0, cntItem = pItems->size(); idxItem < cntItem; idxItem++) | ||
1376 | { | ||
1377 | if (LLAssetType::AT_OBJECT == pItems->get(idxItem)->getType()) | ||
1378 | cntObjects++; | ||
1379 | } | ||
1380 | |||
1381 | // Only rename if there's exactly 1 object/attachment inside of it [see LLFolderBridge::renameItem()] | 1376 | // Only rename if there's exactly 1 object/attachment inside of it [see LLFolderBridge::renameItem()] |
1382 | if ( (1 == cntObjects) && (NEW_CATEGORY_NAME == pFolder->getName()) ) | 1377 | std::string strName = ".(" + strAttachPt + ")"; |
1383 | { | ||
1384 | std::string strName = ".(" + strAttachPt + ")"; | ||
1385 | 1378 | ||
1386 | pFolder->rename(strName); | 1379 | pFolder->rename(strName); |
1387 | pFolder->updateServer(FALSE); | 1380 | pFolder->updateServer(FALSE); |
1388 | gInventory.updateCategory(pFolder); | 1381 | gInventory.updateCategory(pFolder); |
1389 | //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() | 1382 | //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() |
1390 | } | ||
1391 | } | 1383 | } |
1392 | } | 1384 | } |
1393 | } | 1385 | } |
@@ -1864,10 +1856,8 @@ LLViewerInventoryCategory* RlvHandler::getSharedFolder(const std::string& strPat | |||
1864 | return NULL; | 1856 | return NULL; |
1865 | 1857 | ||
1866 | // Walk the path (starting at the root) | 1858 | // Walk the path (starting at the root) |
1867 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | 1859 | boost_tokenizer tokens(strPath, boost::char_separator<char>("/", "", boost::drop_empty_tokens)); |
1868 | boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); | 1860 | for (boost_tokenizer::const_iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) |
1869 | tokenizer tokens(strPath, sep); | ||
1870 | for (tokenizer::iterator itToken = tokens.begin(); itToken != tokens.end(); ++itToken) | ||
1871 | { | 1861 | { |
1872 | pFolder = getSharedFolder(pFolder->getUUID(), *itToken); | 1862 | pFolder = getSharedFolder(pFolder->getUUID(), *itToken); |
1873 | if (!pFolder) | 1863 | if (!pFolder) |
@@ -2102,15 +2092,10 @@ void RlvHandler::onForceRemOutfit(const LLUUID& idObj, const std::string& strOpt | |||
2102 | for (int idxType = 0; idxType < WT_COUNT; idxType++) | 2092 | for (int idxType = 0; idxType < WT_COUNT; idxType++) |
2103 | { | 2093 | { |
2104 | type = (EWearableType)idxType; | 2094 | type = (EWearableType)idxType; |
2095 | if (LLAssetType::AT_CLOTHING != LLWearable::typeToAssetType(type)) | ||
2096 | continue; // Only strip clothing, not bodyparts | ||
2105 | 2097 | ||
2106 | // Only strip clothing (that's currently worn and not marked "nostrip") | 2098 | if ( ((typeOption == type) || (strOption.empty())) && (gAgent.getWearable(type)) && (isStrippable(gAgent.getWearableItem(type))) ) |
2107 | if ( (LLAssetType::AT_CLOTHING != LLWearable::typeToAssetType(type)) || | ||
2108 | (!gAgent.getWearable(type)) || (!isStrippable(gAgent.getWearableItem(type))) ) | ||
2109 | { | ||
2110 | continue; | ||
2111 | } | ||
2112 | |||
2113 | if ( (typeOption == type) || (strOption.empty()) ) | ||
2114 | { | 2099 | { |
2115 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | 2100 | #ifdef RLV_EXPERIMENTAL_COMPOSITES |
2116 | // If we're stripping something that's part of a composite folder then we should @detachthis instead | 2101 | // If we're stripping something that's part of a composite folder then we should @detachthis instead |
@@ -2238,7 +2223,7 @@ void RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMat | |||
2238 | // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog) | 2223 | // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog) |
2239 | // LLAttachObject::handleEvent() => rez_attachment() | 2224 | // LLAttachObject::handleEvent() => rez_attachment() |
2240 | LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); | 2225 | LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); |
2241 | if ( (pAttachPt) && (isDetachable(pAttachPt->getObject())) ) | 2226 | if ( (pAttachPt) && (isDetachable(pAttachPt)) ) |
2242 | { | 2227 | { |
2243 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | 2228 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 |
2244 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; | 2229 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; |
@@ -2498,7 +2483,7 @@ BOOL RlvHandler::setEnabled(BOOL fEnable) | |||
2498 | 2483 | ||
2499 | BOOL RlvHandler::canDisable() | 2484 | BOOL RlvHandler::canDisable() |
2500 | { | 2485 | { |
2501 | return TRUE; | 2486 | return FALSE; |
2502 | } | 2487 | } |
2503 | 2488 | ||
2504 | void RlvHandler::clearState() | 2489 | void RlvHandler::clearState() |