diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/rlvhelper.cpp | 257 |
1 files changed, 224 insertions, 33 deletions
diff --git a/linden/indra/newview/rlvhelper.cpp b/linden/indra/newview/rlvhelper.cpp index c8d430d..67ffbe2 100644 --- a/linden/indra/newview/rlvhelper.cpp +++ b/linden/indra/newview/rlvhelper.cpp | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "llviewerprecompiledheaders.h" | 1 | #include "llviewerprecompiledheaders.h" |
2 | #include "llagent.h" | 2 | #include "llagent.h" |
3 | #include "llfloaterwindlight.h" | 3 | #include "llfloaterwindlight.h" |
4 | #include "llinventoryview.h" | ||
4 | #include "llviewerobject.h" | 5 | #include "llviewerobject.h" |
5 | #include "llviewerstats.h" | 6 | #include "llviewerstats.h" |
6 | #include "llviewerwindow.h" | 7 | #include "llviewerwindow.h" |
@@ -11,6 +12,12 @@ | |||
11 | #include "rlvevent.h" | 12 | #include "rlvevent.h" |
12 | #include "rlvhandler.h" | 13 | #include "rlvhandler.h" |
13 | 14 | ||
15 | // Only defined in llinventorybridge.cpp | ||
16 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
17 | #include "llinventorybridge.h" | ||
18 | void confirm_replace_attachment_rez(S32 option, void* user_data); | ||
19 | #endif | ||
20 | |||
14 | // ============================================================================ | 21 | // ============================================================================ |
15 | // Static variable initialization | 22 | // Static variable initialization |
16 | // | 23 | // |
@@ -104,12 +111,13 @@ void RlvCommand::initLookupTable() | |||
104 | std::string arBehaviours[RLV_BHVR_COUNT] = | 111 | std::string arBehaviours[RLV_BHVR_COUNT] = |
105 | { | 112 | { |
106 | "version", "detach", "sendchat", "emote", "chatshout", "chatnormal", "chatwhisper", "redirchat", "rediremote", | 113 | "version", "detach", "sendchat", "emote", "chatshout", "chatnormal", "chatwhisper", "redirchat", "rediremote", |
107 | "sendim", "recvchat", "recvemote", "recvim", "tplm", "tploc", "tplure", "sittp", "edit", "rez", "addoutfit", | 114 | "sendim", "recvchat", "recvemote", "recvim", "tplm", "tploc", "tplure", "sittp", "edit", "rez", |
108 | "remoutfit", "getoutfit", "getattach", "showinv", "viewnote", "unsit", "sit", "sendchannel", "getstatus", "getstatusall", | 115 | "addoutfit", "remoutfit", "getoutfit", "addattach", "remattach", "getattach", "showinv", "viewnote", "unsit", "sit", |
109 | "getinv", "getinvworn", "findfolder", "findfolders", "attach", "attachall", "detachall", "getpath", "attachthis", | 116 | "sendchannel", "getstatus", "getstatusall", "getinv", "getinvworn", "findfolder", "findfolders", |
110 | "attachallthis", "detachthis", "detachallthis", "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp", | 117 | "attach", "attachall", "detachall", "getpath", "attachthis", "attachallthis", "detachthis", "detachallthis", |
111 | "acceptpermission", "shownames", "fly", "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", | 118 | "fartouch", "showworldmap", "showminimap", "showloc", "tpto", "accepttp", "acceptpermission", "shownames", "fly", |
112 | "showhovertextworld", "showhovertexthud", "showhovertext", "notify", "defaultwear", "versionnum", "permissive" | 119 | "getsitid", "setdebug", "setenv", "detachme", "showhovertextall", "showhovertextworld", "showhovertexthud", |
120 | "showhovertext", "notify", "defaultwear", "versionnum", "permissive", "viewscript", "viewtexture" | ||
113 | }; | 121 | }; |
114 | 122 | ||
115 | for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) | 123 | for (int idxBvhr = 0; idxBvhr < RLV_BHVR_COUNT; idxBvhr++) |
@@ -207,6 +215,204 @@ std::string RlvObject::getStatusString(const std::string& strMatch) const | |||
207 | } | 215 | } |
208 | 216 | ||
209 | // ============================================================================ | 217 | // ============================================================================ |
218 | // RlvAttachmentManager | ||
219 | // | ||
220 | |||
221 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
222 | void RlvAttachmentManager::forceAttach(const LLUUID& idItem, S32 idxAttachPt) | ||
223 | { | ||
224 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
225 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction(); | ||
226 | rez_action->mItemID = idItem; | ||
227 | rez_action->mAttachPt = idxAttachPt; | ||
228 | |||
229 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action) | ||
230 | #else // Version: 1.23.4 | ||
231 | LLSD payload; | ||
232 | payload["item_id"] = idItem; | ||
233 | payload["attachment_point"] = idxAttachPt; | ||
234 | |||
235 | LLNotifications::instance().forceResponse( | ||
236 | LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | ||
237 | #endif | ||
238 | } | ||
239 | |||
240 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
241 | void RlvAttachmentManager::forceDetach(LLViewerJointAttachment* pAttachPt) | ||
242 | { | ||
243 | // Copy/paste from handle_detach_from_avatar() | ||
244 | LLViewerObject* attached_object = pAttachPt->getObject(); | ||
245 | if (attached_object) | ||
246 | { | ||
247 | gMessageSystem->newMessage("ObjectDetach"); | ||
248 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
249 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); | ||
250 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
251 | |||
252 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); | ||
253 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); | ||
254 | gMessageSystem->sendReliable( gAgent.getRegionHost() ); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
259 | void RlvAttachmentManager::onAttach(LLViewerJointAttachment* pAttachPt) | ||
260 | { | ||
261 | S32 idxAttachPt = gRlvHandler.getAttachPointIndex(pAttachPt->getObject()); | ||
262 | if (!idxAttachPt) | ||
263 | return; | ||
264 | |||
265 | // If the attachment point has a pending "reattach" then we don't want to do anything | ||
266 | rlv_attach_map_t::iterator itAttach = m_PendingAttach.find(idxAttachPt); | ||
267 | if (itAttach != m_PendingAttach.end()) | ||
268 | { | ||
269 | if (pAttachPt->getItemID() == itAttach->second.idItem) | ||
270 | m_PendingAttach.erase(itAttach); | ||
271 | return; | ||
272 | } | ||
273 | |||
274 | // Check if the attach is the result of a user action (="Wear") | ||
275 | rlv_wear_map_t::iterator itWear = m_PendingWear.find(pAttachPt->getItemID()); | ||
276 | if (itWear != m_PendingWear.end()) | ||
277 | { | ||
278 | // We need to return the attachment point to its previous state if it's non-attachable | ||
279 | if (gRlvHandler.isLockedAttachment(idxAttachPt, RLV_LOCK_ADD)) | ||
280 | { | ||
281 | // Get the state of the attachment point at the time the user picked "Wear" (if we don't have one it wasn't "add locked" then) | ||
282 | std::map<S32, LLUUID>::iterator itAttachPrev = itWear->second.attachPts.find(idxAttachPt); | ||
283 | if ( (itAttachPrev != itWear->second.attachPts.end()) && (pAttachPt->getItemID() != itAttachPrev->second) ) | ||
284 | { | ||
285 | // If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one | ||
286 | if (itAttachPrev->second.isNull()) | ||
287 | { | ||
288 | forceDetach(pAttachPt); | ||
289 | m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID())); | ||
290 | } | ||
291 | else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there) | ||
292 | { | ||
293 | m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(itAttachPrev->second))); | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | m_PendingWear.erase(itWear); // No need to start the timer since it should be running already if '!m_PendingWear.empty()' | ||
298 | } | ||
299 | } | ||
300 | |||
301 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
302 | void RlvAttachmentManager::onDetach(LLViewerJointAttachment* pAttachPt) | ||
303 | { | ||
304 | S32 idxAttachPt = gRlvHandler.getAttachPointIndex(pAttachPt->getObject()); | ||
305 | if (!idxAttachPt) | ||
306 | return; | ||
307 | |||
308 | // If this is an attachment that we force-detached then we don't want to do anything (even if it is "remove locked") | ||
309 | rlv_detach_map_t::iterator itDetach = m_PendingDetach.find(idxAttachPt); | ||
310 | if ( (itDetach != m_PendingDetach.end()) && (itDetach->second == pAttachPt->getItemID()) ) | ||
311 | { | ||
312 | m_PendingDetach.erase(itDetach); | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | // If the attachment is currently "remove locked" and we're not already trying to reattach something there we should reattach it | ||
317 | if ( (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) && (gRlvHandler.isLockedAttachment(idxAttachPt, RLV_LOCK_REMOVE)) ) | ||
318 | { | ||
319 | m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(pAttachPt->getItemID()))); | ||
320 | startTimer(); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
325 | void RlvAttachmentManager::onSavedAssetIntoInventory(const LLUUID& idItem) | ||
326 | { | ||
327 | for (rlv_attach_map_t::iterator itAttach = m_PendingAttach.begin(); itAttach != m_PendingAttach.end(); ++itAttach) | ||
328 | { | ||
329 | if ( (!itAttach->second.fAssetSaved) && (idItem == itAttach->second.idItem) ) | ||
330 | { | ||
331 | forceAttach(itAttach->second.idItem, itAttach->first); | ||
332 | itAttach->second.tsAttach = LLFrameTimer::getElapsedSeconds(); | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | |||
337 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
338 | BOOL RlvAttachmentManager::onTimer() | ||
339 | { | ||
340 | F64 tsCurrent = LLFrameTimer::getElapsedSeconds(); | ||
341 | |||
342 | // Garbage collect (failed) wear requests older than 60 seconds | ||
343 | rlv_wear_map_t::iterator itWear = m_PendingWear.begin(); | ||
344 | while (itWear != m_PendingWear.end()) | ||
345 | { | ||
346 | if (itWear->second.tsWear + 60 < tsCurrent) | ||
347 | m_PendingWear.erase(itWear++); | ||
348 | else | ||
349 | ++itWear; | ||
350 | } | ||
351 | |||
352 | // Walk over the pending reattach list | ||
353 | rlv_attach_map_t::iterator itAttach = m_PendingAttach.begin(); | ||
354 | while (itAttach != m_PendingAttach.end()) | ||
355 | { | ||
356 | // Sanity check - make sure the item is still in the user's inventory | ||
357 | if (gInventory.getItem(itAttach->second.idItem) == NULL) | ||
358 | { | ||
359 | m_PendingAttach.erase(itAttach++); | ||
360 | continue; | ||
361 | } | ||
362 | |||
363 | // Force an attach if we haven't gotten an SavedAssetIntoInventory message after 15 seconds | ||
364 | // (or if it's been 30 seconds since we last tried to reattach the item) | ||
365 | bool fAttach = false; | ||
366 | if ( (!itAttach->second.fAssetSaved) && (itAttach->second.tsDetach + 15 < tsCurrent) ) | ||
367 | { | ||
368 | itAttach->second.fAssetSaved = true; | ||
369 | fAttach = true; | ||
370 | } | ||
371 | else if ( (itAttach->second.fAssetSaved) && (itAttach->second.tsAttach + 30 < tsCurrent) ) | ||
372 | { | ||
373 | fAttach = true; | ||
374 | } | ||
375 | |||
376 | if (fAttach) | ||
377 | { | ||
378 | forceAttach(itAttach->second.idItem, itAttach->first); | ||
379 | itAttach->second.tsAttach = tsCurrent; | ||
380 | } | ||
381 | |||
382 | ++itAttach; | ||
383 | } | ||
384 | |||
385 | return ( (m_PendingAttach.empty()) && (m_PendingDetach.empty()) && (m_PendingWear.empty()) ); | ||
386 | } | ||
387 | |||
388 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
389 | void RlvAttachmentManager::onWearAttachment(const LLUUID& idItem) | ||
390 | { | ||
391 | // We only need to keep track of wears if there are non-attachable attachment points | ||
392 | if (!gRlvHandler.hasLockedAttachment(RLV_LOCK_ADD)) | ||
393 | return; | ||
394 | |||
395 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
396 | if (!pAvatar) | ||
397 | return; | ||
398 | |||
399 | // If the attachment point this will end up being attached to is: | ||
400 | // - unlocked : nothing should happen (from RLVa's point of view) | ||
401 | // - RLV_LOCK_ADD: the new attachment should get detached and the current one reattached (unless it's currently empty) | ||
402 | // - RLV_LOCK_REM: the current attachment will get reattached on ObjectKill (if there is no current one then nothing should happen) | ||
403 | RlvWearInfo infoWear(idItem); | ||
404 | for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin(); | ||
405 | itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach) | ||
406 | { | ||
407 | if (gRlvHandler.isLockedAttachment(itAttach->first, RLV_LOCK_ADD)) // We only need to keep track of these (see above) | ||
408 | infoWear.attachPts.insert(std::pair<S32, LLUUID>(itAttach->first, itAttach->second->getItemID())); | ||
409 | } | ||
410 | |||
411 | m_PendingWear.insert(std::pair<LLUUID, RlvWearInfo>(idItem, infoWear)); | ||
412 | startTimer(); | ||
413 | } | ||
414 | |||
415 | // ============================================================================ | ||
210 | // RlvWearableItemCollector | 416 | // RlvWearableItemCollector |
211 | // | 417 | // |
212 | 418 | ||
@@ -354,7 +560,10 @@ BOOL RlvSettings::fShowNameTags = FALSE; | |||
354 | 560 | ||
355 | BOOL RlvSettings::getEnableWear() | 561 | BOOL RlvSettings::getEnableWear() |
356 | { | 562 | { |
357 | return rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, TRUE) && (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)); | 563 | return |
564 | rlvGetSettingBOOL(RLV_SETTING_ENABLEWEAR, TRUE) && // "Enable Wear" is toggled on and... | ||
565 | (!gRlvHandler.hasBehaviour(RLV_BHVR_DEFAULTWEAR)) && // not restricted and... | ||
566 | (!gRlvHandler.hasBehaviour(RLV_BHVR_ADDATTACH)); // we have attach points we can attach to [see RlvHandler::onAddRemAttach()] | ||
358 | } | 567 | } |
359 | 568 | ||
360 | #ifdef RLV_EXTENSION_STARTLOCATION | 569 | #ifdef RLV_EXTENSION_STARTLOCATION |
@@ -419,7 +628,7 @@ void RlvCurrentlyWorn::fetchWorn() | |||
419 | // Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0f | 628 | // Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0f |
420 | bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode) | 629 | bool RlvSelectHasLockedAttach::apply(LLSelectNode* pNode) |
421 | { | 630 | { |
422 | return (pNode->getObject()) ? !gRlvHandler.isDetachable(pNode->getObject()) : false; | 631 | return (pNode->getObject()) ? gRlvHandler.isLockedAttachment(pNode->getObject(), m_eLock) : false; |
423 | } | 632 | } |
424 | 633 | ||
425 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0f | 634 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0f |
@@ -438,11 +647,15 @@ bool RlvSelectIsSittingOn::apply(LLSelectNode* pNode) | |||
438 | // Various helper functions | 647 | // Various helper functions |
439 | // | 648 | // |
440 | 649 | ||
441 | // Checked: 2009-09-08 (RLVa-1.0.2c) | Modified: RLVa-1.0.2c | 650 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
442 | BOOL rlvAttachToEnabler(void* pParam) | 651 | BOOL rlvAttachToEnabler(void* pParam) |
443 | { | 652 | { |
444 | // Enables/disables an option on the "Attach to (HUD)" submenu depending on whether it is (un)detachable | 653 | // Disable an option on the "Attach to (HUD)" submenu if: |
445 | return gRlvHandler.isDetachable((LLViewerJointAttachment*)pParam); | 654 | // - the attachment point is locked non-detachable with an object attached |
655 | // - the attachment point is locked non-attachable | ||
656 | return (pParam != NULL) && | ||
657 | (!gRlvHandler.isLockedAttachment(((LLViewerJointAttachment*)pParam)->getObject(), RLV_LOCK_REMOVE)) && | ||
658 | (!gRlvHandler.isLockedAttachment((LLViewerJointAttachment*)pParam, RLV_LOCK_ADD)); | ||
446 | } | 659 | } |
447 | 660 | ||
448 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g | 661 | // Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-0.2.0g |
@@ -527,24 +740,6 @@ S32 rlvGetDirectDescendentsCount(const LLInventoryCategory* pFolder, LLAssetType | |||
527 | // Message sending functions | 740 | // Message sending functions |
528 | // | 741 | // |
529 | 742 | ||
530 | // Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h | ||
531 | void rlvForceDetach(LLViewerJointAttachment* pAttachPt) | ||
532 | { | ||
533 | // Copy/paste from handle_detach_from_avatar() | ||
534 | LLViewerObject* attached_object = pAttachPt->getObject(); | ||
535 | if (attached_object) | ||
536 | { | ||
537 | gMessageSystem->newMessage("ObjectDetach"); | ||
538 | gMessageSystem->nextBlockFast(_PREHASH_AgentData); | ||
539 | gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); | ||
540 | gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); | ||
541 | |||
542 | gMessageSystem->nextBlockFast(_PREHASH_ObjectData); | ||
543 | gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); | ||
544 | gMessageSystem->sendReliable( gAgent.getRegionHost() ); | ||
545 | } | ||
546 | } | ||
547 | |||
548 | void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession) | 743 | void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession) |
549 | { | 744 | { |
550 | // (See process_improved_im) | 745 | // (See process_improved_im) |
@@ -662,7 +857,3 @@ std::string rlvGetLastParenthesisedText(const std::string& strText, std::string: | |||
662 | } | 857 | } |
663 | 858 | ||
664 | // ========================================================================= | 859 | // ========================================================================= |
665 | // Debug helper functions | ||
666 | // | ||
667 | |||
668 | // ========================================================================= | ||