diff options
Diffstat (limited to 'linden/indra/newview/rlvhelper.cpp')
-rw-r--r-- | linden/indra/newview/rlvhelper.cpp | 649 |
1 files changed, 526 insertions, 123 deletions
diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp index f509a43..9ef74ac 100644 --- a/linden/indra/newview/rlvhelper.cpp +++ b/linden/indra/newview/rlvhelper.cpp | |||
@@ -1,27 +1,31 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | 1 | #include "llviewerprecompiledheaders.h" |
2 | #include "llagent.h" | ||
3 | #include "llfloaterwindlight.h" | 2 | #include "llfloaterwindlight.h" |
3 | #include "llgesturemgr.h" | ||
4 | #include "llinventoryview.h" | ||
5 | #include "llinventorybridge.h" | ||
4 | #include "llviewerobject.h" | 6 | #include "llviewerobject.h" |
7 | #include "llviewerobjectlist.h" | ||
8 | #include "llviewerregion.h" | ||
5 | #include "llviewerstats.h" | 9 | #include "llviewerstats.h" |
6 | #include "llviewerwindow.h" | 10 | #include "llviewerwindow.h" |
7 | #include "llvoavatar.h" | 11 | #include "llvoavatar.h" |
12 | #include "llwearablelist.h" | ||
8 | #include "llwlparammanager.h" | 13 | #include "llwlparammanager.h" |
9 | 14 | ||
10 | #include "rlvhelper.h" | 15 | #include "rlvhelper.h" |
11 | #include "rlvevent.h" | ||
12 | #include "rlvhandler.h" | 16 | #include "rlvhandler.h" |
13 | 17 | ||
14 | // ============================================================================ | 18 | // Defined in llinventorybridge.cpp |
15 | // Static variable initialization | 19 | void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOOL remove); |
16 | // | 20 | void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*); |
17 | |||
18 | RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap; | ||
19 | 21 | ||
20 | // ============================================================================ | 22 | // ============================================================================ |
21 | // RlvCommmand | 23 | // RlvCommmand |
22 | // | 24 | // |
23 | 25 | ||
24 | // Checked: 2009-09-10 (RLVa-1.0.3a) | Modified: RLVa-1.0.3a | 26 | RlvCommand::RlvBhvrTable RlvCommand::m_BhvrMap; |
27 | |||
28 | // Checked: 2009-12-27 (RLVa-1.1.0k) | Modified: RLVa-1.1.0k | ||
25 | RlvCommand::RlvCommand(const std::string& strCommand) | 29 | RlvCommand::RlvCommand(const std::string& strCommand) |
26 | : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN) | 30 | : m_eBehaviour(RLV_BHVR_UNKNOWN), m_fStrict(false), m_eParamType(RLV_TYPE_UNKNOWN) |
27 | { | 31 | { |
@@ -32,12 +36,12 @@ RlvCommand::RlvCommand(const std::string& strCommand) | |||
32 | m_eParamType = RLV_TYPE_ADD; | 36 | m_eParamType = RLV_TYPE_ADD; |
33 | else if ( ("y" == m_strParam) || ("rem" == m_strParam) ) | 37 | else if ( ("y" == m_strParam) || ("rem" == m_strParam) ) |
34 | m_eParamType = RLV_TYPE_REMOVE; | 38 | m_eParamType = RLV_TYPE_REMOVE; |
39 | else if (m_strBehaviour == "clear") // clear is the odd one out so just make it its own type | ||
40 | m_eParamType = RLV_TYPE_CLEAR; | ||
35 | else if ("force" == m_strParam) | 41 | else if ("force" == m_strParam) |
36 | m_eParamType = RLV_TYPE_FORCE; | 42 | m_eParamType = RLV_TYPE_FORCE; |
37 | else if (LLStringUtil::convertToS32(m_strParam, nTemp)) // Assume it's a reply command if we can convert <param> to an S32 | 43 | else if (LLStringUtil::convertToS32(m_strParam, nTemp)) // Assume it's a reply command if we can convert <param> to an S32 |
38 | m_eParamType = RLV_TYPE_REPLY; | 44 | m_eParamType = RLV_TYPE_REPLY; |
39 | else if (m_strBehaviour == "clear") // clear is the odd one out so just make it its own type | ||
40 | m_eParamType = RLV_TYPE_CLEAR; | ||
41 | else | 45 | else |
42 | { | 46 | { |
43 | m_eParamType = RLV_TYPE_UNKNOWN; | 47 | m_eParamType = RLV_TYPE_UNKNOWN; |
@@ -51,13 +55,7 @@ RlvCommand::RlvCommand(const std::string& strCommand) | |||
51 | return; | 55 | return; |
52 | } | 56 | } |
53 | 57 | ||
54 | // Check if this is the "strict" (aka "secure") variation of a behaviour | 58 | m_eBehaviour = getBehaviourFromString(m_strBehaviour, &m_fStrict); |
55 | std::string::size_type idxStrict = m_strBehaviour.find("_sec"); | ||
56 | m_fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == m_strBehaviour.length()); | ||
57 | |||
58 | RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find( (!m_fStrict) ? m_strBehaviour : m_strBehaviour.substr(0, idxStrict)); | ||
59 | if ( (itBhvr != m_BhvrMap.end()) && ((!m_fStrict) || (hasStrictVariant(itBhvr->second))) ) | ||
60 | m_eBehaviour = itBhvr->second; | ||
61 | } | 59 | } |
62 | 60 | ||
63 | 61 | ||
@@ -95,6 +93,20 @@ bool RlvCommand::parseCommand(const std::string& strCommand, std::string& strBeh | |||
95 | return true; | 93 | return true; |
96 | } | 94 | } |
97 | 95 | ||
96 | // Checked: 2009-12-05 (RLVa-1.1.0h) | Added: RLVa-1.1.0h | ||
97 | ERlvBehaviour RlvCommand::getBehaviourFromString(const std::string& strBhvr, bool* pfStrict /*=NULL*/) | ||
98 | { | ||
99 | std::string::size_type idxStrict = strBhvr.find("_sec"); | ||
100 | bool fStrict = (std::string::npos != idxStrict) && (idxStrict + 4 == strBhvr.length()); | ||
101 | if (pfStrict) | ||
102 | *pfStrict = fStrict; | ||
103 | |||
104 | RlvBhvrTable::const_iterator itBhvr = m_BhvrMap.find( (!fStrict) ? strBhvr : strBhvr.substr(0, idxStrict)); | ||
105 | if ( (itBhvr != m_BhvrMap.end()) && ((!fStrict) || (hasStrictVariant(itBhvr->second))) ) | ||
106 | return itBhvr->second; | ||
107 | return RLV_BHVR_UNKNOWN; | ||
108 | } | ||
109 | |||
98 | void RlvCommand::initLookupTable() | 110 | void RlvCommand::initLookupTable() |
99 | { | 111 | { |
100 | static bool fInitialized = false; | 112 | static bool fInitialized = false; |
@@ -103,14 +115,16 @@ void RlvCommand::initLookupTable() | |||
103 | // NOTE: keep this matched with the enumeration at all times | 115 | // NOTE: keep this matched with the enumeration at all times |
104 | std::string arBehaviours[RLV_BHVR_COUNT] = | 116 | std::string arBehaviours[RLV_BHVR_COUNT] = |
105 | { | 117 | { |
106 | "version", "detach", "sendchat", "emote", "chatshout", "chatnormal", "chatwhisper", "redirchat", "rediremote", | 118 | "detach", "attach", "addattach", "remattach", "addoutfit", "remoutfit", "emote", "sendchat", "recvchat", "recvemote", |
107 | "sendim", "recvchat", "recvemote", "recvim", "tplm", "tploc", "tplure", "sittp", "edit", "rez", | 119 | "redirchat", "rediremote", "chatwhisper", "chatnormal", "chatshout", "sendchannel", "sendim", "recvim", "permissive", |
108 | "addoutfit", "remoutfit", "getoutfit", "addattach", "remattach", "getattach", "showinv", "viewnote", "unsit", "sit", | 120 | "notify", "showinv", "showminimap", "showworldmap", "showloc", "shownames", "showhovertext", "showhovertexthud", |
109 | "sendchannel", "getstatus", "getstatusall", "getinv", "getinvworn", "findfolder", "findfolders", | 121 | "showhovertextworld", "showhovertextall", "tplm", "tploc", "tplure", "viewnote", "viewscript", "viewtexture", |
110 | "attach", "attachall", "detachall", "getpath", "attachthis", "attachallthis", "detachthis", "detachallthis", | 122 | "acceptpermission", "accepttp", "defaultwear", "allowidle", "edit", "rez", "fartouch", "interact", "touch", |
111 | "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp", "acceptpermission", "shownames", "fly", | 123 | "touchattach", "touchhud", "touchworld", "fly", "unsit", "sit", "sittp", "setdebug", "setenv", "detachme", "detachthis", |
112 | "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", "showhovertextworld", "showhovertexthud", | 124 | "detachall", "detachallthis", "attachthis", "attachall", "attachallthis", "tpto", "version", "versionnew", "versionnum", |
113 | "showhovertext", "notify", "defaultwear", "versionnum", "permissive", "viewscript", "viewtexture" | 125 | "getattach", "getattachnames", "getaddattachnames", "getremattachnames", "getoutfit", "getoutfitnames", |
126 | "getaddoutfitnames", "getremoutfitnames", "findfolder", "findfolders", "getpath", "getinv", "getinvworn", "getsitid", | ||
127 | "getstatus", "getstatusall" | ||
114 | }; | 128 | }; |
115 | 129 | ||
116 | for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) | 130 | for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) |
@@ -133,9 +147,7 @@ RlvObject::RlvObject(const LLUUID& idObj) : m_UUID(idObj), m_nLookupMisses(0) | |||
133 | 147 | ||
134 | bool RlvObject::addCommand(const RlvCommand& rlvCmd) | 148 | bool RlvObject::addCommand(const RlvCommand& rlvCmd) |
135 | { | 149 | { |
136 | // Sanity checking | 150 | RLV_ASSERT(RLV_TYPE_ADD == rlvCmd.getParamType()); |
137 | if (RLV_TYPE_ADD != rlvCmd.getParamType()) | ||
138 | return false; | ||
139 | 151 | ||
140 | // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on) | 152 | // Don't add duplicate commands for this object (ie @detach=n followed by another @detach=n later on) |
141 | for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | 153 | for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) |
@@ -155,9 +167,7 @@ bool RlvObject::addCommand(const RlvCommand& rlvCmd) | |||
155 | 167 | ||
156 | bool RlvObject::removeCommand(const RlvCommand& rlvCmd) | 168 | bool RlvObject::removeCommand(const RlvCommand& rlvCmd) |
157 | { | 169 | { |
158 | // Sanity checking | 170 | RLV_ASSERT(RLV_TYPE_REMOVE == rlvCmd.getParamType()); |
159 | if (RLV_TYPE_REMOVE != rlvCmd.getParamType()) | ||
160 | return false; | ||
161 | 171 | ||
162 | for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) | 172 | for (rlv_command_list_t::iterator itCmd = m_Commands.begin(); itCmd != m_Commands.end(); ++itCmd) |
163 | { | 173 | { |
@@ -188,7 +198,7 @@ bool RlvObject::hasBehaviour(ERlvBehaviour eBehaviour, const std::string& strOpt | |||
188 | return false; | 198 | return false; |
189 | } | 199 | } |
190 | 200 | ||
191 | // Checked: 2009-06-07 (RLVa-0.2.1c) | 201 | // Checked: 2009-11-27 (RLVa-1.1.0f) | Modified: RLVa-1.1.0f |
192 | std::string RlvObject::getStatusString(const std::string& strMatch) const | 202 | std::string RlvObject::getStatusString(const std::string& strMatch) const |
193 | { | 203 | { |
194 | std::string strStatus, strCmd; | 204 | std::string strStatus, strCmd; |
@@ -198,8 +208,7 @@ std::string RlvObject::getStatusString(const std::string& strMatch) const | |||
198 | strCmd = itCmd->asString(); | 208 | strCmd = itCmd->asString(); |
199 | if ( (strMatch.empty()) || (std::string::npos != strCmd.find(strMatch)) ) | 209 | if ( (strMatch.empty()) || (std::string::npos != strCmd.find(strMatch)) ) |
200 | { | 210 | { |
201 | if (!strStatus.empty()) | 211 | strStatus.push_back('/'); |
202 | strStatus.push_back('/'); | ||
203 | strStatus += strCmd; | 212 | strStatus += strCmd; |
204 | } | 213 | } |
205 | } | 214 | } |
@@ -212,7 +221,7 @@ std::string RlvObject::getStatusString(const std::string& strMatch) const | |||
212 | // | 221 | // |
213 | 222 | ||
214 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | 223 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b |
215 | void RlvAttachmentManager::forceAttach(const LLUUID& idItem, S32 idxAttachPt) | 224 | void RlvAttachmentManager::attach(const LLUUID& idItem, S32 idxAttachPt) |
216 | { | 225 | { |
217 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | 226 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 |
218 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction(); | 227 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction(); |
@@ -224,18 +233,15 @@ void RlvAttachmentManager::forceAttach(const LLUUID& idItem, S32 idxAttachPt) | |||
224 | LLSD payload; | 233 | LLSD payload; |
225 | payload["item_id"] = idItem; | 234 | payload["item_id"] = idItem; |
226 | payload["attachment_point"] = idxAttachPt; | 235 | payload["attachment_point"] = idxAttachPt; |
227 | 236 | LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | |
228 | LLNotifications::instance().forceResponse( | ||
229 | LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | ||
230 | #endif | 237 | #endif |
231 | } | 238 | } |
232 | 239 | ||
233 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | 240 | // Checked: 2009-11-24 (RLVa-1.1.0k) | Added: RLVa-1.1.0e |
234 | void RlvAttachmentManager::forceDetach(LLViewerJointAttachment* pAttachPt) | 241 | void RlvAttachmentManager::detach(LLViewerJointAttachment* pAttachPt) |
235 | { | 242 | { |
236 | // Copy/paste from handle_detach_from_avatar() | 243 | // [See handle_detach_from_avatar()] |
237 | LLViewerObject* attached_object = pAttachPt->getObject(); | 244 | if ( (pAttachPt) && (pAttachPt->getObject()) ) |
238 | if (attached_object) | ||
239 | { | 245 | { |
240 | gMessageSystem->newMessage("ObjectDetach"); | 246 | gMessageSystem->newMessage("ObjectDetach"); |
241 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | 247 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); |
@@ -243,7 +249,7 @@ void RlvAttachmentManager::forceDetach(LLViewerJointAttachment* pAttachPt) | |||
243 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | 249 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); |
244 | 250 | ||
245 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); | 251 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); |
246 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); | 252 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachPt->getObject()->getLocalID()); |
247 | gMessageSystem->sendReliable( gAgent.getRegionHost() ); | 253 | gMessageSystem->sendReliable( gAgent.getRegionHost() ); |
248 | } | 254 | } |
249 | } | 255 | } |
@@ -278,7 +284,7 @@ void RlvAttachmentManager::onAttach(LLViewerJointAttachment* pAttachPt) | |||
278 | // If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one | 284 | // If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one |
279 | if (itAttachPrev->second.isNull()) | 285 | if (itAttachPrev->second.isNull()) |
280 | { | 286 | { |
281 | forceDetach(pAttachPt); | 287 | detach(pAttachPt); |
282 | m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID())); | 288 | m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID())); |
283 | } | 289 | } |
284 | else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there) | 290 | else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there) |
@@ -321,7 +327,7 @@ void RlvAttachmentManager::onSavedAssetIntoInventory(const LLUUID& idItem) | |||
321 | { | 327 | { |
322 | if ( (!itAttach->second.fAssetSaved) && (idItem == itAttach->second.idItem) ) | 328 | if ( (!itAttach->second.fAssetSaved) && (idItem == itAttach->second.idItem) ) |
323 | { | 329 | { |
324 | forceAttach(itAttach->second.idItem, itAttach->first); | 330 | attach(itAttach->second.idItem, itAttach->first); |
325 | itAttach->second.tsAttach = LLFrameTimer::getElapsedSeconds(); | 331 | itAttach->second.tsAttach = LLFrameTimer::getElapsedSeconds(); |
326 | } | 332 | } |
327 | } | 333 | } |
@@ -368,7 +374,7 @@ BOOL RlvAttachmentManager::onTimer() | |||
368 | 374 | ||
369 | if (fAttach) | 375 | if (fAttach) |
370 | { | 376 | { |
371 | forceAttach(itAttach->second.idItem, itAttach->first); | 377 | attach(itAttach->second.idItem, itAttach->first); |
372 | itAttach->second.tsAttach = tsCurrent; | 378 | itAttach->second.tsAttach = tsCurrent; |
373 | } | 379 | } |
374 | 380 | ||
@@ -421,7 +427,7 @@ const LLUUID& RlvWearableItemCollector::getFoldedParent(const LLUUID& idFolder) | |||
421 | return (m_Folding.end() == itFolder) ? idFolder : itFolder->second; | 427 | return (m_Folding.end() == itFolder) ? idFolder : itFolder->second; |
422 | } | 428 | } |
423 | 429 | ||
424 | // Checked: 2009-07-29 (RLVa-1.0.1b) | Modified: RLVa-1.0.1b | 430 | // Checked: 2009-12-18 (RLVa-1.1.0k) | Modified: RLVa-1.1.0i |
425 | bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolder) | 431 | bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolder) |
426 | { | 432 | { |
427 | const LLUUID& idParent = pFolder->getParentUUID(); | 433 | const LLUUID& idParent = pFolder->getParentUUID(); |
@@ -437,25 +443,35 @@ bool RlvWearableItemCollector::onCollectFolder(const LLInventoryCategory* pFolde | |||
437 | return false; | 443 | return false; |
438 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | 444 | #endif // RLV_EXTENSION_FLAG_NOSTRIP |
439 | 445 | ||
440 | if (gRlvHandler.isFoldedFolder(pFolder, m_fAttach)) // Check for folder that should get folded under its parent | 446 | if (gRlvHandler.isFoldedFolder(pFolder, m_fAttach, false)) // Check for folder that should get folded under its parent |
441 | { | 447 | { |
442 | m_Tentative.push_front(pFolder->getUUID()); | 448 | m_Tentative.push_front(pFolder->getUUID()); |
443 | m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); | 449 | m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); |
444 | } | 450 | } |
445 | else if ( (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && (m_fMatchAll) ) // Collect from any non-hidden child folder for *all | 451 | else if ( (RLV_FOLDER_PREFIX_HIDDEN != strFolder[0]) && (m_fMatchAll) ) // Collect from any non-hidden child folder for *all |
446 | { | 452 | { |
447 | m_Wearable.push_front(pFolder->getUUID()); | 453 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS |
454 | if ( (!RlvSettings::getEnableComposites()) || // ... if we're not checking composite folders | ||
455 | (!gRlvHandler.isCompositeFolder(pFolder)) || // ... or if it's not a composite folder | ||
456 | ((m_fAttach) && (gRlvHandler.canWearComposite(pFolder))) || // ... or if we're attaching and can attach it OR | ||
457 | (!m_fAttach) && (gRlvHandler.canTakeOffComposite(pFolder)) ) // ... or if we're detaching and can detach it | ||
458 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
459 | { | ||
460 | m_Wearable.push_front(pFolder->getUUID()); | ||
461 | } | ||
448 | return (idParent == m_idFolder); // (Convenience for @getinvworn) | 462 | return (idParent == m_idFolder); // (Convenience for @getinvworn) |
449 | } | 463 | } |
450 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | 464 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS |
451 | else if ( (RLV_FOLDER_PREFIX_HIDDEN == strFolder[0]) && // Hidden folder that's a... | 465 | else if ( (RlvSettings::getEnableComposites()) && |
466 | (RLV_FOLDER_PREFIX_HIDDEN == strFolder[0]) && // Hidden folder that's a... | ||
452 | (gRlvHandler.isCompositeFolder(pFolder)) && // ... composite folder which we... | 467 | (gRlvHandler.isCompositeFolder(pFolder)) && // ... composite folder which we... |
453 | ((m_fAttach) || (gRlvHandler.canTakeOffComposite(pFolder))) ) // ... attach or can detach (see composite locking) | 468 | ( ((m_fAttach) && (gRlvHandler.canWearComposite(pFolder))) || // ... are attaching and can attach OR |
469 | (!m_fAttach) && (gRlvHandler.canTakeOffComposite(pFolder)) ) ) // ... are detaching and can detach | ||
454 | { | 470 | { |
455 | m_Wearable.push_front(pFolder->getUUID()); | 471 | m_Wearable.push_front(pFolder->getUUID()); |
456 | m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); | 472 | m_Folding.insert(std::pair<LLUUID, LLUUID>(pFolder->getUUID(), idParent)); |
457 | } | 473 | } |
458 | #endif // RLV_EXPERIMENTAL_COMPOSITES | 474 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS |
459 | 475 | ||
460 | return false; | 476 | return false; |
461 | } | 477 | } |
@@ -486,13 +502,13 @@ bool RlvWearableItemCollector::onCollectItem(const LLInventoryItem* pItem) | |||
486 | case LLAssetType::AT_OBJECT: | 502 | case LLAssetType::AT_OBJECT: |
487 | fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) || | 503 | fRet = ( (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)) || |
488 | (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) ) && | 504 | (m_Tentative.end() != std::find(m_Tentative.begin(), m_Tentative.end(), idParent)) ) && |
489 | ( (!m_fAttach) || (gRlvHandler.hasAttachPointName(pItem, true)) ); // Only care about attach point on attach* | 505 | ( (!m_fAttach) || (gRlvHandler.hasAttachPointName(pItem, true)) || (RlvSettings::getEnableSharedWear()) ); |
490 | break; | 506 | break; |
491 | #ifdef RLV_EXPERIMENTAL_FORCEWEAR_GESTURES | 507 | #ifdef RLV_EXTENSION_FORCEWEAR_GESTURES |
492 | case LLAssetType::AT_GESTURE: | 508 | case LLAssetType::AT_GESTURE: |
493 | fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)); | 509 | fRet = (m_Wearable.end() != std::find(m_Wearable.begin(), m_Wearable.end(), idParent)); |
494 | break; | 510 | break; |
495 | #endif // RLV_EXPERIMENTAL_FORCEWEAR_GESTURES | 511 | #endif // RLV_EXTENSION_FORCEWEAR_GESTURES |
496 | default: | 512 | default: |
497 | break; | 513 | break; |
498 | } | 514 | } |
@@ -507,6 +523,431 @@ bool RlvWearableItemCollector::operator()(LLInventoryCategory* pFolder, LLInvent | |||
507 | } | 523 | } |
508 | 524 | ||
509 | // ============================================================================ | 525 | // ============================================================================ |
526 | // RlvForceWear | ||
527 | // | ||
528 | |||
529 | // Checked: 2010-02-17 (RLVa-1.1.0o) | Modified: RLVa-1.1.0o | ||
530 | void RlvForceWear::forceFolder(const LLViewerInventoryCategory* pFolder, eWearAction eAction, eWearFlags eFlags) | ||
531 | { | ||
532 | // [See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items] | ||
533 | if (!gAgent.areWearablesLoaded()) | ||
534 | { | ||
535 | LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded"); | ||
536 | return; | ||
537 | } | ||
538 | // Sanity check - getAvatarObject() can't be NULL [see RlvForceWear::isWearingItem()] | ||
539 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
540 | if (!pAvatar) | ||
541 | return; | ||
542 | |||
543 | LLInventoryModel::cat_array_t folders; | ||
544 | LLInventoryModel::item_array_t items; | ||
545 | RlvWearableItemCollector functor(pFolder->getUUID(), (ACTION_ATTACH == eAction), (FLAG_MATCHALL & eFlags)); | ||
546 | |||
547 | // Grab a list of all the items we'll be wearing/attaching | ||
548 | gInventory.collectDescendentsIf(pFolder->getUUID(), folders, items, FALSE, functor); | ||
549 | |||
550 | for (S32 idxItem = 0, cntItem = items.count(); idxItem < cntItem; idxItem++) | ||
551 | { | ||
552 | LLViewerInventoryItem* pItem = items.get(idxItem); | ||
553 | |||
554 | // If it's wearable it should be worn on detach | ||
555 | if ( (ACTION_DETACH == eAction) && (isWearableItem(pItem)) && (!isWearingItem(pItem)) ) | ||
556 | continue; | ||
557 | |||
558 | // NOTES: * if there are composite items then RlvWearableItemCollector made sure they can be worn (or taken off depending) | ||
559 | // * some scripts issue @remattach=force,attach:worn-items=force so we need to attach items even if they're currently worn | ||
560 | switch (pItem->getType()) | ||
561 | { | ||
562 | case LLAssetType::AT_BODYPART: | ||
563 | RLV_ASSERT(ACTION_ATTACH == eAction); // RlvWearableItemCollector shouldn't be supplying us with body parts on detach | ||
564 | case LLAssetType::AT_CLOTHING: | ||
565 | if (ACTION_ATTACH == eAction) | ||
566 | { | ||
567 | // The check for whether we're replacing a currently worn composite item happens in onWearableArrived() | ||
568 | if (std::find(m_addWearables.begin(), m_addWearables.end(), pItem) == m_addWearables.end()) | ||
569 | m_addWearables.push_back(pItem); | ||
570 | } | ||
571 | else | ||
572 | { | ||
573 | LLWearable* pWearable = gAgent.getWearableFromWearableItem(pItem->getUUID()); | ||
574 | if ( (pWearable) && (isForceRemovable(pWearable->getType(), false)) ) | ||
575 | { | ||
576 | if (std::find(m_remWearables.begin(), m_remWearables.end(), pWearable->getType()) == m_remWearables.end()) | ||
577 | m_remWearables.push_back(pWearable->getType()); | ||
578 | } | ||
579 | } | ||
580 | break; | ||
581 | |||
582 | case LLAssetType::AT_OBJECT: | ||
583 | if (ACTION_ATTACH == eAction) | ||
584 | { | ||
585 | LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(pItem, true); | ||
586 | if ( ( (pAttachPt) && // Need a specific attach pt that | ||
587 | (!gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) && // doesn't have a locked object | ||
588 | (!gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) || // and that can be attached to | ||
589 | (RlvSettings::getEnableSharedWear()) ) | ||
590 | { | ||
591 | if (std::find(m_addAttachments.begin(), m_addAttachments.end(), pItem) == m_addAttachments.end()) | ||
592 | { | ||
593 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
594 | // We still need to check whether we're about to replace a currently worn composite item | ||
595 | // (which we're not if we're just reattaching an attachment we're already wearing) | ||
596 | LLViewerInventoryCategory* pCompositeFolder = NULL; | ||
597 | if ( (pAttachPt->getObject()) && (RlvSettings::getEnableComposites()) && | ||
598 | (pAttachPt->getItemID() != pItem->getUUID()) && | ||
599 | (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pCompositeFolder)) ) | ||
600 | { | ||
601 | // If we can't take off the composite folder this item would replace then don't allow it to get attached | ||
602 | if (gRlvHandler.canTakeOffComposite(pCompositeFolder)) | ||
603 | { | ||
604 | forceFolder(pCompositeFolder, ACTION_DETACH, FLAG_DEFAULT); | ||
605 | m_addAttachments.push_back(pItem); | ||
606 | } | ||
607 | } | ||
608 | else | ||
609 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
610 | { | ||
611 | m_addAttachments.push_back(pItem); | ||
612 | } | ||
613 | } | ||
614 | } | ||
615 | } | ||
616 | else | ||
617 | { | ||
618 | LLViewerJointAttachment* pAttachPt = pAvatar->getWornAttachmentPoint(pItem->getUUID()); | ||
619 | if ( (pAttachPt) && (isForceDetachable(pAttachPt, false)) ) | ||
620 | { | ||
621 | if (std::find(m_remAttachments.begin(), m_remAttachments.end(), pAttachPt) == m_remAttachments.end()) | ||
622 | m_remAttachments.push_back(pAttachPt); | ||
623 | } | ||
624 | } | ||
625 | break; | ||
626 | |||
627 | #ifdef RLV_EXTENSION_FORCEWEAR_GESTURES | ||
628 | case LLAssetType::AT_GESTURE: | ||
629 | if (ACTION_ATTACH == eAction) | ||
630 | { | ||
631 | if (std::find(m_addGestures.begin(), m_addGestures.end(), pItem) == m_addGestures.end()) | ||
632 | m_addGestures.push_back(pItem); | ||
633 | } | ||
634 | else | ||
635 | { | ||
636 | if (std::find(m_remGestures.begin(), m_remGestures.end(), pItem) == m_remGestures.end()) | ||
637 | m_remGestures.push_back(pItem); | ||
638 | } | ||
639 | break; | ||
640 | #endif // RLV_EXTENSION_FORCEWEAR_GESTURES | ||
641 | |||
642 | default: | ||
643 | break; | ||
644 | } | ||
645 | } | ||
646 | } | ||
647 | |||
648 | // Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i | ||
649 | bool RlvForceWear::isForceDetachable(LLViewerJointAttachment* pAttachPt, bool fCheckComposite /*=true*/, LLViewerObject* pExceptObj /*=NULL*/) | ||
650 | { | ||
651 | // Attachment point can be detached by an RLV command if: | ||
652 | // - something is worn on the attachment point | ||
653 | // - what's worn isn't "remove locked" by anything (or anything except the object specified by pExceptObj) | ||
654 | // - what's worn is strippable | ||
655 | // - composite folders are disabled *or* what's worn isn't part of a composite folder that has at least one item locked | ||
656 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
657 | LLViewerInventoryCategory* pFolder = NULL; | ||
658 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
659 | return | ||
660 | ( | ||
661 | (pAttachPt) && (pAttachPt->getObject()) && | ||
662 | ( (!pExceptObj) ? (!gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) | ||
663 | : (!gRlvHandler.isLockedAttachmentExcept(pAttachPt->getObject(), RLV_LOCK_REMOVE, pExceptObj)) ) | ||
664 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
665 | && (gRlvHandler.isStrippable(pAttachPt->getItemID())) | ||
666 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
667 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
668 | && ( (!fCheckComposite) || (!RlvSettings::getEnableComposites()) || | ||
669 | (!gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) ) | ||
670 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
671 | ); | ||
672 | } | ||
673 | |||
674 | // Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i | ||
675 | void RlvForceWear::forceDetach(LLViewerJointAttachment* pAttachPt) | ||
676 | { | ||
677 | // Sanity check - no need to process duplicate removes | ||
678 | if ( (!pAttachPt) || (std::find(m_remAttachments.begin(), m_remAttachments.end(), pAttachPt) != m_remAttachments.end()) ) | ||
679 | return; | ||
680 | |||
681 | if (isForceDetachable(pAttachPt)) | ||
682 | { | ||
683 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
684 | LLViewerInventoryCategory* pFolder = NULL; | ||
685 | if ( (RlvSettings::getEnableComposites()) && | ||
686 | (gRlvHandler.getCompositeInfo(pAttachPt->getItemID(), NULL, &pFolder)) ) | ||
687 | { | ||
688 | // Attachment belongs to a composite folder so detach the entire folder (if we can take it off) | ||
689 | if (gRlvHandler.canTakeOffComposite(pFolder)) | ||
690 | forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT); | ||
691 | } | ||
692 | else | ||
693 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
694 | { | ||
695 | m_remAttachments.push_back(pAttachPt); | ||
696 | } | ||
697 | } | ||
698 | } | ||
699 | |||
700 | // Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i | ||
701 | bool RlvForceWear::isForceRemovable(EWearableType wtType, bool fCheckComposite /*=true*/, const LLUUID& idExcept /*=LLUUID::null*/) | ||
702 | { | ||
703 | // Wearable type can be removed by an RLV command if: | ||
704 | // - something is worn on that layer | ||
705 | // - its asset type is AT_CLOTHING | ||
706 | // - what's worn isn't "remove locked" by anything (or anything except the object specified by idExcept) | ||
707 | // - what's worn is strippable | ||
708 | // - composite folders are disabled *or* what's worn isn't part of a composite folder that has at least one item locked | ||
709 | LLWearable* pWearable = gAgent.getWearable(wtType); | ||
710 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
711 | LLViewerInventoryCategory* pFolder = NULL; | ||
712 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
713 | return | ||
714 | ( | ||
715 | (pWearable) && | ||
716 | (LLAssetType::AT_CLOTHING == LLWearable::typeToAssetType(wtType)) && | ||
717 | ( (idExcept.notNull()) ? (gRlvHandler.isRemovable(wtType)) | ||
718 | : (gRlvHandler.isRemovableExcept(wtType, idExcept)) ) | ||
719 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | ||
720 | && (gRlvHandler.isStrippable(gAgent.getWearableItem(wtType))) | ||
721 | #endif // RLV_EXTENSION_FLAG_NOSTRIP | ||
722 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
723 | && ( (!fCheckComposite) || (!RlvSettings::getEnableComposites()) || | ||
724 | (!gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) || (gRlvHandler.canTakeOffComposite(pFolder)) ) | ||
725 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
726 | ); | ||
727 | } | ||
728 | |||
729 | // Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i | ||
730 | void RlvForceWear::forceRemove(EWearableType wtType) | ||
731 | { | ||
732 | // Sanity check - no need to process duplicate removes | ||
733 | if ( (WT_INVALID == wtType) || (std::find(m_remWearables.begin(), m_remWearables.end(), wtType) != m_remWearables.end()) ) | ||
734 | return; | ||
735 | |||
736 | if (isForceRemovable(wtType)) | ||
737 | { | ||
738 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
739 | LLViewerInventoryCategory* pFolder = NULL; | ||
740 | if ( (RlvSettings::getEnableComposites()) && | ||
741 | (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(wtType), NULL, &pFolder)) ) | ||
742 | { | ||
743 | // Wearable belongs to a composite folder so detach the entire folder (if we can take it off) | ||
744 | if (gRlvHandler.canTakeOffComposite(pFolder)) | ||
745 | forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT); | ||
746 | } | ||
747 | else | ||
748 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
749 | { | ||
750 | m_remWearables.push_back(wtType); | ||
751 | } | ||
752 | } | ||
753 | } | ||
754 | |||
755 | // Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i | ||
756 | void RlvForceWear::processAdd() | ||
757 | { | ||
758 | // Process attachments | ||
759 | if (m_addAttachments.size()) | ||
760 | { | ||
761 | // Workaround for RezMultipleAttachmentsFromInv bug (see http://jira.secondlife.com/browse/SVC-5383) | ||
762 | #ifndef RLV_WORKAROUND_REZMULTIPLEATTACH | ||
763 | wear_attachments_on_avatar(m_addAttachments, FALSE); | ||
764 | #else | ||
765 | for (S32 idxItem = 0, cntItem = m_addAttachments.count(); idxItem < cntItem; idxItem++) | ||
766 | { | ||
767 | LLViewerInventoryItem* pItem = m_addAttachments.get(idxItem); | ||
768 | |||
769 | S32 idxAttachPt = gRlvHandler.getAttachPointIndex(pItem, true); | ||
770 | if (0 != idxAttachPt) | ||
771 | { | ||
772 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
773 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction(); | ||
774 | rez_action->mItemID = pItem->getUUID(); | ||
775 | rez_action->mAttachPt = idxAttachPt; | ||
776 | |||
777 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action) | ||
778 | #else // Version: 1.23.4 | ||
779 | LLSD payload; | ||
780 | payload["item_id"] = pItem->getUUID(); | ||
781 | payload["attachment_point"] = idxAttachPt; | ||
782 | |||
783 | LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | ||
784 | #endif | ||
785 | } | ||
786 | } | ||
787 | #endif // RLV_WORKAROUND_REZMULTIPLEATTACH | ||
788 | |||
789 | m_addAttachments.clear(); | ||
790 | } | ||
791 | |||
792 | // Process wearables | ||
793 | if (m_addWearables.size()) | ||
794 | { | ||
795 | // [See wear_inventory_category_on_avatar_step2()] | ||
796 | LLWearableHoldingPattern* pWearData = new LLWearableHoldingPattern(TRUE); | ||
797 | |||
798 | // We need to populate 'pWearData->mFoundList' before doing anything else because (some of) the assets might already be available | ||
799 | for (S32 idxItem = 0, cntItem = m_addWearables.count(); idxItem < cntItem; idxItem++) | ||
800 | { | ||
801 | LLViewerInventoryItem* pItem = m_addWearables.get(idxItem); | ||
802 | if ( (pItem) && ((LLAssetType::AT_BODYPART == pItem->getType()) || (LLAssetType::AT_CLOTHING == pItem->getType())) ) | ||
803 | { | ||
804 | LLFoundData* pFound = new LLFoundData(pItem->getUUID(), pItem->getAssetUUID(), pItem->getName(), pItem->getType()); | ||
805 | pWearData->mFoundList.push_front(pFound); | ||
806 | } | ||
807 | } | ||
808 | |||
809 | if (!pWearData->mFoundList.size()) | ||
810 | { | ||
811 | delete pWearData; | ||
812 | return; | ||
813 | } | ||
814 | |||
815 | // If all the assets are available locally then "pWearData" will be freed *before* the last "gWearableList.getAsset()" call returns | ||
816 | bool fContinue = true; LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin(); | ||
817 | while ( (fContinue) && (itWearable != pWearData->mFoundList.end()) ) | ||
818 | { | ||
819 | const LLFoundData* pFound = *itWearable; | ||
820 | ++itWearable; | ||
821 | fContinue = (itWearable != pWearData->mFoundList.end()); | ||
822 | gWearableList.getAsset(pFound->mAssetID, pFound->mName, pFound->mAssetType, onWearableArrived, (void*)pWearData); | ||
823 | } | ||
824 | |||
825 | m_addWearables.clear(); | ||
826 | } | ||
827 | |||
828 | // Process gestures | ||
829 | if (m_addGestures.size()) | ||
830 | { | ||
831 | gGestureManager.activateGestures(m_addGestures); | ||
832 | for (S32 idxGesture = 0, cntGesture = m_addGestures.count(); idxGesture < cntGesture; idxGesture++) | ||
833 | gInventory.updateItem(m_addGestures.get(idxGesture)); | ||
834 | gInventory.notifyObservers(); | ||
835 | |||
836 | m_addGestures.clear(); | ||
837 | } | ||
838 | } | ||
839 | |||
840 | // Checked: 2009-12-18 (RLVa-1.1.0k) | Added: RLVa-1.1.0i | ||
841 | void RlvForceWear::processRem() | ||
842 | { | ||
843 | // Process attachments | ||
844 | if (m_remAttachments.size()) | ||
845 | { | ||
846 | // [See LLAgent::userRemoveAllAttachments()] | ||
847 | gMessageSystem->newMessage("ObjectDetach"); | ||
848 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
849 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); | ||
850 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
851 | |||
852 | for (std::list<LLViewerJointAttachment*>::const_iterator itAttachPt = m_remAttachments.begin(); | ||
853 | itAttachPt != m_remAttachments.end(); ++itAttachPt) | ||
854 | { | ||
855 | LLViewerJointAttachment* pAttachPt = *itAttachPt; | ||
856 | if (pAttachPt->getObject()) | ||
857 | { | ||
858 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); | ||
859 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachPt->getObject()->getLocalID()); | ||
860 | } | ||
861 | } | ||
862 | |||
863 | gMessageSystem->sendReliable(gAgent.getRegionHost()); | ||
864 | |||
865 | m_remAttachments.clear(); | ||
866 | } | ||
867 | |||
868 | // Process wearables | ||
869 | if (m_remWearables.size()) | ||
870 | { | ||
871 | for (std::list<EWearableType>::const_iterator itWearable = m_remWearables.begin(); itWearable != m_remWearables.end(); ++itWearable) | ||
872 | gAgent.removeWearable(*itWearable); | ||
873 | |||
874 | m_remWearables.clear(); | ||
875 | } | ||
876 | |||
877 | // Process gestures | ||
878 | if (m_remGestures.size()) | ||
879 | { | ||
880 | for (S32 idxGesture = 0, cntGesture = m_remGestures.count(); idxGesture < cntGesture; idxGesture++) | ||
881 | { | ||
882 | LLViewerInventoryItem* pItem = m_remGestures.get(idxGesture); | ||
883 | gGestureManager.deactivateGesture(pItem->getUUID()); | ||
884 | gInventory.updateItem(pItem); | ||
885 | gInventory.notifyObservers(); | ||
886 | } | ||
887 | |||
888 | m_remGestures.clear(); | ||
889 | } | ||
890 | } | ||
891 | |||
892 | // Checked: 2010-02-17 (RLVa-1.1.0o) | Modified: RLVa-1.1.0o | ||
893 | void RlvForceWear::onWearableArrived(LLWearable* pWearable, void* pParam) | ||
894 | { | ||
895 | #ifdef RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
896 | // If this wearable will end up replacing a currently worn one that belongs to a composite folder then we need to detach the composite | ||
897 | LLViewerInventoryCategory* pFolder = NULL; | ||
898 | if ( (RlvSettings::getEnableComposites()) && (pWearable) && (gAgent.getWearable(pWearable->getType())) ) | ||
899 | { | ||
900 | // If we're just rewearing the same item we're already wearing then we're not replacing a composite folder | ||
901 | LLWearableHoldingPattern* pWearData = (LLWearableHoldingPattern*)pParam; LLUUID idItem; | ||
902 | for (LLWearableHoldingPattern::found_list_t::const_iterator itWearable = pWearData->mFoundList.begin(); | ||
903 | itWearable != pWearData->mFoundList.end(); ++itWearable) | ||
904 | { | ||
905 | LLFoundData* pFound = *itWearable; | ||
906 | if (pWearable->getID() == pFound->mAssetID) | ||
907 | { | ||
908 | idItem = pFound->mItemID; | ||
909 | break; | ||
910 | } | ||
911 | } | ||
912 | if ( (idItem.notNull()) && (idItem != gAgent.getWearableItem(pWearable->getType())) && | ||
913 | (gRlvHandler.getCompositeInfo(gAgent.getWearableItem(pWearable->getType()), NULL, &pFolder)) ) | ||
914 | { | ||
915 | RlvForceWear rlvWear; | ||
916 | rlvWear.forceFolder(pFolder, ACTION_DETACH, FLAG_DEFAULT); | ||
917 | rlvWear.done(); | ||
918 | } | ||
919 | } | ||
920 | #endif // RLV_EXPERIMENTAL_COMPOSITEFOLDERS | ||
921 | |||
922 | wear_inventory_category_on_avatar_loop(pWearable, pParam); | ||
923 | } | ||
924 | |||
925 | // ============================================================================ | ||
926 | // RlvBehaviourNotifyObserver | ||
927 | // | ||
928 | |||
929 | void RlvBehaviourNotifyObserver::changed(const RlvCommand& rlvCmd, bool fInternal) | ||
930 | { | ||
931 | if (fInternal) | ||
932 | return; | ||
933 | |||
934 | std::string strCmd = rlvCmd.asString(), strNotify; ERlvParamType eCmdType = rlvCmd.getParamType(); | ||
935 | if ( (RLV_TYPE_ADD == eCmdType) || (RLV_TYPE_REMOVE == eCmdType) ) | ||
936 | strNotify = llformat("/%s=%s", strCmd.c_str(), rlvCmd.getParam().c_str()); | ||
937 | else if (RLV_TYPE_CLEAR == eCmdType) | ||
938 | strNotify = llformat("/%s", strCmd.c_str()); | ||
939 | else | ||
940 | return; | ||
941 | |||
942 | for (std::multimap<LLUUID, notifyData>::const_iterator itNotify = m_Notifications.begin(); | ||
943 | itNotify != m_Notifications.end(); ++itNotify) | ||
944 | { | ||
945 | if ( (itNotify->second.strFilter.empty()) || (std::string::npos != strCmd.find(itNotify->second.strFilter)) ) | ||
946 | rlvSendChatReply(itNotify->second.nChannel, strNotify); | ||
947 | } | ||
948 | } | ||
949 | |||
950 | // ============================================================================ | ||
510 | // RlvWLSnapshot | 951 | // RlvWLSnapshot |
511 | // | 952 | // |
512 | 953 | ||
@@ -546,38 +987,6 @@ RlvWLSnapshot* RlvWLSnapshot::takeSnapshot() | |||
546 | } | 987 | } |
547 | 988 | ||
548 | // ========================================================================= | 989 | // ========================================================================= |
549 | // RlvSettings | ||
550 | // | ||
551 | |||
552 | BOOL RlvSettings::fShowNameTags = FALSE; | ||
553 | |||
554 | BOOL RlvSettings::getEnableWear() | ||
555 | { | ||
556 | return | ||
557 | rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, TRUE) && // "Enable Wear" is toggled on and... | ||
558 | (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)) && // not restricted and... | ||
559 | (!gRlvHandler.hasBehaviour(RLV_BHVR_ADDATTACH)); // we have attach points we can attach to [see RlvHandler::onAddRemAttach()] | ||
560 | } | ||
561 | |||
562 | #ifdef RLV_EXTENSION_STARTLOCATION | ||
563 | // Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.1d | ||
564 | void RlvSettings::updateLoginLastLocation() | ||
565 | { | ||
566 | if (gSavedPerAccountSettings.controlExists(RLV_SETTING_LOGINLASTLOCATION)) | ||
567 | { | ||
568 | BOOL fValue = (gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)) || | ||
569 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && | ||
570 | (gAgent.getAvatarObject()) && (!gAgent.getAvatarObject()->mIsSitting) ); | ||
571 | if (gSavedPerAccountSettings.getBOOL(RLV_SETTING_LOGINLASTLOCATION) != fValue) | ||
572 | { | ||
573 | gSavedPerAccountSettings.setBOOL(RLV_SETTING_LOGINLASTLOCATION, fValue); | ||
574 | gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE); | ||
575 | } | ||
576 | } | ||
577 | } | ||
578 | #endif // RLV_EXTENSION_STARTLOCATION | ||
579 | |||
580 | // ========================================================================= | ||
581 | // Various helper classes/timers/functors | 990 | // Various helper classes/timers/functors |
582 | // | 991 | // |
583 | 992 | ||
@@ -618,39 +1027,40 @@ void RlvCurrentlyWorn::fetchWorn() | |||
618 | f.fetchItems(idItems); | 1027 | f.fetchItems(idItems); |
619 | } | 1028 | } |
620 | 1029 | ||
621 | // Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0f | 1030 | void RlvGiveToRLVAgentOffer::done() |
622 | bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode) | ||
623 | { | ||
624 | return (pNode->getObject()) ? gRlvHandler.isLockedAttachment(pNode->getObject(), m_eLock) : false; | ||
625 | } | ||
626 | |||
627 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0f | ||
628 | bool RlvSelectIsOwnedByOrGroupOwned::apply(LLSelectNode* pNode) | ||
629 | { | 1031 | { |
630 | return (pNode->mPermissions->isGroupOwned()) || (pNode->mPermissions->getOwner() == m_idAgent); | 1032 | LLViewerInventoryCategory* pRlvRoot = gRlvHandler.getSharedRoot(); |
631 | } | 1033 | LLViewerInventoryCategory* pFolder = (mCompleteFolders.size()) ? gInventory.getCategory(mCompleteFolders[0]) : NULL; |
1034 | if ( (pRlvRoot) && (pFolder) ) | ||
1035 | { | ||
1036 | std::string strName = pFolder->getName(); | ||
1037 | if (strName.find(RLV_PUTINV_PREFIX) == 0) | ||
1038 | { | ||
1039 | LLInventoryModel::update_list_t update; | ||
1040 | LLInventoryModel::LLCategoryUpdate updOldParent(pFolder->getParentUUID(), -1); | ||
1041 | update.push_back(updOldParent); | ||
1042 | LLInventoryModel::LLCategoryUpdate updNewParent(pRlvRoot->getUUID(), 1); | ||
1043 | update.push_back(updNewParent); | ||
1044 | gInventory.accountForUpdate(update); | ||
1045 | |||
1046 | LLPointer<LLViewerInventoryCategory> pNewFolder = new LLViewerInventoryCategory(pFolder); | ||
1047 | pNewFolder->setParent(pRlvRoot->getUUID()); | ||
1048 | pNewFolder->updateParentOnServer(FALSE); | ||
1049 | pNewFolder->rename(strName.erase(0, strName.find(RLV_FOLDER_PREFIX_PUTINV))); | ||
1050 | pNewFolder->updateServer(FALSE); | ||
1051 | gInventory.updateCategory(pNewFolder); | ||
1052 | } | ||
1053 | } | ||
632 | 1054 | ||
633 | // Checked: 2009-05-31 (RLVa-0.2.0f) | Modified: RLVa-0.2.0f | 1055 | gInventory.removeObserver(this); |
634 | bool RlvSelectIsSittingOn::apply(LLSelectNode* pNode) | 1056 | gInventory.notifyObservers(); |
635 | { | 1057 | delete this; |
636 | return (pNode->getObject()) && (pNode->getObject()->getRootEdit() == m_pObject); | ||
637 | } | 1058 | } |
638 | 1059 | ||
639 | // ============================================================================ | 1060 | // ============================================================================ |
640 | // Various helper functions | 1061 | // Various helper functions |
641 | // | 1062 | // |
642 | 1063 | ||
643 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a | ||
644 | BOOL rlvAttachToEnabler(void* pParam) | ||
645 | { | ||
646 | // Disable an option on the "Attach to (HUD)" submenu if: | ||
647 | // - the attachment point is locked non-detachable with an object attached | ||
648 | // - the attachment point is locked non-attachable | ||
649 | return (pParam != NULL) && | ||
650 | (!gRlvHandler.isLockedAttachment(((LLViewerJointAttachment*)pParam)->getObject(), RLV_LOCK_REMOVE)) && | ||
651 | (!gRlvHandler.isLockedAttachment((LLViewerJointAttachment*)pParam, RLV_LOCK_ADD)); | ||
652 | } | ||
653 | |||
654 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g | 1064 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g |
655 | bool rlvCanDeleteOrReturn() | 1065 | bool rlvCanDeleteOrReturn() |
656 | { | 1066 | { |
@@ -677,13 +1087,6 @@ bool rlvCanDeleteOrReturn() | |||
677 | return fIsAllowed; | 1087 | return fIsAllowed; |
678 | } | 1088 | } |
679 | 1089 | ||
680 | // Checked: 2009-10-04 (RLVa-1.0.4b) | Modified: RLVa-1.0.4b | ||
681 | BOOL rlvEnableWearEnabler(void* pParam) | ||
682 | { | ||
683 | // Visually disables the "Enable Wear" option when restricted from toggling it | ||
684 | return (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)); | ||
685 | } | ||
686 | |||
687 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | 1090 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d |
688 | S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type) | 1091 | S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType::EType type) |
689 | { | 1092 | { |
@@ -712,12 +1115,12 @@ S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType | |||
712 | 1115 | ||
713 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | 1116 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 |
714 | LLStringUtil::format_map_t args; | 1117 | LLStringUtil::format_map_t args; |
715 | args["[MESSAGE]"] = llformat("Restrained Life Support will be %s after you restart", | 1118 | args["[MESSAGE]"] = llformat("RestrainedLove Support will be %s after you restart", |
716 | (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); | 1119 | (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); |
717 | gViewerWindow->alertXml("GenericAlert", args); | 1120 | gViewerWindow->alertXml("GenericAlert", args); |
718 | #else // Version: 1.23.4 | 1121 | #else // Version: 1.23.4 |
719 | LLSD args; | 1122 | LLSD args; |
720 | args["MESSAGE"] = llformat("Restrained Life Support will be %s after you restart", | 1123 | args["MESSAGE"] = llformat("RestrainedLove Support will be %s after you restart", |
721 | (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); | 1124 | (rlv_handler_t::isEnabled()) ? "disabled" : "enabled" ); |
722 | LLNotifications::instance().add("GenericAlert", args); | 1125 | LLNotifications::instance().add("GenericAlert", args); |
723 | #endif | 1126 | #endif |