diff options
author | McCabe Maxsted | 2009-10-06 22:12:05 -0700 |
---|---|---|
committer | McCabe Maxsted | 2009-10-06 22:12:05 -0700 |
commit | 23d5c59f6833156ee0714ecfba8194dd8708c730 (patch) | |
tree | 4ab05bf6af6da511c6d5072d42c2cb70570c5a11 /linden/indra/newview/rlvhandler.cpp | |
parent | Tiny improvement to radar code (diff) | |
download | meta-impy-23d5c59f6833156ee0714ecfba8194dd8708c730.zip meta-impy-23d5c59f6833156ee0714ecfba8194dd8708c730.tar.gz meta-impy-23d5c59f6833156ee0714ecfba8194dd8708c730.tar.bz2 meta-impy-23d5c59f6833156ee0714ecfba8194dd8708c730.tar.xz |
Applied RLVa-1.0.2c_20091005_Imprudence-1.2.0-diff.patch
Diffstat (limited to 'linden/indra/newview/rlvhandler.cpp')
-rw-r--r-- | linden/indra/newview/rlvhandler.cpp | 104 |
1 files changed, 35 insertions, 69 deletions
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp index 2915002..987c62a 100644 --- a/linden/indra/newview/rlvhandler.cpp +++ b/linden/indra/newview/rlvhandler.cpp | |||
@@ -93,7 +93,7 @@ inline bool rlvIsWearingItem(const LLInventoryItem* pItem) | |||
93 | static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, std::string& strFilter) | 93 | static bool rlvParseNotifyOption(const std::string& strOption, S32& nChannel, std::string& strFilter) |
94 | { | 94 | { |
95 | boost_tokenizer tokens(strOption, boost::char_separator<char>(";", "", boost::keep_empty_tokens)); | 95 | boost_tokenizer tokens(strOption, boost::char_separator<char>(";", "", boost::keep_empty_tokens)); |
96 | boost_tokenizer::iterator itTok = tokens.begin(); | 96 | boost_tokenizer::const_iterator itTok = tokens.begin(); |
97 | 97 | ||
98 | // Extract and sanity check the first token (required) which is the channel | 98 | // Extract and sanity check the first token (required) which is the channel |
99 | if ( (itTok == tokens.end()) || (!LLStringUtil::convertToS32(*itTok, nChannel)) || (!rlvIsValidChannel(nChannel)) ) | 99 | if ( (itTok == tokens.end()) || (!LLStringUtil::convertToS32(*itTok, nChannel)) || (!rlvIsValidChannel(nChannel)) ) |
@@ -274,7 +274,7 @@ bool RlvHandler::isDetachableExcept(S32 idxAttachPt, LLViewerObject *pObj) const | |||
274 | return true; | 274 | return true; |
275 | } | 275 | } |
276 | 276 | ||
277 | // Checked: 2009-05-31 (RLVa-0.2.0e) | Modified: RLVa-0.2.0e | 277 | // Checked: 2009-09-06 (RLVa-1.0.2b) | Modified: RLVa-1.0.2b |
278 | bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable) | 278 | bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable) |
279 | { | 279 | { |
280 | // Sanity check - make sure it's an object we know about | 280 | // Sanity check - make sure it's an object we know about |
@@ -284,20 +284,12 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe | |||
284 | 284 | ||
285 | if (!fDetachable) | 285 | if (!fDetachable) |
286 | { | 286 | { |
287 | // Sanity check - make sure it's not already marked undetachable by this object (NOTE: m_Attachments is a *multimap*, not a map) | 287 | // NOTE: m_Attachments can contain duplicate <idxAttachPt, idRlvObj> pairs (ie @detach:spine=n,detach=n from an attachment on spine) |
288 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | ||
289 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | ||
290 | { | ||
291 | if (itObj->second.m_UUID == itAttach->second) | ||
292 | return false; | ||
293 | } | ||
294 | |||
295 | m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID)); | 288 | m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID)); |
296 | return true; | 289 | return true; |
297 | } | 290 | } |
298 | else | 291 | else |
299 | { | 292 | { |
300 | // NOTE: m_Attachments is a *multimap*, not a map | ||
301 | for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | 293 | for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt), |
302 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | 294 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) |
303 | { | 295 | { |
@@ -325,11 +317,11 @@ bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDe | |||
325 | LLViewerInventoryItem* pItem = gInventory.getItem(idItem); | 317 | LLViewerInventoryItem* pItem = gInventory.getItem(idItem); |
326 | if (pItem) | 318 | if (pItem) |
327 | { | 319 | { |
328 | if (-1 != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) | 320 | if (std::string::npos != pItem->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) |
329 | return false; | 321 | return false; |
330 | 322 | ||
331 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); | 323 | LLViewerInventoryCategory* pFolder = gInventory.getCategory(pItem->getParentUUID()); |
332 | if ( (pFolder) && (-1 != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) | 324 | if ( (pFolder) && (std::string::npos != pFolder->getName().find(RLV_FOLDER_FLAG_NOSTRIP)) ) |
333 | return false; | 325 | return false; |
334 | } | 326 | } |
335 | } | 327 | } |
@@ -499,7 +491,7 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
499 | itCurCmd = itCmd++; // Point itCmd ahead so it won't get invalidated if/when we erase a command | 491 | itCurCmd = itCmd++; // Point itCmd ahead so it won't get invalidated if/when we erase a command |
500 | 492 | ||
501 | const RlvCommand& rlvCmdRem = *itCurCmd; | 493 | const RlvCommand& rlvCmdRem = *itCurCmd; |
502 | if ( (strFilter.empty()) || (-1 != rlvCmdRem.asString().find(strFilter)) ) | 494 | if ( (strFilter.empty()) || (std::string::npos != rlvCmdRem.asString().find(strFilter)) ) |
503 | { | 495 | { |
504 | fContinue = (rlvObj.m_Commands.size() > 1); // rlvObj will become invalid once we remove the last command | 496 | fContinue = (rlvObj.m_Commands.size() > 1); // rlvObj will become invalid once we remove the last command |
505 | strCmdRem = rlvCmdRem.getBehaviour() + ":" + rlvCmdRem.getOption() + "=y"; | 497 | strCmdRem = rlvCmdRem.getBehaviour() + ":" + rlvCmdRem.getOption() + "=y"; |
@@ -780,22 +772,15 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC | |||
780 | { | 772 | { |
781 | case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | 773 | case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d |
782 | { | 774 | { |
783 | S32 idxAttachPt; | 775 | S32 idxAttachPt = 0; |
784 | if (strOption.empty()) // @detach=y | 776 | if (strOption.empty()) // @detach=y |
785 | { | 777 | { |
786 | // The object may or may not (if it got detached) still exist so clean up the hard way | 778 | // The object may or may not (if it got detached) still exist |
787 | if (m_Objects.find(uuid) != m_Objects.end()) | 779 | rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid); |
788 | { | 780 | if (itObj != m_Objects.end()) |
789 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.begin(), endAttach = m_Attachments.end(); | 781 | idxAttachPt = itObj->second.m_idxAttachPt; |
790 | itAttach != endAttach; ++itAttach) | 782 | if (idxAttachPt) |
791 | { | 783 | 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 | } | 784 | } |
800 | else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y | 785 | else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y |
801 | { | 786 | { |
@@ -946,10 +931,8 @@ BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvC | |||
946 | { | 931 | { |
947 | LLVector3d posGlobal; | 932 | LLVector3d posGlobal; |
948 | 933 | ||
949 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | 934 | 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); | 935 | 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 | { | 936 | { |
954 | if (idx < 3) | 937 | if (idx < 3) |
955 | LLStringUtil::convertToF64(*itToken, posGlobal[idx++]); | 938 | LLStringUtil::convertToF64(*itToken, posGlobal[idx++]); |
@@ -1165,7 +1148,7 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm | |||
1165 | case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked: | 1148 | case RLV_BHVR_GETINVWORN: // @getinvworn[:path]=<channel> - Checked: |
1166 | onGetInvWorn(rlvCmd.getOption(), strReply); | 1149 | onGetInvWorn(rlvCmd.getOption(), strReply); |
1167 | break; | 1150 | break; |
1168 | case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | 1151 | case RLV_BHVR_FINDFOLDER: // @findfolder:<criteria>=<channel> - Checked: 2009-08-26 (RLVa-1.0.2a) | Modified: RLVa-1.0.2a |
1169 | { | 1152 | { |
1170 | // COMPAT-RLV: RLV 1.16.1 returns the first random folder it finds (probably tries to match "" to a folder name?) | 1153 | // 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) | 1154 | // (just going to stick with what's there for now... no option => no folder) |
@@ -1173,7 +1156,8 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm | |||
1173 | if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) ) | 1156 | if ( (!strOption.empty()) && (findSharedFolders(strOption, folders)) ) |
1174 | { | 1157 | { |
1175 | // We need to return an "in depth" result so whoever has the most '/' is our lucky winner | 1158 | // 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; | 1159 | // (maxSlashes needs to be initialized to -1 since children of the #RLV folder won't have '/' in their shared path) |
1160 | int maxSlashes = -1, curSlashes; std::string strFolderName; | ||
1177 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) | 1161 | for (S32 idxFolder = 0, cntFolder = folders.count(); idxFolder < cntFolder; idxFolder++) |
1178 | { | 1162 | { |
1179 | strFolderName = getSharedPath(folders.get(idxFolder)); | 1163 | strFolderName = getSharedPath(folders.get(idxFolder)); |
@@ -1307,6 +1291,9 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1307 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); | 1291 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); |
1308 | if (itObj != m_Objects.end()) | 1292 | if (itObj != m_Objects.end()) |
1309 | { | 1293 | { |
1294 | // Save the attachment point index | ||
1295 | itObj->second.m_idxAttachPt = idxAttachPt; | ||
1296 | |||
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 | 1297 | // 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) | 1298 | if (!itObj->second.m_fLookup) |
1312 | itObj->second.m_fLookup = true; | 1299 | itObj->second.m_fLookup = true; |
@@ -1315,7 +1302,7 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1315 | if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) | 1302 | if (itObj->second.hasBehaviour(RLV_BHVR_DETACH)) |
1316 | { | 1303 | { |
1317 | // (Copy/paste from processAddCommand) | 1304 | // (Copy/paste from processAddCommand) |
1318 | setDetachable(pObj, pObj->getID(), false); | 1305 | setDetachable(idxAttachPt, pObj->getID(), false); |
1319 | 1306 | ||
1320 | if (pObj->isHUDAttachment()) | 1307 | if (pObj->isHUDAttachment()) |
1321 | LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments | 1308 | LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments |
@@ -1365,29 +1352,15 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1365 | (!getAttachPoint(pFolder, true)) ) | 1352 | (!getAttachPoint(pFolder, true)) ) |
1366 | { | 1353 | { |
1367 | // It's no mod and its parent folder doesn't contain an attach point | 1354 | // It's no mod and its parent folder doesn't contain an attach point |
1368 | LLInventoryModel::cat_array_t* pFolders; | 1355 | 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 | { | 1356 | { |
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()] | 1357 | // Only rename if there's exactly 1 object/attachment inside of it [see LLFolderBridge::renameItem()] |
1382 | if ( (1 == cntObjects) && (NEW_CATEGORY_NAME == pFolder->getName()) ) | 1358 | std::string strName = ".(" + strAttachPt + ")"; |
1383 | { | ||
1384 | std::string strName = ".(" + strAttachPt + ")"; | ||
1385 | 1359 | ||
1386 | pFolder->rename(strName); | 1360 | pFolder->rename(strName); |
1387 | pFolder->updateServer(FALSE); | 1361 | pFolder->updateServer(FALSE); |
1388 | gInventory.updateCategory(pFolder); | 1362 | gInventory.updateCategory(pFolder); |
1389 | //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() | 1363 | //gInventory.notifyObservers(); <- done further down in LLVOAvatar::attachObject() |
1390 | } | ||
1391 | } | 1364 | } |
1392 | } | 1365 | } |
1393 | } | 1366 | } |
@@ -1864,10 +1837,8 @@ LLViewerInventoryCategory* RlvHandler::getSharedFolder(const std::string& strPat | |||
1864 | return NULL; | 1837 | return NULL; |
1865 | 1838 | ||
1866 | // Walk the path (starting at the root) | 1839 | // Walk the path (starting at the root) |
1867 | typedef boost::tokenizer<boost::char_separator<char> > tokenizer; | 1840 | boost_tokenizer tokens(strPath, boost::char_separator<char>("/", "", boost::drop_empty_tokens)); |
1868 | boost::char_separator<char> sep("/", "", boost::drop_empty_tokens); | 1841 | 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 | { | 1842 | { |
1872 | pFolder = getSharedFolder(pFolder->getUUID(), *itToken); | 1843 | pFolder = getSharedFolder(pFolder->getUUID(), *itToken); |
1873 | if (!pFolder) | 1844 | if (!pFolder) |
@@ -2102,15 +2073,10 @@ void RlvHandler::onForceRemOutfit(const LLUUID& idObj, const std::string& strOpt | |||
2102 | for (int idxType = 0; idxType < WT_COUNT; idxType++) | 2073 | for (int idxType = 0; idxType < WT_COUNT; idxType++) |
2103 | { | 2074 | { |
2104 | type = (EWearableType)idxType; | 2075 | type = (EWearableType)idxType; |
2076 | if (LLAssetType::AT_CLOTHING != LLWearable::typeToAssetType(type)) | ||
2077 | continue; // Only strip clothing, not bodyparts | ||
2105 | 2078 | ||
2106 | // Only strip clothing (that's currently worn and not marked "nostrip") | 2079 | 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 | { | 2080 | { |
2115 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | 2081 | #ifdef RLV_EXPERIMENTAL_COMPOSITES |
2116 | // If we're stripping something that's part of a composite folder then we should @detachthis instead | 2082 | // If we're stripping something that's part of a composite folder then we should @detachthis instead |
@@ -2238,7 +2204,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) | 2204 | // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog) |
2239 | // LLAttachObject::handleEvent() => rez_attachment() | 2205 | // LLAttachObject::handleEvent() => rez_attachment() |
2240 | LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); | 2206 | LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); |
2241 | if ( (pAttachPt) && (isDetachable(pAttachPt->getObject())) ) | 2207 | if ( (pAttachPt) && (isDetachable(pAttachPt)) ) |
2242 | { | 2208 | { |
2243 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | 2209 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 |
2244 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; | 2210 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; |
@@ -2498,7 +2464,7 @@ BOOL RlvHandler::setEnabled(BOOL fEnable) | |||
2498 | 2464 | ||
2499 | BOOL RlvHandler::canDisable() | 2465 | BOOL RlvHandler::canDisable() |
2500 | { | 2466 | { |
2501 | return TRUE; | 2467 | return FALSE; |
2502 | } | 2468 | } |
2503 | 2469 | ||
2504 | void RlvHandler::clearState() | 2470 | void RlvHandler::clearState() |