diff options
Diffstat (limited to 'linden')
-rw-r--r-- | linden/indra/newview/llagent.cpp | 4 | ||||
-rw-r--r-- | linden/indra/newview/llfloateropenobject.cpp | 13 | ||||
-rw-r--r-- | linden/indra/newview/llinventorybridge.cpp | 159 | ||||
-rw-r--r-- | linden/indra/newview/llpanelcontents.cpp | 8 | ||||
-rw-r--r-- | linden/indra/newview/llpanelinventory.cpp | 51 | ||||
-rw-r--r-- | linden/indra/newview/llpreviewscript.cpp | 12 | ||||
-rw-r--r-- | linden/indra/newview/lltooldraganddrop.cpp | 10 | ||||
-rw-r--r-- | linden/indra/newview/llviewerdisplay.cpp | 4 | ||||
-rw-r--r-- | linden/indra/newview/llviewermenu.cpp | 106 | ||||
-rw-r--r-- | linden/indra/newview/llviewertexteditor.cpp | 7 | ||||
-rw-r--r-- | linden/indra/newview/llvoavatar.cpp | 31 | ||||
-rw-r--r-- | linden/indra/newview/llvovolume.cpp | 8 | ||||
-rw-r--r-- | linden/indra/newview/pipeline.cpp | 4 | ||||
-rw-r--r-- | linden/indra/newview/rlvdefines.h | 21 | ||||
-rw-r--r-- | linden/indra/newview/rlvextensions.cpp | 2 | ||||
-rw-r--r-- | linden/indra/newview/rlvhandler.cpp | 519 | ||||
-rw-r--r-- | linden/indra/newview/rlvhandler.h | 139 | ||||
-rw-r--r-- | linden/indra/newview/rlvhelper.cpp | 257 | ||||
-rw-r--r-- | linden/indra/newview/rlvhelper.h | 78 |
19 files changed, 905 insertions, 528 deletions
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 8b118e0..a0ab4ab 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp | |||
@@ -7761,7 +7761,7 @@ void LLAgent::userRemoveAllAttachments( void* userdata ) | |||
7761 | return; | 7761 | return; |
7762 | } | 7762 | } |
7763 | 7763 | ||
7764 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.0c | 7764 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
7765 | // NOTE-RLVa: This function is called from inside RlvHandler as well, hence the rather heavy modifications | 7765 | // NOTE-RLVa: This function is called from inside RlvHandler as well, hence the rather heavy modifications |
7766 | std::list<U32> rlvAttachments; | 7766 | std::list<U32> rlvAttachments; |
7767 | // TODO-RLVa: Once we have the improved "removeWearable" logic implemented we can just get rid of the whole "rlvCompFolders" hassle | 7767 | // TODO-RLVa: Once we have the improved "removeWearable" logic implemented we can just get rid of the whole "rlvCompFolders" hassle |
@@ -7779,7 +7779,7 @@ void LLAgent::userRemoveAllAttachments( void* userdata ) | |||
7779 | { | 7779 | { |
7780 | if (rlv_handler_t::isEnabled()) | 7780 | if (rlv_handler_t::isEnabled()) |
7781 | { | 7781 | { |
7782 | if (!gRlvHandler.isDetachable(curiter->first)) | 7782 | if (gRlvHandler.isLockedAttachment(curiter->first, RLV_LOCK_REMOVE)) |
7783 | continue; | 7783 | continue; |
7784 | 7784 | ||
7785 | // Check if we're being called in response to an RLV command (that would be @detach=force) | 7785 | // Check if we're being called in response to an RLV command (that would be @detach=force) |
diff --git a/linden/indra/newview/llfloateropenobject.cpp b/linden/indra/newview/llfloateropenobject.cpp index fd4f9c6..a83b0c9 100644 --- a/linden/indra/newview/llfloateropenobject.cpp +++ b/linden/indra/newview/llfloateropenobject.cpp | |||
@@ -207,18 +207,7 @@ void LLFloaterOpenObject::onClickMoveToInventory(void* data) | |||
207 | void LLFloaterOpenObject::onClickMoveAndWear(void* data) | 207 | void LLFloaterOpenObject::onClickMoveAndWear(void* data) |
208 | { | 208 | { |
209 | LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; | 209 | LLFloaterOpenObject* self = (LLFloaterOpenObject*)data; |
210 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Deprecated: RLVa-0.2.2a | 210 | self->moveToInventory(true); |
211 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
212 | { | ||
213 | // TODO-RLVa: once we have "Add to Outfit" and "Replace Outfit" working we don't need this anymore | ||
214 | self->moveToInventory(false); | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | self->moveToInventory(true); | ||
219 | } | ||
220 | // [/RLVa:KB] | ||
221 | // self->moveToInventory(true); | ||
222 | self->close(); | 211 | self->close(); |
223 | } | 212 | } |
224 | 213 | ||
diff --git a/linden/indra/newview/llinventorybridge.cpp b/linden/indra/newview/llinventorybridge.cpp index 5060d21..f706ad6 100644 --- a/linden/indra/newview/llinventorybridge.cpp +++ b/linden/indra/newview/llinventorybridge.cpp | |||
@@ -488,6 +488,20 @@ void LLInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
488 | items.push_back(std::string("Open")); | 488 | items.push_back(std::string("Open")); |
489 | items.push_back(std::string("Properties")); | 489 | items.push_back(std::string("Properties")); |
490 | 490 | ||
491 | // [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c | ||
492 | if (rlv_handler_t::isEnabled()) | ||
493 | { | ||
494 | LLInventoryObject* pItem = (mInventoryPanel->getModel()) ? mInventoryPanel->getModel()->getObject(mUUID) : NULL; | ||
495 | if ( (pItem) && | ||
496 | ( ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE))) || | ||
497 | ((LLAssetType::AT_LSL_TEXT == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT))) || | ||
498 | ((LLAssetType::AT_NOTECARD == pItem->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) ) ) | ||
499 | { | ||
500 | disabled_items.push_back(std::string("Open")); | ||
501 | } | ||
502 | } | ||
503 | // [/RLVa:KB] | ||
504 | |||
491 | getClipboardEntries(true, items, disabled_items, flags); | 505 | getClipboardEntries(true, items, disabled_items, flags); |
492 | } | 506 | } |
493 | hideContextEntries(menu, items, disabled_items); | 507 | hideContextEntries(menu, items, disabled_items); |
@@ -2446,6 +2460,13 @@ void open_texture(const LLUUID& item_id, | |||
2446 | const LLUUID& source_id, | 2460 | const LLUUID& source_id, |
2447 | BOOL take_focus) | 2461 | BOOL take_focus) |
2448 | { | 2462 | { |
2463 | // [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Added: RLVa-1.0.5c | ||
2464 | if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE)) | ||
2465 | { | ||
2466 | return; | ||
2467 | } | ||
2468 | // [/RLVa:KB] | ||
2469 | |||
2449 | // See if we can bring an exiting preview to the front | 2470 | // See if we can bring an exiting preview to the front |
2450 | if( !LLPreview::show( item_id, take_focus ) ) | 2471 | if( !LLPreview::show( item_id, take_focus ) ) |
2451 | { | 2472 | { |
@@ -3274,11 +3295,11 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model | |||
3274 | item = (LLViewerInventoryItem*)gInventory.getItem(object_id); | 3295 | item = (LLViewerInventoryItem*)gInventory.getItem(object_id); |
3275 | if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID())) | 3296 | if(item && gInventory.isObjectDescendentOf(object_id, gAgent.getInventoryRootID())) |
3276 | { | 3297 | { |
3277 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 3298 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
3278 | // User picked "Wear" so either nothing is locked, or we need to look up the specific attach point from its name | 3299 | // User picked "Wear" so either nothing is locked, or we need to look up the specific attach point from its name |
3279 | // (NOTE: rez_attachment will take care of deciding whether or not we *can* attach) | 3300 | // (NOTE: rez_attachment will take care of deciding whether or not we *can* attach) |
3280 | rez_attachment(item, | 3301 | rez_attachment(item, |
3281 | ((!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment()) || (RlvSettings::getEnableWear())) | 3302 | ((!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) || (RlvSettings::getEnableWear())) |
3282 | ? NULL : gRlvHandler.getAttachPoint(item, true)); | 3303 | ? NULL : gRlvHandler.getAttachPoint(item, true)); |
3283 | // [/RLVa:KB] | 3304 | // [/RLVa:KB] |
3284 | // rez_attachment(item, NULL); | 3305 | // rez_attachment(item, NULL); |
@@ -3301,9 +3322,9 @@ void LLObjectBridge::performAction(LLFolderView* folder, LLInventoryModel* model | |||
3301 | { | 3322 | { |
3302 | LLInventoryItem* item = gInventory.getItem(mUUID); | 3323 | LLInventoryItem* item = gInventory.getItem(mUUID); |
3303 | 3324 | ||
3304 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 3325 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
3305 | // Fall-through: if there's a "Detach from yourself" code path we missed then we'll still disallow the detach here | 3326 | // Fall-through: if there's a "Detach from yourself" code path we missed then we'll still disallow the detach here |
3306 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(item)) ) | 3327 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(item, RLV_LOCK_REMOVE)) ) |
3307 | { | 3328 | { |
3308 | return; | 3329 | return; |
3309 | } | 3330 | } |
@@ -3398,24 +3419,38 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach | |||
3398 | rez_action->mAttachPt = attach_pt; | 3419 | rez_action->mAttachPt = attach_pt; |
3399 | if (attachment && attachment->getObject()) | 3420 | if (attachment && attachment->getObject()) |
3400 | { | 3421 | { |
3401 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | 3422 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
3402 | if ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.isDetachable(attach_pt)) ) | 3423 | if ( (rlv_handler_t::isEnabled()) && // Can't replace an existing object if it's undetachable |
3403 | gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action); | 3424 | (gRlvHandler.isLockedAttachment(attach_pt, RLV_LOCK_ANY)) ) // or if we're not allowed to attach to that attach point |
3404 | else | 3425 | { |
3405 | delete rez_action; | 3426 | delete rez_action; |
3406 | // [/RLVa] | 3427 | return; |
3407 | // gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action); | 3428 | } |
3429 | // [/RLVa:KB] | ||
3430 | gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action); | ||
3408 | } | 3431 | } |
3409 | else | 3432 | else |
3410 | { | 3433 | { |
3411 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | 3434 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-10-10 (RLVa-1.0.5) | Modified: RLVa-1.0.5 |
3412 | // Don't allow wear to default attach point if there are any locked attachments | 3435 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ) |
3413 | if ( (!rlv_handler_t::isEnabled()) || (0 != attach_pt) || (!gRlvHandler.hasLockedAttachment()) || (RlvSettings::getEnableWear()) ) | 3436 | { |
3414 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); | 3437 | if (0 == attach_pt) // Can't wear on the default attachment point |
3415 | else | 3438 | { |
3416 | delete rez_action; | 3439 | if (!RlvSettings::getEnableWear()) // (unless "Enable Wear" is enabled) |
3417 | // [/RLVa] | 3440 | { |
3418 | // confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); | 3441 | delete rez_action; |
3442 | return; | ||
3443 | } | ||
3444 | gRlvHandler.onWearAttachment(item->getUUID()); | ||
3445 | } | ||
3446 | else if (gRlvHandler.isLockedAttachment(attach_pt, RLV_LOCK_ADD)) // and we can never wear on a non-attachable attach point | ||
3447 | { | ||
3448 | delete rez_action; | ||
3449 | return; | ||
3450 | } | ||
3451 | } | ||
3452 | // [/RLVa:KB] | ||
3453 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); | ||
3419 | } | 3454 | } |
3420 | } | 3455 | } |
3421 | 3456 | ||
@@ -3485,9 +3520,12 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
3485 | { | 3520 | { |
3486 | items.push_back(std::string("Detach From Yourself")); | 3521 | items.push_back(std::string("Detach From Yourself")); |
3487 | 3522 | ||
3488 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 3523 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
3489 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(item)) ) | 3524 | if ( (rlv_handler_t::isEnabled()) && |
3525 | (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) && (gRlvHandler.isLockedAttachment(item, RLV_LOCK_REMOVE)) ) | ||
3526 | { | ||
3490 | disabled_items.push_back(std::string("Detach From Yourself")); | 3527 | disabled_items.push_back(std::string("Detach From Yourself")); |
3528 | } | ||
3491 | // [/RLVa:KB] | 3529 | // [/RLVa:KB] |
3492 | } | 3530 | } |
3493 | else | 3531 | else |
@@ -3500,13 +3538,16 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
3500 | items.push_back(std::string("RestoreToWorld Separator")); | 3538 | items.push_back(std::string("RestoreToWorld Separator")); |
3501 | items.push_back(std::string("Restore to Last Position")); | 3539 | items.push_back(std::string("Restore to Last Position")); |
3502 | 3540 | ||
3503 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0c | 3541 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
3504 | // Only enable "Wear" if there is an attach point name *and* there isn't a worn attachment there that's currently locked | 3542 | if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getEnableWear()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ) |
3505 | if ( (rlv_handler_t::isEnabled()) && (!RlvSettings::getEnableWear()) && (gRlvHandler.hasLockedAttachment()) ) | ||
3506 | { | 3543 | { |
3507 | LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(item, true); | 3544 | LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(item, true); // The item's name should specify |
3508 | if ( (!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt)) ) | 3545 | if ( (!pAttachPt) || // an attachment point that |
3546 | (gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) || // doesn't have an undetachable object | ||
3547 | (gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) // and that can be attached to | ||
3548 | { | ||
3509 | disabled_items.push_back(std::string("Object Wear")); | 3549 | disabled_items.push_back(std::string("Object Wear")); |
3550 | } | ||
3510 | } | 3551 | } |
3511 | // [/RLVa:KB] | 3552 | // [/RLVa:KB] |
3512 | 3553 | ||
@@ -3609,6 +3650,13 @@ LLUIImagePtr LLLSLTextBridge::getIcon() const | |||
3609 | 3650 | ||
3610 | void LLLSLTextBridge::openItem() | 3651 | void LLLSLTextBridge::openItem() |
3611 | { | 3652 | { |
3653 | // [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c | ||
3654 | if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) | ||
3655 | { | ||
3656 | return; | ||
3657 | } | ||
3658 | // [/RLVa:KB] | ||
3659 | |||
3612 | // See if we can bring an exiting preview to the front | 3660 | // See if we can bring an exiting preview to the front |
3613 | if(!LLPreview::show(mUUID)) | 3661 | if(!LLPreview::show(mUUID)) |
3614 | { | 3662 | { |
@@ -4050,15 +4098,26 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata ) | |||
4050 | is_gesture); | 4098 | is_gesture); |
4051 | S32 gest_count = gest_item_array.count(); | 4099 | S32 gest_count = gest_item_array.count(); |
4052 | 4100 | ||
4053 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-1.0.0c | 4101 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
4054 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) && (!RlvSettings::getEnableWear()) ) | 4102 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ) |
4055 | { | 4103 | { |
4056 | // Filter anything that doesn't specify an attachment point (or that specifies one that's currently locked) | 4104 | // Filter anything that we shouldn't be attaching |
4057 | for (S32 idxObj = obj_item_array.count() - 1; idxObj >= 0; idxObj--) | 4105 | for (S32 idxObj = obj_item_array.count() - 1; idxObj >= 0; idxObj--) |
4058 | { | 4106 | { |
4059 | LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(obj_item_array.get(idxObj).get(), true); | 4107 | if (!RlvSettings::getEnableWear()) |
4060 | if ( ((!pAttachPt) || (!gRlvHandler.isDetachable(pAttachPt))) ) | 4108 | { |
4061 | obj_item_array.remove(idxObj); | 4109 | LLViewerJointAttachment* pAttachPt = gRlvHandler.getAttachPoint(obj_item_array.get(idxObj).get(), true); |
4110 | if ( (!pAttachPt) || // Item should specify attachpt that | ||
4111 | (gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) || // doesn't have an undetachable object | ||
4112 | (gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) // and that is attachable | ||
4113 | { | ||
4114 | obj_item_array.remove(idxObj); | ||
4115 | } | ||
4116 | } | ||
4117 | else | ||
4118 | { | ||
4119 | gRlvHandler.onWearAttachment(obj_item_array.get(idxObj)->getUUID()); | ||
4120 | } | ||
4062 | } | 4121 | } |
4063 | obj_count = obj_item_array.count(); | 4122 | obj_count = obj_item_array.count(); |
4064 | } | 4123 | } |
@@ -4241,15 +4300,26 @@ void wear_attachments_on_avatar(const std::set<LLUUID>& item_ids, BOOL remove) | |||
4241 | { | 4300 | { |
4242 | if ( (gInventory.isObjectDescendentOf(*it, gAgent.getInventoryRootID())) ) | 4301 | if ( (gInventory.isObjectDescendentOf(*it, gAgent.getInventoryRootID())) ) |
4243 | { | 4302 | { |
4244 | // items.put(item); | 4303 | // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-10-15 (RLVa-1.0.5e) | Modified: RLVa-1.0.5e |
4245 | // [RLVa:KB] - Checked: 2009-09-11 (RLVa-1.0.2c) | Modified: RLVa-1.0.2c | 4304 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ) |
4246 | LLViewerJointAttachment* pAttachPt = NULL; | ||
4247 | if ( (!rlv_handler_t::isEnabled()) || (RlvSettings::getEnableWear()) || (!gRlvHandler.hasLockedAttachment()) || | ||
4248 | (((pAttachPt = gRlvHandler.getAttachPoint(item, true)) != NULL) && (gRlvHandler.isDetachable(pAttachPt))) ) | ||
4249 | { | 4305 | { |
4250 | items.put(item); | 4306 | if (!RlvSettings::getEnableWear()) |
4307 | { | ||
4308 | LLViewerJointAttachment* pAttachPt = NULL; | ||
4309 | if ( ((pAttachPt = gRlvHandler.getAttachPoint(item, true)) == NULL) || // Item should specify attachpt that | ||
4310 | (gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) || // doesn't have an undetachable object | ||
4311 | (gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) // and that is attachable | ||
4312 | { | ||
4313 | continue; | ||
4314 | } | ||
4315 | } | ||
4316 | else | ||
4317 | { | ||
4318 | gRlvHandler.onWearAttachment(item->getUUID()); | ||
4319 | } | ||
4251 | } | 4320 | } |
4252 | // [/RLVa:KB] | 4321 | // [/RLVa:KB] |
4322 | items.put(item); | ||
4253 | } | 4323 | } |
4254 | else if ( (item->isComplete()) ) | 4324 | else if ( (item->isComplete()) ) |
4255 | { | 4325 | { |
@@ -4309,9 +4379,9 @@ void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOO | |||
4309 | msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); | 4379 | msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); |
4310 | msg->addU8Fast(_PREHASH_TotalObjects, count ); | 4380 | msg->addU8Fast(_PREHASH_TotalObjects, count ); |
4311 | // msg->addBOOLFast(_PREHASH_FirstDetachAll, remove ); | 4381 | // msg->addBOOLFast(_PREHASH_FirstDetachAll, remove ); |
4312 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.2a | 4382 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
4313 | // This really should just *always* be FALSE since TRUE can result in loss of the current asset state | 4383 | // This really should just *always* be FALSE since TRUE can result in loss of the current asset state |
4314 | msg->addBOOLFast(_PREHASH_FirstDetachAll, remove && (!gRlvHandler.hasLockedAttachment()) ); | 4384 | msg->addBOOLFast(_PREHASH_FirstDetachAll, remove && (!gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ); |
4315 | // [/RLVa:KB] | 4385 | // [/RLVa:KB] |
4316 | } | 4386 | } |
4317 | 4387 | ||
@@ -4320,9 +4390,9 @@ void wear_attachments_on_avatar(const LLInventoryModel::item_array_t& items, BOO | |||
4320 | msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() ); | 4390 | msg->addUUIDFast(_PREHASH_ItemID, item->getUUID() ); |
4321 | msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); | 4391 | msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner()); |
4322 | // msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point | 4392 | // msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point |
4323 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.2a | 4393 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
4324 | msg->addU8Fast(_PREHASH_AttachmentPt, | 4394 | msg->addU8Fast(_PREHASH_AttachmentPt, |
4325 | ( (!rlv_handler_t::isEnabled()) || (RlvSettings::getEnableWear()) || (!gRlvHandler.hasLockedAttachment()) ) | 4395 | ( (!rlv_handler_t::isEnabled()) || (RlvSettings::getEnableWear()) || (!gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ) |
4326 | ? 0 | 4396 | ? 0 |
4327 | : gRlvHandler.getAttachPointIndex(gRlvHandler.getAttachPoint(item, true))); | 4397 | : gRlvHandler.getAttachPointIndex(gRlvHandler.getAttachPoint(item, true))); |
4328 | // [/RLVa:KB] | 4398 | // [/RLVa:KB] |
@@ -4428,13 +4498,12 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata) | |||
4428 | { | 4498 | { |
4429 | for(i = 0; i < obj_count; ++i) | 4499 | for(i = 0; i < obj_count; ++i) |
4430 | { | 4500 | { |
4431 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.2a | 4501 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
4432 | // TODO-RLVa: is there a reason why LL doesn't bother checking to see if you're actually wearing the object? | 4502 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) |
4433 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | ||
4434 | { | 4503 | { |
4435 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | 4504 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); |
4436 | if ( (!pAvatar) || (!pAvatar->isWearingAttachment(obj_item_array.get(i)->getUUID())) || | 4505 | if ( (!pAvatar) || (!pAvatar->isWearingAttachment(obj_item_array.get(i)->getUUID())) || |
4437 | (!gRlvHandler.isDetachable(obj_item_array.get(i).get())) ) // Why does LLPointer have a cast to BOOL aka S32??? | 4506 | (gRlvHandler.isLockedAttachment(obj_item_array.get(i).get(), RLV_LOCK_REMOVE)) ) |
4438 | { | 4507 | { |
4439 | continue; | 4508 | continue; |
4440 | } | 4509 | } |
diff --git a/linden/indra/newview/llpanelcontents.cpp b/linden/indra/newview/llpanelcontents.cpp index e13ec46..6462d44 100644 --- a/linden/indra/newview/llpanelcontents.cpp +++ b/linden/indra/newview/llpanelcontents.cpp | |||
@@ -121,11 +121,11 @@ void LLPanelContents::getState(LLViewerObject *objectp ) | |||
121 | && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 | 121 | && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488 |
122 | BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); | 122 | BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME ); |
123 | 123 | ||
124 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0g | 124 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
125 | if ( (rlv_handler_t::isEnabled()) && (editable) ) | 125 | if ( (rlv_handler_t::isEnabled()) && (editable) ) |
126 | { | 126 | { |
127 | // Don't allow creation of new scripts if it's undetachable | 127 | // Don't allow creation of new scripts if it's undetachable |
128 | editable = gRlvHandler.isDetachable(objectp); | 128 | editable = !gRlvHandler.isLockedAttachment(objectp, RLV_LOCK_REMOVE); |
129 | 129 | ||
130 | // Don't allow creation of new scripts if we're @unsit=n or @sittp=n restricted and we're sitting on the selection | 130 | // Don't allow creation of new scripts if we're @unsit=n or @sittp=n restricted and we're sitting on the selection |
131 | if ( (editable) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) | 131 | if ( (editable) && ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_SITTP))) ) |
@@ -182,10 +182,10 @@ void LLPanelContents::onClickNewScript(void *userdata) | |||
182 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); | 182 | LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject(children_ok); |
183 | if(object) | 183 | if(object) |
184 | { | 184 | { |
185 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 185 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) |
186 | if (rlv_handler_t::isEnabled()) // Fallback code [see LLPanelContents::getState()] | 186 | if (rlv_handler_t::isEnabled()) // Fallback code [see LLPanelContents::getState()] |
187 | { | 187 | { |
188 | if (!gRlvHandler.isDetachable(object)) | 188 | if (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) |
189 | { | 189 | { |
190 | return; // Disallow creating new scripts in a locked attachment | 190 | return; // Disallow creating new scripts in a locked attachment |
191 | } | 191 | } |
diff --git a/linden/indra/newview/llpanelinventory.cpp b/linden/indra/newview/llpanelinventory.cpp index 0ae2aec..d45b9d5 100644 --- a/linden/indra/newview/llpanelinventory.cpp +++ b/linden/indra/newview/llpanelinventory.cpp | |||
@@ -368,9 +368,9 @@ void LLTaskInvFVBridge::previewItem() | |||
368 | 368 | ||
369 | BOOL LLTaskInvFVBridge::isItemRenameable() const | 369 | BOOL LLTaskInvFVBridge::isItemRenameable() const |
370 | { | 370 | { |
371 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 371 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
372 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 372 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
373 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | 373 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) |
374 | { | 374 | { |
375 | return FALSE; | 375 | return FALSE; |
376 | } | 376 | } |
@@ -394,8 +394,8 @@ BOOL LLTaskInvFVBridge::isItemRenameable() const | |||
394 | BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name) | 394 | BOOL LLTaskInvFVBridge::renameItem(const std::string& new_name) |
395 | { | 395 | { |
396 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 396 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
397 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 397 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
398 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | 398 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) |
399 | { | 399 | { |
400 | return TRUE; // Fallback code [see LLTaskInvFVBridge::isItemRenameable()] | 400 | return TRUE; // Fallback code [see LLTaskInvFVBridge::isItemRenameable()] |
401 | } | 401 | } |
@@ -426,13 +426,13 @@ BOOL LLTaskInvFVBridge::isItemMovable() | |||
426 | // return TRUE; | 426 | // return TRUE; |
427 | //} | 427 | //} |
428 | //return FALSE; | 428 | //return FALSE; |
429 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0g | 429 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
430 | if (rlv_handler_t::isEnabled()) | 430 | if (rlv_handler_t::isEnabled()) |
431 | { | 431 | { |
432 | LLViewerObject* pObj = gObjectList.findObject(mPanel->getTaskUUID()); | 432 | LLViewerObject* pObj = gObjectList.findObject(mPanel->getTaskUUID()); |
433 | if (pObj) | 433 | if (pObj) |
434 | { | 434 | { |
435 | if (!gRlvHandler.isDetachable(pObj)) | 435 | if (gRlvHandler.isLockedAttachment(pObj, RLV_LOCK_REMOVE)) |
436 | { | 436 | { |
437 | return FALSE; | 437 | return FALSE; |
438 | } | 438 | } |
@@ -451,10 +451,10 @@ BOOL LLTaskInvFVBridge::isItemMovable() | |||
451 | BOOL LLTaskInvFVBridge::isItemRemovable() | 451 | BOOL LLTaskInvFVBridge::isItemRemovable() |
452 | { | 452 | { |
453 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 453 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
454 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0g | 454 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
455 | if ( (object) && (rlv_handler_t::isEnabled()) ) | 455 | if ( (object) && (rlv_handler_t::isEnabled()) ) |
456 | { | 456 | { |
457 | if (!gRlvHandler.isDetachable(object)) | 457 | if (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) |
458 | { | 458 | { |
459 | return FALSE; | 459 | return FALSE; |
460 | } | 460 | } |
@@ -611,9 +611,9 @@ BOOL LLTaskInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const | |||
611 | const LLPermissions& perm = inv->getPermissions(); | 611 | const LLPermissions& perm = inv->getPermissions(); |
612 | bool can_copy = gAgent.allowOperation(PERM_COPY, perm, | 612 | bool can_copy = gAgent.allowOperation(PERM_COPY, perm, |
613 | GP_OBJECT_MANIPULATE); | 613 | GP_OBJECT_MANIPULATE); |
614 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 614 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
615 | // Kind of redundant due to the note below, but in case that ever gets fixed | 615 | // Kind of redundant due to the note below, but in case that ever gets fixed |
616 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | 616 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) |
617 | { | 617 | { |
618 | return FALSE; | 618 | return FALSE; |
619 | } | 619 | } |
@@ -735,12 +735,16 @@ void LLTaskInvFVBridge::buildContextMenu(LLMenuGL& menu, U32 flags) | |||
735 | { | 735 | { |
736 | disabled_items.push_back(std::string("Task Open")); | 736 | disabled_items.push_back(std::string("Task Open")); |
737 | } | 737 | } |
738 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 738 | // [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c |
739 | else if ( (rlv_handler_t::isEnabled()) && | 739 | else if (rlv_handler_t::isEnabled()) |
740 | ((LLAssetType::AT_LSL_TEXT == item->getType()) || (LLAssetType::AT_NOTECARD == item->getType())) && | ||
741 | (!gRlvHandler.isDetachable(gObjectList.findObject(mPanel->getTaskUUID()))) ) | ||
742 | { | 740 | { |
743 | disabled_items.push_back(std::string("Task Open")); | 741 | bool fLocked = gRlvHandler.isLockedAttachment(gObjectList.findObject(mPanel->getTaskUUID()), RLV_LOCK_REMOVE); |
742 | if ( ((LLAssetType::AT_LSL_TEXT == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) || (fLocked))) || | ||
743 | ((LLAssetType::AT_NOTECARD == item->getType()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (fLocked))) || | ||
744 | ((LLAssetType::AT_NOTECARD == item->getType()) && (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE))) ) | ||
745 | { | ||
746 | disabled_items.push_back(std::string("Task Open")); | ||
747 | } | ||
744 | } | 748 | } |
745 | // [/RLVa:KB] | 749 | // [/RLVa:KB] |
746 | } | 750 | } |
@@ -967,6 +971,13 @@ LLUIImagePtr LLTaskTextureBridge::getIcon() const | |||
967 | 971 | ||
968 | void LLTaskTextureBridge::openItem() | 972 | void LLTaskTextureBridge::openItem() |
969 | { | 973 | { |
974 | // [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Added: RLVa-1.0.5c | ||
975 | if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE)) | ||
976 | { | ||
977 | return; | ||
978 | } | ||
979 | // [/RLVa:KB] | ||
980 | |||
970 | llinfos << "LLTaskTextureBridge::openItem()" << llendl; | 981 | llinfos << "LLTaskTextureBridge::openItem()" << llendl; |
971 | if(!LLPreview::show(mUUID)) | 982 | if(!LLPreview::show(mUUID)) |
972 | { | 983 | { |
@@ -1248,9 +1259,10 @@ LLTaskLSLBridge::LLTaskLSLBridge( | |||
1248 | 1259 | ||
1249 | void LLTaskLSLBridge::openItem() | 1260 | void LLTaskLSLBridge::openItem() |
1250 | { | 1261 | { |
1251 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 1262 | // [RLVa:KB] - Checked: 2009-10-13 (RLVa-1.0.5c) | Modified: RLVa-1.0.5c |
1252 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); | 1263 | LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID()); |
1253 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | 1264 | if ( (rlv_handler_t::isEnabled()) && |
1265 | ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWSCRIPT)) || (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE))) ) | ||
1254 | { | 1266 | { |
1255 | return; | 1267 | return; |
1256 | } | 1268 | } |
@@ -1376,8 +1388,9 @@ void LLTaskNotecardBridge::openItem() | |||
1376 | { | 1388 | { |
1377 | return; | 1389 | return; |
1378 | } | 1390 | } |
1379 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 1391 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
1380 | if ( (rlv_handler_t::isEnabled()) && ((gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (!gRlvHandler.isDetachable(object))) ) | 1392 | if ( (rlv_handler_t::isEnabled()) && |
1393 | ( (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWNOTE)) || (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) ) | ||
1381 | { | 1394 | { |
1382 | return; | 1395 | return; |
1383 | } | 1396 | } |
diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp index 6273011..69b6864 100644 --- a/linden/indra/newview/llpreviewscript.cpp +++ b/linden/indra/newview/llpreviewscript.cpp | |||
@@ -1989,8 +1989,8 @@ void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata ) | |||
1989 | LLCheckBoxCtrl* runningCheckbox = self->getChild<LLCheckBoxCtrl>("running"); | 1989 | LLCheckBoxCtrl* runningCheckbox = self->getChild<LLCheckBoxCtrl>("running"); |
1990 | BOOL running = runningCheckbox->get(); | 1990 | BOOL running = runningCheckbox->get(); |
1991 | //self->mRunningCheckbox->get(); | 1991 | //self->mRunningCheckbox->get(); |
1992 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 1992 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
1993 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | 1993 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) |
1994 | { | 1994 | { |
1995 | return; | 1995 | return; |
1996 | } | 1996 | } |
@@ -2020,8 +2020,8 @@ void LLLiveLSLEditor::onReset(void *userdata) | |||
2020 | LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; | 2020 | LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; |
2021 | 2021 | ||
2022 | LLViewerObject* object = gObjectList.findObject( self->mObjectID ); | 2022 | LLViewerObject* object = gObjectList.findObject( self->mObjectID ); |
2023 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 2023 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
2024 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(object)) ) | 2024 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(object, RLV_LOCK_REMOVE)) ) |
2025 | { | 2025 | { |
2026 | return; | 2026 | return; |
2027 | } | 2027 | } |
@@ -2448,8 +2448,8 @@ void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save) | |||
2448 | { | 2448 | { |
2449 | LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; | 2449 | LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; |
2450 | 2450 | ||
2451 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 2451 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
2452 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(gObjectList.findObject(self->mObjectID))) ) | 2452 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(gObjectList.findObject(self->mObjectID), RLV_LOCK_REMOVE)) ) |
2453 | { | 2453 | { |
2454 | return; | 2454 | return; |
2455 | } | 2455 | } |
diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index 178bde6..c0fa28c 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp | |||
@@ -1946,7 +1946,7 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL | |||
1946 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 1946 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
1947 | if (rlv_handler_t::isEnabled()) | 1947 | if (rlv_handler_t::isEnabled()) |
1948 | { | 1948 | { |
1949 | if (!gRlvHandler.isDetachable(obj)) | 1949 | if (gRlvHandler.isLockedAttachment(obj, RLV_LOCK_REMOVE)) |
1950 | { | 1950 | { |
1951 | return ACCEPT_NO_LOCKED; // Disallow inventory drops on a locked attachment | 1951 | return ACCEPT_NO_LOCKED; // Disallow inventory drops on a locked attachment |
1952 | } | 1952 | } |
@@ -2014,10 +2014,12 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( | |||
2014 | return ACCEPT_NO; | 2014 | return ACCEPT_NO; |
2015 | } | 2015 | } |
2016 | 2016 | ||
2017 | // [RLVa:KB] - Checked: 2009-09-08 (RLVa-1.0.2c) | Modified: RLVa-1.0.2c | 2017 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5) | Modified: RLVa-1.0.5 |
2018 | LLViewerJointAttachment* pAttachPt = NULL; | 2018 | LLViewerJointAttachment* pAttachPt = NULL; |
2019 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) && (!RlvSettings::getEnableWear()) && | 2019 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) && (!RlvSettings::getEnableWear()) && |
2020 | ( ((pAttachPt = gRlvHandler.getAttachPoint(item, true)) == NULL) || (!gRlvHandler.isDetachable(pAttachPt)) ) ) | 2020 | ( ((pAttachPt = gRlvHandler.getAttachPoint(item, true)) == NULL) || // Item should specify an attachpt that |
2021 | (gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) || // doesn't have an undetachable object | ||
2022 | (gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) ) // and that is attachable | ||
2021 | { | 2023 | { |
2022 | return ACCEPT_NO_LOCKED; | 2024 | return ACCEPT_NO_LOCKED; |
2023 | } | 2025 | } |
diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index 4b352a4..77d2509 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp | |||
@@ -676,8 +676,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) | |||
676 | } | 676 | } |
677 | 677 | ||
678 | // if(gUseWireframe) | 678 | // if(gUseWireframe) |
679 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 679 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
680 | if ( (gUseWireframe) && ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment()) ) ) | 680 | if ( (gUseWireframe) && ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) ) |
681 | // [/RLVa:KB] | 681 | // [/RLVa:KB] |
682 | { | 682 | { |
683 | glClearColor(0.5f, 0.5f, 0.5f, 0.f); | 683 | glClearColor(0.5f, 0.5f, 0.5f, 0.f); |
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 4732046..ecf6fcb 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp | |||
@@ -2146,8 +2146,9 @@ class LLSelfEnableRemoveAllAttachments : public view_listener_t | |||
2146 | LLVOAvatar::attachment_map_t::iterator curiter = iter++; | 2146 | LLVOAvatar::attachment_map_t::iterator curiter = iter++; |
2147 | LLViewerJointAttachment* attachment = curiter->second; | 2147 | LLViewerJointAttachment* attachment = curiter->second; |
2148 | // if (attachment->getObject()) | 2148 | // if (attachment->getObject()) |
2149 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0c | 2149 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
2150 | if ( (attachment->getObject()) && ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.isDetachable(curiter->first)) ) ) | 2150 | if ( (attachment->getObject()) && |
2151 | ((!rlv_handler_t::isEnabled()) || (!gRlvHandler.isLockedAttachment(curiter->first, RLV_LOCK_REMOVE))) ) | ||
2151 | // [/RLVa:KB] | 2152 | // [/RLVa:KB] |
2152 | { | 2153 | { |
2153 | new_value = true; | 2154 | new_value = true; |
@@ -2387,7 +2388,7 @@ class LLObjectImportUpload : public view_listener_t | |||
2387 | bool handle_go_to_confirm() | 2388 | bool handle_go_to_confirm() |
2388 | { | 2389 | { |
2389 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 2390 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
2390 | if ( (rlv_handler_t::isEnabled()) && gAgent.forwardGrabbed() && (gRlvHandler.hasLockedAttachment()) ) | 2391 | if ( (rlv_handler_t::isEnabled()) && (gAgent.forwardGrabbed()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) |
2391 | { | 2392 | { |
2392 | return true; | 2393 | return true; |
2393 | } | 2394 | } |
@@ -2410,12 +2411,12 @@ bool handle_go_to_confirm() | |||
2410 | 2411 | ||
2411 | bool handle_go_to() | 2412 | bool handle_go_to() |
2412 | { | 2413 | { |
2413 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 2414 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
2414 | if ( (rlv_handler_t::isEnabled()) && gAgent.forwardGrabbed() && (gRlvHandler.hasLockedAttachment()) ) | 2415 | if ( (rlv_handler_t::isEnabled()) && (gAgent.forwardGrabbed()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) |
2415 | { | 2416 | { |
2416 | return true; | 2417 | return true; |
2417 | } | 2418 | } |
2418 | // [/RLVa:KB] | 2419 | // [/RLVa:KB] |
2419 | 2420 | ||
2420 | handle_go_to_callback( 0, (void*)LLToolPie::getInstance() ); | 2421 | handle_go_to_callback( 0, (void*)LLToolPie::getInstance() ); |
2421 | 2422 | ||
@@ -4737,8 +4738,8 @@ class LLToolsReleaseKeys : public view_listener_t | |||
4737 | { | 4738 | { |
4738 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4739 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4739 | { | 4740 | { |
4740 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 4741 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
4741 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | 4742 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) |
4742 | { | 4743 | { |
4743 | return true; | 4744 | return true; |
4744 | } | 4745 | } |
@@ -4754,9 +4755,9 @@ class LLToolsEnableReleaseKeys : public view_listener_t | |||
4754 | { | 4755 | { |
4755 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 4756 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
4756 | { | 4757 | { |
4757 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 4758 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
4758 | gMenuHolder->findControl(userdata["control"].asString())->setValue( | 4759 | gMenuHolder->findControl(userdata["control"].asString())->setValue( |
4759 | gAgent.anyControlGrabbed() && ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment() ) ) ); | 4760 | gAgent.anyControlGrabbed() && ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE) ) ) ); |
4760 | // [/RLVa:KB] | 4761 | // [/RLVa:KB] |
4761 | //gMenuHolder->findControl(userdata["control"].asString())->setValue( gAgent.anyControlGrabbed() ); | 4762 | //gMenuHolder->findControl(userdata["control"].asString())->setValue( gAgent.anyControlGrabbed() ); |
4762 | return true; | 4763 | return true; |
@@ -6070,11 +6071,13 @@ private: | |||
6070 | if (index > 0) | 6071 | if (index > 0) |
6071 | attachment_point = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); | 6072 | attachment_point = get_if_there(gAgent.getAvatarObject()->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL); |
6072 | 6073 | ||
6073 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6074 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6074 | if ( (rlv_handler_t::isEnabled()) && | 6075 | if ( (rlv_handler_t::isEnabled()) && |
6075 | ( ((index == 0) && (gRlvHandler.hasLockedAttachment())) || // Can't wear on default attach point | 6076 | ( ((index == 0) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY))) || // Can't wear on default attach point |
6076 | ((index > 0) && (!gRlvHandler.isDetachable(attachment_point))) || // Can't replace locked attachment | 6077 | ((index > 0) && // or replace a locked attachment |
6077 | (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) ) // Attach on rezzed object == "Take" | 6078 | ((gRlvHandler.isLockedAttachment(attachment_point->getObject(), RLV_LOCK_REMOVE)) || |
6079 | (gRlvHandler.isLockedAttachment(attachment_point, RLV_LOCK_ADD)) ) ) || // or wear on a non-attachable attach point | ||
6080 | (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) ) // Attach on rezzed object == "Take" | ||
6078 | { | 6081 | { |
6079 | setObjectSelection(NULL); // Clear the selection or it'll get stuck | 6082 | setObjectSelection(NULL); // Clear the selection or it'll get stuck |
6080 | return true; | 6083 | return true; |
@@ -6188,15 +6191,15 @@ class LLAttachmentDrop : public view_listener_t | |||
6188 | return true; | 6191 | return true; |
6189 | } | 6192 | } |
6190 | 6193 | ||
6191 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6194 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6192 | if (rlv_handler_t::isEnabled()) | 6195 | if (rlv_handler_t::isEnabled()) |
6193 | { | 6196 | { |
6194 | if (gRlvHandler.hasLockedAttachment()) | 6197 | if (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) |
6195 | { | 6198 | { |
6196 | // NOTE: copy/paste of the code in enable_detach() | 6199 | // NOTE: copy/paste of the code in enable_detach() |
6197 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); | 6200 | LLObjectSelectionHandle hSelection = LLSelectMgr::getInstance()->getSelection(); |
6198 | RlvSelectHasLockedAttach functor; | 6201 | RlvSelectHasLockedAttach functor(RLV_LOCK_REMOVE); |
6199 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) | 6202 | if ( (hSelection->isAttachment()) && (hSelection->getFirstRootNode(&functor, FALSE)) ) |
6200 | return true; | 6203 | return true; |
6201 | } | 6204 | } |
6202 | else if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) | 6205 | else if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) |
@@ -6224,8 +6227,8 @@ void handle_detach_from_avatar(void* user_data) | |||
6224 | 6227 | ||
6225 | if (attached_object) | 6228 | if (attached_object) |
6226 | { | 6229 | { |
6227 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-0.2.0d | 6230 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6228 | if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isDetachable(attached_object)) ) | 6231 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.isLockedAttachment(attached_object, RLV_LOCK_REMOVE)) ) |
6229 | { | 6232 | { |
6230 | return; | 6233 | return; |
6231 | } | 6234 | } |
@@ -6313,12 +6316,12 @@ class LLAttachmentDetach : public view_listener_t | |||
6313 | return true; | 6316 | return true; |
6314 | } | 6317 | } |
6315 | 6318 | ||
6316 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6319 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5) | Modified: RLVa-1.0.5 |
6317 | // NOTE: copy/paste of the code in enable_detach() | 6320 | // NOTE: copy/paste of the code in enable_detach() |
6318 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | 6321 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) |
6319 | { | 6322 | { |
6320 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); | 6323 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); |
6321 | RlvSelectHasLockedAttach functor; | 6324 | RlvSelectHasLockedAttach functor(RLV_LOCK_REMOVE); |
6322 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) | 6325 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) |
6323 | return FALSE; | 6326 | return FALSE; |
6324 | } | 6327 | } |
@@ -6431,16 +6434,16 @@ BOOL enable_detach(void*) | |||
6431 | // ...if it's you, good to detach | 6434 | // ...if it's you, good to detach |
6432 | if (avatar->getID() == gAgent.getID()) | 6435 | if (avatar->getID() == gAgent.getID()) |
6433 | { | 6436 | { |
6434 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6437 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5) | Modified: RLVa-1.0.5 |
6435 | // NOTE: this code is reused as-is in LLAttachmentDetach::handleEvent() and LLAttachmentDrop::handleEvent() | 6438 | // NOTE: this code is reused as-is in LLAttachmentDetach::handleEvent() and LLAttachmentDrop::handleEvent() |
6436 | // so any changes here should be reflected there as well (I think it's in a number of other places as well by now) | 6439 | // so any changes here should be reflected there as well |
6437 | 6440 | ||
6438 | // RELEASE-RLVa: LLSelectMgr::sendDetach() and LLSelectMgr::sendDropAttachment() call sendListToRegions with | 6441 | // RELEASE-RLVa: LLSelectMgr::sendDetach() and LLSelectMgr::sendDropAttachment() call sendListToRegions with |
6439 | // SEND_ONLY_ROOTS so we only need to examine the roots which saves us time | 6442 | // SEND_ONLY_ROOTS so we only need to examine the roots which saves us time |
6440 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | 6443 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) |
6441 | { | 6444 | { |
6442 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); | 6445 | LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection(); |
6443 | RlvSelectHasLockedAttach functor; | 6446 | RlvSelectHasLockedAttach functor(RLV_LOCK_REMOVE); |
6444 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) | 6447 | if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&functor, FALSE)) ) |
6445 | return FALSE; | 6448 | return FALSE; |
6446 | } | 6449 | } |
@@ -6467,7 +6470,7 @@ class LLAttachmentEnableDetach : public view_listener_t | |||
6467 | // Used to tell if the selected object can be attached to your avatar. | 6470 | // Used to tell if the selected object can be attached to your avatar. |
6468 | BOOL object_selected_and_point_valid(void *user_data) | 6471 | BOOL object_selected_and_point_valid(void *user_data) |
6469 | { | 6472 | { |
6470 | // [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | 6473 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5) | Modified: RLVa-1.0.5 |
6471 | if (rlv_handler_t::isEnabled()) | 6474 | if (rlv_handler_t::isEnabled()) |
6472 | { | 6475 | { |
6473 | // RELEASE-RLVa: look at the caller graph for this function on every new release | 6476 | // RELEASE-RLVa: look at the caller graph for this function on every new release |
@@ -6477,9 +6480,11 @@ BOOL object_selected_and_point_valid(void *user_data) | |||
6477 | // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / right-click / "Attach >" [user_data == pAttachPt] | 6480 | // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / right-click / "Attach >" [user_data == pAttachPt] |
6478 | // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / Edit menu / "Attach Object" [user_data == pAttachPt] | 6481 | // - enabler set up in LLVOAvatar::buildCharacter() => Rezzed prim / Edit menu / "Attach Object" [user_data == pAttachPt] |
6479 | LLViewerJointAttachment* pAttachPt = (LLViewerJointAttachment*)user_data; | 6482 | LLViewerJointAttachment* pAttachPt = (LLViewerJointAttachment*)user_data; |
6480 | if ( ((!pAttachPt) && (gRlvHandler.hasLockedAttachment())) || // Don't allow attach to default attach point | 6483 | if ( ( (!pAttachPt) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) ) || // Don't allow attach to default attach point |
6481 | ((pAttachPt) && (!gRlvHandler.isDetachable(pAttachPt))) || // Don't allow replacing of locked attachment | 6484 | ( (pAttachPt) && // Don't allow replacing of a locked attachment |
6482 | (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) // Attaching a rezzed object == "Take" | 6485 | ( (gRlvHandler.isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) || |
6486 | (gRlvHandler.isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) ) || // or wear on a non-attachable attach point | ||
6487 | (gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) // Attaching a rezzed object == "Take" | ||
6483 | { | 6488 | { |
6484 | return FALSE; | 6489 | return FALSE; |
6485 | } | 6490 | } |
@@ -6556,7 +6561,7 @@ BOOL object_attached(void *user_data) | |||
6556 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6561 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) |
6557 | return ( | 6562 | return ( |
6558 | (attachment->getObject() != NULL) && | 6563 | (attachment->getObject() != NULL) && |
6559 | ( (!rlv_handler_t::isEnabled()) || (gRlvHandler.isDetachable(attachment->getObject())) ) | 6564 | ( (!rlv_handler_t::isEnabled()) || (!gRlvHandler.isLockedAttachment(attachment->getObject(), RLV_LOCK_REMOVE)) ) |
6560 | ); | 6565 | ); |
6561 | // [/RLVa:KB] | 6566 | // [/RLVa:KB] |
6562 | // return attachment->getObject() != NULL; | 6567 | // return attachment->getObject() != NULL; |
@@ -6708,12 +6713,13 @@ class LLToolsSelectedScriptAction : public view_listener_t | |||
6708 | { | 6713 | { |
6709 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) | 6714 | bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) |
6710 | { | 6715 | { |
6711 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6716 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6712 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | 6717 | // We'll allow resetting the scripts of objects on a non-attachable attach point since they wouldn't be able to circumvent anything |
6718 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) | ||
6713 | { | 6719 | { |
6714 | LLObjectSelectionHandle selectHandle = LLSelectMgr::getInstance()->getSelection(); | 6720 | LLObjectSelectionHandle hSelection = LLSelectMgr::getInstance()->getSelection(); |
6715 | RlvSelectHasLockedAttach functor; | 6721 | RlvSelectHasLockedAttach functor(RLV_LOCK_REMOVE); |
6716 | if ( (selectHandle->isAttachment()) && (selectHandle->getFirstNode(&functor)) ) | 6722 | if ( (hSelection->isAttachment()) && (hSelection->getFirstNode(&functor)) ) |
6717 | return true; | 6723 | return true; |
6718 | } | 6724 | } |
6719 | // [/RLVa:KB] | 6725 | // [/RLVa:KB] |
@@ -6802,9 +6808,9 @@ void handle_dump_image_list(void*) | |||
6802 | 6808 | ||
6803 | void handle_test_male(void*) | 6809 | void handle_test_male(void*) |
6804 | { | 6810 | { |
6805 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6811 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6806 | if ( (rlv_handler_t::isEnabled()) && | 6812 | if ( (rlv_handler_t::isEnabled()) && |
6807 | ( (gRlvHandler.hasLockedAttachment()) || | 6813 | ( (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) || |
6808 | (gRlvHandler.hasBehaviour(RLV_BHVR_ADDOUTFIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REMOUTFIT)) ) ) | 6814 | (gRlvHandler.hasBehaviour(RLV_BHVR_ADDOUTFIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REMOUTFIT)) ) ) |
6809 | { | 6815 | { |
6810 | return; | 6816 | return; |
@@ -6817,9 +6823,9 @@ void handle_test_male(void*) | |||
6817 | 6823 | ||
6818 | void handle_test_female(void*) | 6824 | void handle_test_female(void*) |
6819 | { | 6825 | { |
6820 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 6826 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6821 | if ( (rlv_handler_t::isEnabled()) && | 6827 | if ( (rlv_handler_t::isEnabled()) && |
6822 | ( (gRlvHandler.hasLockedAttachment()) || | 6828 | ( (gRlvHandler.hasLockedAttachment(RLV_LOCK_ANY)) || |
6823 | (gRlvHandler.hasBehaviour(RLV_BHVR_ADDOUTFIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REMOUTFIT)) ) ) | 6829 | (gRlvHandler.hasBehaviour(RLV_BHVR_ADDOUTFIT)) || (gRlvHandler.hasBehaviour(RLV_BHVR_REMOUTFIT)) ) ) |
6824 | { | 6830 | { |
6825 | return; | 6831 | return; |
@@ -6968,16 +6974,16 @@ BOOL enable_more_than_one_selected(void* ) | |||
6968 | 6974 | ||
6969 | static bool is_editable_selected() | 6975 | static bool is_editable_selected() |
6970 | { | 6976 | { |
6971 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Modified: RLVa-1.0.0c | 6977 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6972 | // RELEASE-RLVa: check that this still isn't called by anything but script actions in the Tools menu | 6978 | // RELEASE-RLVa: check that this still isn't called by anything but script actions in the Tools menu |
6973 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment()) ) | 6979 | if ( (rlv_handler_t::isEnabled()) && (gRlvHandler.hasLockedAttachment(RLV_LOCK_REMOVE)) ) |
6974 | { | 6980 | { |
6975 | LLObjectSelectionHandle selectHandle = LLSelectMgr::getInstance()->getSelection(); | 6981 | LLObjectSelectionHandle hSelection = LLSelectMgr::getInstance()->getSelection(); |
6976 | 6982 | ||
6977 | // NOTE: this is called for 5 different menu items so we'll trade accuracy for efficiency and only | 6983 | // NOTE: this is called for 5 different menu items so we'll trade accuracy for efficiency and only |
6978 | // examine root nodes (LLToolsSelectedScriptAction::handleEvent() will catch what we miss) | 6984 | // examine root nodes (LLToolsSelectedScriptAction::handleEvent() will catch what we miss) |
6979 | RlvSelectHasLockedAttach functor; | 6985 | RlvSelectHasLockedAttach functor(RLV_LOCK_REMOVE); |
6980 | if ( (selectHandle->isAttachment()) && (selectHandle->getFirstRootNode(&functor)) ) | 6986 | if ( (hSelection->isAttachment()) && (hSelection->getFirstRootNode(&functor)) ) |
6981 | { | 6987 | { |
6982 | return false; | 6988 | return false; |
6983 | } | 6989 | } |
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp index 8f4a944..c8b8fec 100644 --- a/linden/indra/newview/llviewertexteditor.cpp +++ b/linden/indra/newview/llviewertexteditor.cpp | |||
@@ -1364,6 +1364,13 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLInventoryItem* item) | |||
1364 | 1364 | ||
1365 | void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item ) | 1365 | void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item ) |
1366 | { | 1366 | { |
1367 | // [RLVa:KB] - Version: 1.22.11 | Checked: 2009-10-13 (RLVa-1.0.5c) | Added: RLVa-1.0.5c | ||
1368 | if (gRlvHandler.hasBehaviour(RLV_BHVR_VIEWTEXTURE)) | ||
1369 | { | ||
1370 | return; | ||
1371 | } | ||
1372 | // [/RLVa:KB] | ||
1373 | |||
1367 | // See if we can bring an existing preview to the front | 1374 | // See if we can bring an existing preview to the front |
1368 | // *NOTE: Just for embedded Texture , we should use getAssetUUID(), | 1375 | // *NOTE: Just for embedded Texture , we should use getAssetUUID(), |
1369 | // not getUUID(), because LLPreviewTexture pass in AssetUUID into | 1376 | // not getUUID(), because LLPreviewTexture pass in AssetUUID into |
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 4ab14f4..df07701 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp | |||
@@ -6451,37 +6451,10 @@ BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) | |||
6451 | { | 6451 | { |
6452 | updateAttachmentVisibility(gAgent.getCameraMode()); | 6452 | updateAttachmentVisibility(gAgent.getCameraMode()); |
6453 | 6453 | ||
6454 | // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | 6454 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
6455 | if (rlv_handler_t::isEnabled()) | 6455 | if (rlv_handler_t::isEnabled()) |
6456 | { | 6456 | { |
6457 | static bool fRlvFullyLoaded = false; | 6457 | gRlvHandler.onAttach(attachment); |
6458 | static LLFrameTimer* pRlvFullyLoadedTimer = NULL; | ||
6459 | |||
6460 | // There's no way to know when we're done reattaching what was attached at log-off but this ugly evil bad hack tries anyway | ||
6461 | if (!fRlvFullyLoaded) | ||
6462 | { | ||
6463 | if (pRlvFullyLoadedTimer) | ||
6464 | { | ||
6465 | if (pRlvFullyLoadedTimer->getElapsedTimeF32() > 30.0f) | ||
6466 | { | ||
6467 | fRlvFullyLoaded = true; | ||
6468 | delete pRlvFullyLoadedTimer; | ||
6469 | pRlvFullyLoadedTimer = NULL; | ||
6470 | } | ||
6471 | else | ||
6472 | { | ||
6473 | pRlvFullyLoadedTimer->reset(); | ||
6474 | } | ||
6475 | } | ||
6476 | else if ( (!pRlvFullyLoadedTimer) && | ||
6477 | ( (0 == mPendingAttachment.size()) || | ||
6478 | ((1 == mPendingAttachment.size()) && (mPendingAttachment[0] == viewer_object)) ) ) | ||
6479 | { | ||
6480 | pRlvFullyLoadedTimer = new LLFrameTimer(); | ||
6481 | } | ||
6482 | } | ||
6483 | |||
6484 | gRlvHandler.onAttach(attachment, fRlvFullyLoaded); | ||
6485 | } | 6458 | } |
6486 | // [/RLVa:KB] | 6459 | // [/RLVa:KB] |
6487 | 6460 | ||
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index adf82cd..7b151e8 100644 --- a/linden/indra/newview/llvovolume.cpp +++ b/linden/indra/newview/llvovolume.cpp | |||
@@ -1943,9 +1943,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e | |||
1943 | { | 1943 | { |
1944 | if (!mbCanSelect || | 1944 | if (!mbCanSelect || |
1945 | // (gHideSelectedObjects && isSelected()) || | 1945 | // (gHideSelectedObjects && isSelected()) || |
1946 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 1946 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
1947 | ( (gHideSelectedObjects && isSelected()) && | 1947 | ( (gHideSelectedObjects && isSelected()) && |
1948 | ((!rlv_handler_t::isEnabled()) || (!isHUDAttachment()) || (gRlvHandler.isDetachable(this))) ) || | 1948 | ((!rlv_handler_t::isEnabled()) || (!isHUDAttachment()) || (!gRlvHandler.isLockedAttachment(this, RLV_LOCK_REMOVE))) ) || |
1949 | // [/RLVa:KB] | 1949 | // [/RLVa:KB] |
1950 | mDrawable->isDead() || | 1950 | mDrawable->isDead() || |
1951 | !gPipeline.hasRenderType(mDrawable->getRenderType())) | 1951 | !gPipeline.hasRenderType(mDrawable->getRenderType())) |
@@ -2092,10 +2092,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, | |||
2092 | // { | 2092 | // { |
2093 | // return; | 2093 | // return; |
2094 | // } | 2094 | // } |
2095 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 2095 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
2096 | LLViewerObject* pObj = facep->getViewerObject(); | 2096 | LLViewerObject* pObj = facep->getViewerObject(); |
2097 | if ( (pObj->isSelected() && gHideSelectedObjects) && | 2097 | if ( (pObj->isSelected() && gHideSelectedObjects) && |
2098 | ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (gRlvHandler.isDetachable(pObj))) ) | 2098 | ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (!gRlvHandler.isLockedAttachment(pObj, RLV_LOCK_REMOVE))) ) |
2099 | { | 2099 | { |
2100 | return; | 2100 | return; |
2101 | } | 2101 | } |
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index efb5ff6..bf7799c 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -1797,10 +1797,10 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) | |||
1797 | { | 1797 | { |
1798 | // if (drawablep->getVObj().notNull() && | 1798 | // if (drawablep->getVObj().notNull() && |
1799 | // drawablep->getVObj()->isSelected()) | 1799 | // drawablep->getVObj()->isSelected()) |
1800 | // [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | 1800 | // [RLVa:KB] - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
1801 | LLViewerObject* pObj = drawablep->getVObj(); | 1801 | LLViewerObject* pObj = drawablep->getVObj(); |
1802 | if ( (pObj) && (pObj->isSelected()) && | 1802 | if ( (pObj) && (pObj->isSelected()) && |
1803 | ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (gRlvHandler.isDetachable(pObj))) ) | 1803 | ((!rlv_handler_t::isEnabled()) || (!pObj->isHUDAttachment()) || (!gRlvHandler.isLockedAttachment(pObj, RLV_LOCK_REMOVE))) ) |
1804 | // [/RVLa:KB] | 1804 | // [/RVLa:KB] |
1805 | { | 1805 | { |
1806 | return; | 1806 | return; |
diff --git a/linden/indra/newview/rlvdefines.h b/linden/indra/newview/rlvdefines.h index 118ba31..a35d109 100644 --- a/linden/indra/newview/rlvdefines.h +++ b/linden/indra/newview/rlvdefines.h | |||
@@ -41,14 +41,14 @@ | |||
41 | 41 | ||
42 | // Version of the specifcation we support | 42 | // Version of the specifcation we support |
43 | const S32 RLV_VERSION_MAJOR = 1; | 43 | const S32 RLV_VERSION_MAJOR = 1; |
44 | const S32 RLV_VERSION_MINOR = 21; | 44 | const S32 RLV_VERSION_MINOR = 22; |
45 | const S32 RLV_VERSION_PATCH = 0; | 45 | const S32 RLV_VERSION_PATCH = 0; |
46 | const S32 RLV_VERSION_BUILD = 0; | 46 | const S32 RLV_VERSION_BUILD = 0; |
47 | 47 | ||
48 | // Implementation version | 48 | // Implementation version |
49 | const S32 RLVa_VERSION_MAJOR = 1; | 49 | const S32 RLVa_VERSION_MAJOR = 1; |
50 | const S32 RLVa_VERSION_MINOR = 0; | 50 | const S32 RLVa_VERSION_MINOR = 0; |
51 | const S32 RLVa_VERSION_PATCH = 4; | 51 | const S32 RLVa_VERSION_PATCH = 5; |
52 | const S32 RLVa_VERSION_BUILD = 4; | 52 | const S32 RLVa_VERSION_BUILD = 4; |
53 | 53 | ||
54 | // The official viewer version we're patching against | 54 | // The official viewer version we're patching against |
@@ -59,12 +59,15 @@ const S32 RLVa_VERSION_BUILD = 4; | |||
59 | #define RLV_WARNS LL_WARNS("RLV") | 59 | #define RLV_WARNS LL_WARNS("RLV") |
60 | #define RLV_INFOS LL_INFOS("RLV") | 60 | #define RLV_INFOS LL_INFOS("RLV") |
61 | #define RLV_DEBUGS LL_DEBUGS("RLV") | 61 | #define RLV_DEBUGS LL_DEBUGS("RLV") |
62 | #define RLV_ENDL LL_ENDL | ||
62 | 63 | ||
63 | #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | 64 | #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG |
64 | // Turn on extended debugging information | 65 | // Turn on extended debugging information |
65 | #define RLV_DEBUG | 66 | #define RLV_DEBUG |
66 | // Make sure we halt execution on errors | 67 | // Make sure we halt execution on errors |
67 | #define RLV_ERRS LL_ERRS("RLV") | 68 | #define RLV_ERRS LL_ERRS("RLV") |
69 | // Keep our asserts separate from LL's | ||
70 | #define RLV_ASSERT(f) if (!(f)) RLV_ERRS << "ASSERT (" << #f << ")" << RLV_ENDL; | ||
68 | // Uncomment to enable the Advanced / RLVa / Unit Tests menu (non-public) | 71 | // Uncomment to enable the Advanced / RLVa / Unit Tests menu (non-public) |
69 | //#define RLV_DEBUG_TESTS | 72 | //#define RLV_DEBUG_TESTS |
70 | #else | 73 | #else |
@@ -72,6 +75,8 @@ const S32 RLVa_VERSION_BUILD = 4; | |||
72 | //#define RLV_DEBUG | 75 | //#define RLV_DEBUG |
73 | // Don't halt execution on errors in release | 76 | // Don't halt execution on errors in release |
74 | #define RLV_ERRS LL_WARNS("RLV") | 77 | #define RLV_ERRS LL_WARNS("RLV") |
78 | // We don't want to check assertions in release builds | ||
79 | #define RLV_ASSERT(f) | ||
75 | #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG | 80 | #endif // LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG |
76 | 81 | ||
77 | #define RLV_ROOT_FOLDER "#RLV" | 82 | #define RLV_ROOT_FOLDER "#RLV" |
@@ -111,6 +116,8 @@ enum ERlvBehaviour { | |||
111 | RLV_BHVR_ADDOUTFIT, // "addoutfit" | 116 | RLV_BHVR_ADDOUTFIT, // "addoutfit" |
112 | RLV_BHVR_REMOUTFIT, // "remoutfit" | 117 | RLV_BHVR_REMOUTFIT, // "remoutfit" |
113 | RLV_BHVR_GETOUTFIT, // "getoutfit" | 118 | RLV_BHVR_GETOUTFIT, // "getoutfit" |
119 | RLV_BHVR_ADDATTACH, // "addattach" | ||
120 | RLV_BHVR_REMATTACH, // "remattach" | ||
114 | RLV_BHVR_GETATTACH, // "getattach" | 121 | RLV_BHVR_GETATTACH, // "getattach" |
115 | RLV_BHVR_SHOWINV, // "showinv" | 122 | RLV_BHVR_SHOWINV, // "showinv" |
116 | RLV_BHVR_VIEWNOTE, // "viewnote" | 123 | RLV_BHVR_VIEWNOTE, // "viewnote" |
@@ -152,6 +159,8 @@ enum ERlvBehaviour { | |||
152 | RLV_BHVR_DEFAULTWEAR, // "defaultwear" | 159 | RLV_BHVR_DEFAULTWEAR, // "defaultwear" |
153 | RLV_BHVR_VERSIONNUM, // "versionnum" | 160 | RLV_BHVR_VERSIONNUM, // "versionnum" |
154 | RLV_BHVR_PERMISSIVE, // "permissive" | 161 | RLV_BHVR_PERMISSIVE, // "permissive" |
162 | RLV_BHVR_VIEWSCRIPT, // "viewscript" | ||
163 | RLV_BHVR_VIEWTEXTURE, // "viewtexture" | ||
155 | 164 | ||
156 | RLV_BHVR_COUNT, | 165 | RLV_BHVR_COUNT, |
157 | RLV_BHVR_UNKNOWN | 166 | RLV_BHVR_UNKNOWN |
@@ -185,6 +194,12 @@ enum ERlvExceptionCheck { | |||
185 | RLV_CHECK_DEFAULT // Permissive or strict will be determined by currently enforced restrictions | 194 | RLV_CHECK_DEFAULT // Permissive or strict will be determined by currently enforced restrictions |
186 | }; | 195 | }; |
187 | 196 | ||
197 | enum ERlvLockMask { | ||
198 | RLV_LOCK_ADD = 0x01, | ||
199 | RLV_LOCK_REMOVE = 0x02, | ||
200 | RLV_LOCK_ANY = RLV_LOCK_ADD | RLV_LOCK_REMOVE | ||
201 | }; | ||
202 | |||
188 | // ============================================================================ | 203 | // ============================================================================ |
189 | // Settings | 204 | // Settings |
190 | 205 | ||
diff --git a/linden/indra/newview/rlvextensions.cpp b/linden/indra/newview/rlvextensions.cpp index f31c62e..769d3cc 100644 --- a/linden/indra/newview/rlvextensions.cpp +++ b/linden/indra/newview/rlvextensions.cpp | |||
@@ -97,7 +97,7 @@ BOOL RlvExtGetSet::processCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) | |||
97 | F32 nAngle = 0.0f; | 97 | F32 nAngle = 0.0f; |
98 | if (LLStringUtil::convertToF32(rlvCmd.getOption(), nAngle)) | 98 | if (LLStringUtil::convertToF32(rlvCmd.getOption(), nAngle)) |
99 | { | 99 | { |
100 | nAngle += RLV_SETROT_OFFSET; | 100 | nAngle = RLV_SETROT_OFFSET - nAngle; |
101 | 101 | ||
102 | gAgent.startCameraAnimation(); | 102 | gAgent.startCameraAnimation(); |
103 | 103 | ||
diff --git a/linden/indra/newview/rlvhandler.cpp b/linden/indra/newview/rlvhandler.cpp index 69e2e2f..88cd174 100644 --- a/linden/indra/newview/rlvhandler.cpp +++ b/linden/indra/newview/rlvhandler.cpp | |||
@@ -31,11 +31,6 @@ | |||
31 | #include "rlvextensions.h" | 31 | #include "rlvextensions.h" |
32 | #include "rlvhandler.h" | 32 | #include "rlvhandler.h" |
33 | 33 | ||
34 | // Only defined in llinventorybridge.cpp | ||
35 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
36 | #include "llinventorybridge.h" | ||
37 | void confirm_replace_attachment_rez(S32 option, void* user_data); | ||
38 | #endif | ||
39 | // Only defined in llinventorymodel.cpp | 34 | // Only defined in llinventorymodel.cpp |
40 | extern const char* NEW_CATEGORY_NAME; | 35 | extern const char* NEW_CATEGORY_NAME; |
41 | 36 | ||
@@ -66,8 +61,8 @@ const std::string RlvHandler::cstrMsgTpLure = | |||
66 | const std::string RlvHandler::cstrAnonyms[] = | 61 | const std::string RlvHandler::cstrAnonyms[] = |
67 | { | 62 | { |
68 | "A resident", "This resident", "That resident", "An individual", "This individual", "That individual", "A person", | 63 | "A resident", "This resident", "That resident", "An individual", "This individual", "That individual", "A person", |
69 | "This person", "That person", "A stranger", "This stranger", "That stranger", "A human being", "This human being", | 64 | "This person", "That person", "A stranger", "This stranger", "That stranger", "A being", "This being", |
70 | "That human being", "An agent", "This agent", "That agent", "A soul", "This soul", "That soul", "Somebody", | 65 | "That being", "An agent", "This agent", "That agent", "A soul", "This soul", "That soul", "Somebody", |
71 | "Some people", "Someone", "Mysterious one", "An unknown being", "Unidentified one", "An unknown person" | 66 | "Some people", "Someone", "Mysterious one", "An unknown being", "Unidentified one", "An unknown person" |
72 | }; | 67 | }; |
73 | 68 | ||
@@ -131,6 +126,7 @@ RlvHandler::~RlvHandler() | |||
131 | //delete m_pGCTimer; // <- deletes itself | 126 | //delete m_pGCTimer; // <- deletes itself |
132 | delete m_pWLSnapshot; // <- delete on NULL is harmless | 127 | delete m_pWLSnapshot; // <- delete on NULL is harmless |
133 | delete m_pBhvrNotify; | 128 | delete m_pBhvrNotify; |
129 | delete m_pAttachMgr; | ||
134 | } | 130 | } |
135 | 131 | ||
136 | // ============================================================================ | 132 | // ============================================================================ |
@@ -246,7 +242,7 @@ bool RlvHandler::hasLockedHUD() const | |||
246 | return false; | 242 | return false; |
247 | 243 | ||
248 | LLViewerJointAttachment* pAttachPt; | 244 | LLViewerJointAttachment* pAttachPt; |
249 | for (rlv_detach_map_t::const_iterator itAttachPt = m_Attachments.begin(); itAttachPt != m_Attachments.end(); ++itAttachPt) | 245 | for (rlv_attachlock_map_t::const_iterator itAttachPt = m_AttachRem.begin(); itAttachPt != m_AttachRem.end(); ++itAttachPt) |
250 | { | 246 | { |
251 | pAttachPt = get_if_there(pAvatar->mAttachmentPoints, (S32)itAttachPt->first, (LLViewerJointAttachment*)NULL); | 247 | pAttachPt = get_if_there(pAvatar->mAttachmentPoints, (S32)itAttachPt->first, (LLViewerJointAttachment*)NULL); |
252 | if ( (pAttachPt) && (pAttachPt->getIsHUDAttachment()) ) | 248 | if ( (pAttachPt) && (pAttachPt->getIsHUDAttachment()) ) |
@@ -255,61 +251,94 @@ bool RlvHandler::hasLockedHUD() const | |||
255 | return false; // None of our locked attachments is a HUD | 251 | return false; // None of our locked attachments is a HUD |
256 | } | 252 | } |
257 | 253 | ||
258 | bool RlvHandler::isDetachable(const LLInventoryItem* pItem) const | 254 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
255 | bool RlvHandler::isLockedAttachment(const LLInventoryItem* pItem, ERlvLockMask eLock) const | ||
259 | { | 256 | { |
260 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | 257 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); |
261 | return ( (pItem) && (pAvatar) ) ? isDetachable(pAvatar->getWornAttachment(pItem->getUUID())) : true; | 258 | return (pItem) && (pAvatar) && (isLockedAttachment(pAvatar->getWornAttachment(pItem->getUUID()), eLock)); |
262 | } | 259 | } |
263 | 260 | ||
264 | // Checked: 2009-08-11 (RLVa-1.0.1h) | Added: RLVa-1.0.1h | 261 | // Checked: 2009-10-13 (RLVa-1.0.5b) | Added: RLVa-1.0.5b |
265 | bool RlvHandler::isDetachableExcept(S32 idxAttachPt, LLViewerObject *pObj) const | 262 | bool RlvHandler::isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, LLViewerObject *pObj) const |
266 | { | 263 | { |
267 | // Loop over every object that marked the specific attachment point undetachable (but ignore pObj and any of its children) | 264 | // Loop over every object that marked the specific attachment point eLock type locked (but ignore pObj and any of its children) |
268 | for (rlv_detach_map_t::const_iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | 265 | LLViewerObject* pTempObj; |
269 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | 266 | if (eLock & RLV_LOCK_REMOVE) |
270 | { | 267 | { |
271 | LLViewerObject* pTempObj = gObjectList.findObject(itAttach->second); | 268 | for (rlv_attachlock_map_t::const_iterator itAttach = m_AttachRem.lower_bound(idxAttachPt), |
272 | if ( (!pTempObj) || (pTempObj->getRootEdit()->getID() != pObj->getID()) ) | 269 | endAttach = m_AttachRem.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) |
273 | return false; | 270 | { |
271 | if ( ((pTempObj = gObjectList.findObject(itAttach->second)) == NULL) || (pTempObj->getRootEdit()->getID() != pObj->getID()) ) | ||
272 | return true; | ||
273 | } | ||
274 | } | 274 | } |
275 | return true; | 275 | if (eLock & RLV_LOCK_ADD) |
276 | { | ||
277 | for (rlv_attachlock_map_t::const_iterator itAttach = m_AttachAdd.lower_bound(idxAttachPt), | ||
278 | endAttach = m_AttachAdd.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | ||
279 | { | ||
280 | if ( ((pTempObj = gObjectList.findObject(itAttach->second)) == NULL) || (pTempObj->getRootEdit()->getID() != pObj->getID()) ) | ||
281 | return true; | ||
282 | } | ||
283 | } | ||
284 | return false; | ||
276 | } | 285 | } |
277 | 286 | ||
278 | // Checked: 2009-09-06 (RLVa-1.0.2b) | Modified: RLVa-1.0.2b | 287 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
279 | bool RlvHandler::setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable) | 288 | void RlvHandler::addAttachmentLock(S32 idxAttachPt, const LLUUID &idRlvObj, ERlvLockMask eLock) |
280 | { | 289 | { |
281 | // Sanity check - make sure it's an object we know about | 290 | // Sanity check - make sure it's an object we know about |
282 | rlv_object_map_t::const_iterator itObj = m_Objects.find(idRlvObj); | 291 | if ( (m_Objects.find(idRlvObj) == m_Objects.end()) || (!idxAttachPt) ) |
283 | if ( (itObj == m_Objects.end()) || (!idxAttachPt) ) | 292 | return; // If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE) |
284 | return false; // If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE) | ||
285 | 293 | ||
286 | if (!fDetachable) | 294 | // NOTE: m_AttachXXX can contain duplicate <idxAttachPt, idRlvObj> pairs (ie @detach:spine=n,detach=n from an attachment on spine) |
295 | if (eLock & RLV_LOCK_REMOVE) | ||
287 | { | 296 | { |
288 | #ifdef RLV_EXPERIMENTAL_FIRSTUSE | 297 | #ifdef RLV_EXPERIMENTAL_FIRSTUSE |
289 | //LLFirstUse::useRlvDetach(); | 298 | //LLFirstUse::useRlvDetach(); |
290 | #endif // RLV_EXPERIMENTAL_FIRSTUSE | 299 | #endif // RLV_EXPERIMENTAL_FIRSTUSE |
291 | 300 | ||
292 | // NOTE: m_Attachments can contain duplicate <idxAttachPt, idRlvObj> pairs (ie @detach:spine=n,detach=n from an attachment on spine) | 301 | m_AttachRem.insert(std::pair<S32, LLUUID>(idxAttachPt, idRlvObj)); |
293 | m_Attachments.insert(std::pair<S32, LLUUID>(idxAttachPt, itObj->second.m_UUID)); | ||
294 | return true; | ||
295 | } | 302 | } |
296 | else | 303 | if (eLock & RLV_LOCK_ADD) |
297 | { | 304 | { |
298 | for (rlv_detach_map_t::iterator itAttach = m_Attachments.lower_bound(idxAttachPt), | 305 | m_AttachAdd.insert(std::pair<S32, LLUUID>(idxAttachPt, idRlvObj)); |
299 | endAttach = m_Attachments.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | 306 | } |
307 | } | ||
308 | |||
309 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a | ||
310 | void RlvHandler::removeAttachmentLock(S32 idxAttachPt, const LLUUID &idRlvObj, ERlvLockMask eLock) | ||
311 | { | ||
312 | // Sanity check - make sure it's an object we know about | ||
313 | if ( (m_Objects.find(idRlvObj) == m_Objects.end()) || (!idxAttachPt) ) | ||
314 | return; // If (idxAttachPt) == 0 then: (pObj == NULL) || (pObj->isAttachment() == FALSE) | ||
315 | |||
316 | if (eLock & RLV_LOCK_REMOVE) | ||
317 | { | ||
318 | for (rlv_attachlock_map_t::iterator itAttach = m_AttachRem.lower_bound(idxAttachPt), | ||
319 | endAttach = m_AttachRem.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | ||
300 | { | 320 | { |
301 | if (itObj->second.m_UUID == itAttach->second) | 321 | if (idRlvObj == itAttach->second) |
302 | { | 322 | { |
303 | m_Attachments.erase(itAttach); | 323 | m_AttachRem.erase(itAttach); |
304 | return true; | 324 | break; |
325 | } | ||
326 | } | ||
327 | } | ||
328 | if (eLock & RLV_LOCK_ADD) | ||
329 | { | ||
330 | for (rlv_attachlock_map_t::iterator itAttach = m_AttachAdd.lower_bound(idxAttachPt), | ||
331 | endAttach = m_AttachAdd.upper_bound(idxAttachPt); itAttach != endAttach; ++itAttach) | ||
332 | { | ||
333 | if (idRlvObj == itAttach->second) | ||
334 | { | ||
335 | m_AttachAdd.erase(itAttach); | ||
336 | break; | ||
305 | } | 337 | } |
306 | } | 338 | } |
307 | } | 339 | } |
308 | return false; // Fall-through for (fDetachable == TRUE) - if the object wasn't undetachable then we consider it a failure | ||
309 | } | 340 | } |
310 | 341 | ||
311 | |||
312 | |||
313 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP | 342 | #ifdef RLV_EXTENSION_FLAG_NOSTRIP |
314 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | 343 | // Checked: 2009-05-26 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d |
315 | bool RlvHandler::isStrippable(const LLUUID& idItem) const | 344 | bool RlvHandler::isStrippable(const LLUUID& idItem) const |
@@ -413,10 +442,10 @@ void RlvHandler::notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fIntern | |||
413 | } | 442 | } |
414 | 443 | ||
415 | // Checked: | 444 | // Checked: |
416 | BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, bool fFromObj) | 445 | BOOL RlvHandler::processCommand(const LLUUID& idObj, const std::string& strCmd, bool fFromObj) |
417 | { | 446 | { |
418 | #ifdef RLV_DEBUG | 447 | #ifdef RLV_DEBUG |
419 | RLV_INFOS << "[" << uuid << "]: " << strCmd << LL_ENDL; | 448 | RLV_INFOS << "[" << idObj << "]: " << strCmd << LL_ENDL; |
420 | #endif // RLV_DEBUG | 449 | #endif // RLV_DEBUG |
421 | 450 | ||
422 | RlvCommand rlvCmd(strCmd); | 451 | RlvCommand rlvCmd(strCmd); |
@@ -427,7 +456,10 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
427 | #endif // RLV_DEBUG | 456 | #endif // RLV_DEBUG |
428 | return FALSE; | 457 | return FALSE; |
429 | } | 458 | } |
430 | m_pCurCommand = &rlvCmd; m_idCurObject = uuid; | 459 | |
460 | // NOTE: if we pass RlvObject::m_UUID for idObj somewhere and process a @clear then it will point to invalid/cleared memory at the end | ||
461 | // so make sure to *always* pass our private copy to other functions | ||
462 | m_pCurCommand = &rlvCmd; m_idCurObject = idObj; | ||
431 | 463 | ||
432 | BOOL fRet = FALSE; | 464 | BOOL fRet = FALSE; |
433 | switch (rlvCmd.getParamType()) | 465 | switch (rlvCmd.getParamType()) |
@@ -444,7 +476,7 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
444 | break; | 476 | break; |
445 | } | 477 | } |
446 | 478 | ||
447 | rlv_object_map_t::iterator itObj = m_Objects.find(uuid); | 479 | rlv_object_map_t::iterator itObj = m_Objects.find(m_idCurObject); |
448 | if (itObj != m_Objects.end()) | 480 | if (itObj != m_Objects.end()) |
449 | { | 481 | { |
450 | RlvObject& rlvObj = itObj->second; | 482 | RlvObject& rlvObj = itObj->second; |
@@ -452,9 +484,9 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
452 | } | 484 | } |
453 | else | 485 | else |
454 | { | 486 | { |
455 | RlvObject rlvObj(uuid); | 487 | RlvObject rlvObj(m_idCurObject); |
456 | fRet = rlvObj.addCommand(rlvCmd); | 488 | fRet = rlvObj.addCommand(rlvCmd); |
457 | m_Objects.insert(std::pair<LLUUID, RlvObject>(uuid, rlvObj)); | 489 | m_Objects.insert(std::pair<LLUUID, RlvObject>(m_idCurObject, rlvObj)); |
458 | } | 490 | } |
459 | 491 | ||
460 | #ifdef RLV_DEBUG | 492 | #ifdef RLV_DEBUG |
@@ -464,14 +496,14 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
464 | if (fRet) { // If FALSE then this was a duplicate, there's no need to handle those | 496 | if (fRet) { // If FALSE then this was a duplicate, there's no need to handle those |
465 | if (!m_pGCTimer) | 497 | if (!m_pGCTimer) |
466 | m_pGCTimer = new RlvGCTimer(); | 498 | m_pGCTimer = new RlvGCTimer(); |
467 | processAddCommand(uuid, rlvCmd); | 499 | processAddCommand(m_idCurObject, rlvCmd); |
468 | notifyBehaviourObservers(rlvCmd, !fFromObj); | 500 | notifyBehaviourObservers(rlvCmd, !fFromObj); |
469 | } | 501 | } |
470 | } | 502 | } |
471 | break; | 503 | break; |
472 | case RLV_TYPE_REMOVE: // Checked: | 504 | case RLV_TYPE_REMOVE: // Checked: |
473 | { | 505 | { |
474 | rlv_object_map_t::iterator itObj = m_Objects.find(uuid); | 506 | rlv_object_map_t::iterator itObj = m_Objects.find(m_idCurObject); |
475 | if (itObj != m_Objects.end()) | 507 | if (itObj != m_Objects.end()) |
476 | fRet = itObj->second.removeCommand(rlvCmd); | 508 | fRet = itObj->second.removeCommand(rlvCmd); |
477 | 509 | ||
@@ -481,13 +513,13 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
481 | #endif // RLV_DEBUG | 513 | #endif // RLV_DEBUG |
482 | 514 | ||
483 | if (fRet) { // Don't handle non-sensical removes | 515 | if (fRet) { // Don't handle non-sensical removes |
484 | processRemoveCommand(uuid, rlvCmd); | 516 | processRemoveCommand(m_idCurObject, rlvCmd); |
485 | notifyBehaviourObservers(rlvCmd, !fFromObj); | 517 | notifyBehaviourObservers(rlvCmd, !fFromObj); |
486 | 518 | ||
487 | if (0 == itObj->second.m_Commands.size()) | 519 | if (0 == itObj->second.m_Commands.size()) |
488 | { | 520 | { |
489 | #ifdef RLV_DEBUG | 521 | #ifdef RLV_DEBUG |
490 | RLV_INFOS << "\t- command list empty => removing " << uuid << LL_ENDL; | 522 | RLV_INFOS << "\t- command list empty => removing " << m_idCurObject << LL_ENDL; |
491 | #endif // RLV_DEBUG | 523 | #endif // RLV_DEBUG |
492 | m_Objects.erase(itObj); | 524 | m_Objects.erase(itObj); |
493 | } | 525 | } |
@@ -495,14 +527,14 @@ BOOL RlvHandler::processCommand(const LLUUID& uuid, const std::string& strCmd, b | |||
495 | } | 527 | } |
496 | break; | 528 | break; |
497 | case RLV_TYPE_CLEAR: | 529 | case RLV_TYPE_CLEAR: |
498 | fRet = processClearCommand(uuid, rlvCmd); | 530 | fRet = processClearCommand(m_idCurObject, rlvCmd); |
499 | notifyBehaviourObservers(rlvCmd, !fFromObj); | 531 | notifyBehaviourObservers(rlvCmd, !fFromObj); |
500 | break; | 532 | break; |
501 | case RLV_TYPE_FORCE: // Checked: | 533 | case RLV_TYPE_FORCE: // Checked: |
502 | fRet = processForceCommand(uuid, rlvCmd); | 534 | fRet = processForceCommand(m_idCurObject, rlvCmd); |
503 | break; | 535 | break; |
504 | case RLV_TYPE_REPLY: // Checked: | 536 | case RLV_TYPE_REPLY: // Checked: |
505 | fRet = processReplyCommand(uuid, rlvCmd); | 537 | fRet = processReplyCommand(m_idCurObject, rlvCmd); |
506 | break; | 538 | break; |
507 | case RLV_TYPE_UNKNOWN: // Checked: | 539 | case RLV_TYPE_UNKNOWN: // Checked: |
508 | break; | 540 | break; |
@@ -535,35 +567,15 @@ BOOL RlvHandler::processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) | |||
535 | m_Behaviours[eBehaviour]++; | 567 | m_Behaviours[eBehaviour]++; |
536 | } | 568 | } |
537 | 569 | ||
570 | bool fRefCount = false; // Unused for the moment | ||
538 | switch (eBehaviour) | 571 | switch (eBehaviour) |
539 | { | 572 | { |
540 | case RLV_BHVR_DETACH: // @detach[:<option>]=n - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | 573 | case RLV_BHVR_DETACH: // @detach[:<option>]=n - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
541 | { | 574 | onAddRemDetach(uuid, rlvCmd, fRefCount); |
542 | LLViewerObject* pObj = NULL; S32 idxAttachPt = 0; | 575 | break; |
543 | if (strOption.empty()) // @detach=n | 576 | case RLV_BHVR_ADDATTACH: // @addattach[:<option>]=n - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
544 | { | 577 | case RLV_BHVR_REMATTACH: // @addattach[:<option>]=n - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
545 | // If the object rezzed before we received @detach=n from it then we can just do our thing here | 578 | onAddRemAttach(uuid, rlvCmd, fRefCount); |
546 | // If the object hasn't rezzed yet then we need to wait until RlvHandler::onAttach() | ||
547 | // If @detach=n were possible for non-attachments another copy/paste would be needed in RlvHandler::onGC() | ||
548 | if ((pObj = gObjectList.findObject(uuid)) != NULL) | ||
549 | setDetachable(pObj, uuid, false); | ||
550 | } | ||
551 | else if ((idxAttachPt = getAttachPointIndex(strOption, true)) != 0) // @detach:<attachpt>=n | ||
552 | { | ||
553 | setDetachable(idxAttachPt, uuid, false); | ||
554 | |||
555 | // (See below) | ||
556 | LLViewerJointAttachment* pAttachPt = getAttachPoint(strOption, true); | ||
557 | if (pAttachPt) | ||
558 | pObj = pAttachPt->getObject(); | ||
559 | } | ||
560 | |||
561 | // When at least one HUD attachment is locked we want to make sure they're all visible (ie prevent hiding a blindfold HUD) | ||
562 | // However, since @detach:<attachpt>=n might lock a HUD attachment point that doesn't currently have an object we | ||
563 | // have to do this here *and* in RlvHandler::onAttach() | ||
564 | if ( (pObj) && (pObj->isHUDAttachment()) ) | ||
565 | LLPipeline::sShowHUDAttachments = TRUE; | ||
566 | } | ||
567 | break; | 579 | break; |
568 | case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d) | 580 | case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d) |
569 | case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a | 581 | case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=n - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a |
@@ -797,25 +809,15 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC | |||
797 | m_Behaviours[eBehaviour]--; | 809 | m_Behaviours[eBehaviour]--; |
798 | } | 810 | } |
799 | 811 | ||
812 | bool fRefCount = false; // Unused for the moment | ||
800 | switch (eBehaviour) | 813 | switch (eBehaviour) |
801 | { | 814 | { |
802 | case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-08-04 (RLVa-1.0.1d) | Modified: RLVa-1.0.1d | 815 | case RLV_BHVR_DETACH: // @detach[:<option>]=y - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
803 | { | 816 | onAddRemDetach(uuid, rlvCmd, fRefCount); |
804 | S32 idxAttachPt = 0; | 817 | break; |
805 | if (strOption.empty()) // @detach=y | 818 | case RLV_BHVR_ADDATTACH: // @addattach[:<option>]=y - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
806 | { | 819 | case RLV_BHVR_REMATTACH: // @addattach[:<option>]=y - Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a |
807 | // The object may or may not (if it got detached) still exist | 820 | onAddRemAttach(uuid, rlvCmd, fRefCount); |
808 | rlv_object_map_t::const_iterator itObj = m_Objects.find(uuid); | ||
809 | if (itObj != m_Objects.end()) | ||
810 | idxAttachPt = itObj->second.m_idxAttachPt; | ||
811 | if (idxAttachPt) | ||
812 | setDetachable(idxAttachPt, uuid, true); | ||
813 | } | ||
814 | else if ((idxAttachPt = getAttachPointIndex(strOption, true))) // @detach:<attachpt>=y | ||
815 | { | ||
816 | setDetachable(idxAttachPt, uuid, true); | ||
817 | } | ||
818 | } | ||
819 | break; | 821 | break; |
820 | case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d) | 822 | case RLV_BHVR_REDIRCHAT: // @redirchat:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d) |
821 | case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a | 823 | case RLV_BHVR_REDIREMOTE: // @rediremote:<option>=y - Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.2a |
@@ -940,7 +942,7 @@ BOOL RlvHandler::processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvC | |||
940 | return TRUE; // Remove commands don't fail, doesn't matter what we return here | 942 | return TRUE; // Remove commands don't fail, doesn't matter what we return here |
941 | } | 943 | } |
942 | 944 | ||
943 | BOOL RlvHandler::processClearCommand(const LLUUID& idObj, const RlvCommand& rlvCmd) | 945 | BOOL RlvHandler::processClearCommand(const LLUUID idObj, const RlvCommand& rlvCmd) |
944 | { | 946 | { |
945 | const std::string& strFilter = rlvCmd.getParam(); std::string strCmdRem; | 947 | const std::string& strFilter = rlvCmd.getParam(); std::string strCmdRem; |
946 | 948 | ||
@@ -976,8 +978,11 @@ BOOL RlvHandler::processForceCommand(const LLUUID& idObj, const RlvCommand& rlvC | |||
976 | 978 | ||
977 | switch (rlvCmd.getBehaviourType()) | 979 | switch (rlvCmd.getBehaviourType()) |
978 | { | 980 | { |
979 | case RLV_BHVR_DETACH: // @detach[:<option>]=force - Checked: | 981 | case RLV_BHVR_DETACH: // @detach[:<option>]=force - Checked: 2009-10-12 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
980 | onForceDetach(idObj, strOption); | 982 | onForceDetach(idObj, rlvCmd); |
983 | break; | ||
984 | case RLV_BHVR_REMATTACH: // @remattach[:<option>]=force - Checked: 2009-10-12 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a | ||
985 | onForceRemAttach(idObj, rlvCmd); | ||
981 | break; | 986 | break; |
982 | case RLV_BHVR_REMOUTFIT: // @remoutfit:<option>=force - Checked: | 987 | case RLV_BHVR_REMOUTFIT: // @remoutfit:<option>=force - Checked: |
983 | onForceRemOutfit(idObj, strOption); | 988 | onForceRemOutfit(idObj, strOption); |
@@ -1125,7 +1130,7 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm | |||
1125 | #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING | 1130 | #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING |
1126 | } | 1131 | } |
1127 | break; | 1132 | break; |
1128 | case RLV_BHVR_GETATTACH: // @getattach[:<layer>]=<channel> - Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | 1133 | case RLV_BHVR_GETATTACH: // @getattach[:<layer>]=<channel> - Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a |
1129 | { | 1134 | { |
1130 | // If we're fetching all worn attachments then the reply should start with 0 | 1135 | // If we're fetching all worn attachments then the reply should start with 0 |
1131 | if (strOption.empty()) | 1136 | if (strOption.empty()) |
@@ -1155,9 +1160,9 @@ BOOL RlvHandler::processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCm | |||
1155 | { | 1160 | { |
1156 | bool fWorn = (pAttachment->getItemID().notNull()) && | 1161 | bool fWorn = (pAttachment->getItemID().notNull()) && |
1157 | ( (!RlvSettings::getHideLockedAttach()) || | 1162 | ( (!RlvSettings::getHideLockedAttach()) || |
1158 | ( (isDetachable(itAttach->first)) && (isStrippable(pAttachment->getItemID())) ) ); | 1163 | ( (!isLockedAttachmentExcept(itAttach->first, RLV_LOCK_REMOVE, gObjectList.findObject(uuid))) && |
1164 | (isStrippable(pAttachment->getItemID())) ) ); | ||
1159 | strReply.push_back( (fWorn) ? '1' : '0' ); | 1165 | strReply.push_back( (fWorn) ? '1' : '0' ); |
1160 | //strReply.push_back( (pAttachment->getItemID().notNull()) ? '1' : '0' ); | ||
1161 | } | 1166 | } |
1162 | #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING | 1167 | #endif // RLV_EXPERIMENTAL_COMPOSITE_FOLDING |
1163 | } | 1168 | } |
@@ -1327,7 +1332,7 @@ void RlvHandler::initLookupTables() | |||
1327 | } | 1332 | } |
1328 | 1333 | ||
1329 | // Checked: 2009-08-11 (RLVa-1.0.1h) | Modified: RLVa-1.0.1h | 1334 | // Checked: 2009-08-11 (RLVa-1.0.1h) | Modified: RLVa-1.0.1h |
1330 | void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | 1335 | void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt) |
1331 | { | 1336 | { |
1332 | // Sanity check - LLVOAvatar::attachObject() should call us *after* calling LLViewerJointAttachment::addObject() | 1337 | // Sanity check - LLVOAvatar::attachObject() should call us *after* calling LLViewerJointAttachment::addObject() |
1333 | LLViewerObject* pObj = pAttachPt->getObject(); | 1338 | LLViewerObject* pObj = pAttachPt->getObject(); |
@@ -1338,30 +1343,8 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1338 | return; | 1343 | return; |
1339 | } | 1344 | } |
1340 | 1345 | ||
1341 | // Check if this attachment point has a pending "reattach-on-detach" | 1346 | // Let the attachment manager know |
1342 | rlv_reattach_map_t::iterator itReattach = m_AttachPending.find(idxAttachPt); | 1347 | m_pAttachMgr->onAttach(pAttachPt); |
1343 | if (itReattach != m_AttachPending.end()) | ||
1344 | { | ||
1345 | if (itReattach->second == pAttachPt->getItemID()) | ||
1346 | { | ||
1347 | RLV_INFOS << "Reattached " << pAttachPt->getItemID().asString() << " to " << idxAttachPt << LL_ENDL; | ||
1348 | m_AttachPending.erase(itReattach); | ||
1349 | } | ||
1350 | } | ||
1351 | else if ( (fFullyLoaded) && (!isDetachableExcept(idxAttachPt, pObj)) ) | ||
1352 | { | ||
1353 | // We're fully loaded with no pending reattach on this attach point but it's "undetachable" -> force detach the new attachment | ||
1354 | |||
1355 | // Assertion: the only way the attachment point could be locked at this point is if some object locked it with @detach:attachpt=n | ||
1356 | // - previous attachments on this attachment point might have issued @detach=n but those were all cleaned up at detach | ||
1357 | // - the new attachment might have issued @detach=n but that won't actually lock down the attachment point until further down | ||
1358 | // NOTE 1: "some object" may no longer exist if it was not an attachment and the GC hasn't cleaned it up yet (informative) | ||
1359 | // NOTE 2: "some object" may refer to the new attachment - ie @detach:spine=n from object on spine (problematic, causes reattach) | ||
1360 | // -> solved by using isDetachableExcept(idxAttachPt, pObj) instead of isDetachable(idxAttachPt) | ||
1361 | |||
1362 | m_DetachPending.insert(std::pair<S32, LLUUID>(idxAttachPt, pObj->getID())); | ||
1363 | rlvForceDetach(pAttachPt); | ||
1364 | } | ||
1365 | 1348 | ||
1366 | // Check if we already have an RlvObject instance for this object (rezzed prim attached from in-world, or an attachment that rezzed in) | 1349 | // Check if we already have an RlvObject instance for this object (rezzed prim attached from in-world, or an attachment that rezzed in) |
1367 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); | 1350 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); |
@@ -1378,7 +1361,7 @@ void RlvHandler::onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded) | |||
1378 | if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false)) | 1361 | if (itObj->second.hasBehaviour(RLV_BHVR_DETACH, false)) |
1379 | { | 1362 | { |
1380 | // (Copy/paste from processAddCommand) | 1363 | // (Copy/paste from processAddCommand) |
1381 | setDetachable(idxAttachPt, pObj->getID(), false); | 1364 | addAttachmentLock(idxAttachPt, itObj->second.m_UUID, RLV_LOCK_REMOVE); |
1382 | 1365 | ||
1383 | if (pObj->isHUDAttachment()) | 1366 | if (pObj->isHUDAttachment()) |
1384 | LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments | 1367 | LLPipeline::sShowHUDAttachments = TRUE; // Prevents hiding of locked HUD attachments |
@@ -1469,44 +1452,19 @@ void RlvHandler::onDetach(LLViewerJointAttachment* pAttachPt) | |||
1469 | //RLV_INFOS << "Clean up for '" << pDbgAttachmentPt->getName() << "'" << LL_ENDL; | 1452 | //RLV_INFOS << "Clean up for '" << pDbgAttachmentPt->getName() << "'" << LL_ENDL; |
1470 | #endif // RLV_DEBUG | 1453 | #endif // RLV_DEBUG |
1471 | 1454 | ||
1472 | // If the attachment was locked then we should reattach it (unless we're already trying to reattach to this attachment point) | 1455 | // Let the attachment manager know |
1473 | // (unless we forcefully detached it else in which case we do not want to reattach it) | 1456 | m_pAttachMgr->onDetach(pAttachPt); |
1474 | rlv_reattach_map_t::iterator itDetach = m_DetachPending.find(idxAttachPt); | ||
1475 | if (itDetach != m_DetachPending.end()) | ||
1476 | { | ||
1477 | // RLVa-TODO: we should really be comparing item UUIDs but is it even possible to end up here and not have them match? | ||
1478 | m_DetachPending.erase(itDetach); | ||
1479 | } | ||
1480 | else if ( (!isDetachable(idxAttachPt)) && (m_AttachPending.find(idxAttachPt) == m_AttachPending.end()) ) | ||
1481 | { | ||
1482 | // In an ideal world we would simply set up an LLInventoryObserver but there's no specific "asset updated" changed flag *sighs* | ||
1483 | // NOTE: attachments *always* know their "inventory item UUID" so we don't have to worry about fetched vs unfetched inventory | ||
1484 | m_AttachPending.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID())); | ||
1485 | } | ||
1486 | 1457 | ||
1487 | // We can't - easily - clean up child prims that never issued @detach=n but the GC will get those eventually | 1458 | // Clean up any restriction this object (or one of its child prims) may have |
1488 | rlv_detach_map_t::iterator itAttach = m_Attachments.find(idxAttachPt); | 1459 | rlv_object_map_t::iterator itObj = m_Objects.begin(), itCurrent; |
1489 | while ( (itAttach != m_Attachments.upper_bound(idxAttachPt)) && (itAttach != m_Attachments.end()) ) | 1460 | while (itObj != m_Objects.end()) |
1490 | { | 1461 | { |
1491 | LLViewerObject* pTempObj = gObjectList.findObject(itAttach->second); | 1462 | itCurrent = itObj++; // @clear will invalidate our iterator so point it ahead now |
1492 | if ( (pTempObj) && (pTempObj->getRootEdit()->getID() == pObj->getID()) ) | ||
1493 | { | ||
1494 | // Iterator points to the object (or to a child prim) so issue a clear on behalf of the object (there's the | ||
1495 | // possibility of going into an eternal loop, but that's ok since it indicates a bug in @clear that needs fixing) | ||
1496 | processCommand(itAttach->second, "clear", true); | ||
1497 | 1463 | ||
1498 | itAttach = m_Attachments.find(idxAttachPt); // @clear will invalidate all iterators so we have to start anew | 1464 | // NOTE: ObjectKill seems to happen in reverse (child prims are killed before the root is) so we can't use gObjectList here |
1499 | } | 1465 | if (itCurrent->second.m_idxAttachPt == idxAttachPt) |
1500 | else | 1466 | processCommand(itCurrent->second.m_UUID, "clear", true); |
1501 | { | ||
1502 | itAttach++; | ||
1503 | } | ||
1504 | } | 1467 | } |
1505 | |||
1506 | // Clean up in case there was never a @detach=n (only works for the root prim - see above) | ||
1507 | rlv_object_map_t::iterator itObj = m_Objects.find(pObj->getID()); | ||
1508 | if (itObj != m_Objects.end()) | ||
1509 | processCommand(itObj->second.m_UUID, "clear", true); | ||
1510 | } | 1468 | } |
1511 | 1469 | ||
1512 | // Checked: 2009-07-30 (RLVa-1.0.1c) | Modified: RLVa-1.0.1c | 1470 | // Checked: 2009-07-30 (RLVa-1.0.1c) | Modified: RLVa-1.0.1c |
@@ -1548,32 +1506,6 @@ bool RlvHandler::onGC() | |||
1548 | return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do | 1506 | return (0 != m_Objects.size()); // GC will kill itself if it has nothing to do |
1549 | } | 1507 | } |
1550 | 1508 | ||
1551 | // Checked: 2009-08-08 (RLVa-1.0.1g) | Modified: RLVa-1.0.1g | ||
1552 | void RlvHandler::onSavedAssetIntoInventory(const LLUUID& idItem) | ||
1553 | { | ||
1554 | for (rlv_reattach_map_t::iterator itAttach = m_AttachPending.begin(); itAttach != m_AttachPending.end(); ++itAttach) | ||
1555 | { | ||
1556 | if (idItem == itAttach->second) | ||
1557 | { | ||
1558 | RLV_INFOS << "Reattaching " << idItem.asString() << " to " << itAttach->first << LL_ENDL; | ||
1559 | |||
1560 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | ||
1561 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; | ||
1562 | rez_action->mItemID = itAttach->second; | ||
1563 | rez_action->mAttachPt = itAttach->first; | ||
1564 | |||
1565 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action) | ||
1566 | #else // Version: 1.23.4 | ||
1567 | LLSD payload; | ||
1568 | payload["item_id"] = itAttach->second; | ||
1569 | payload["attachment_point"] = itAttach->first; | ||
1570 | |||
1571 | LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | ||
1572 | #endif | ||
1573 | } | ||
1574 | } | ||
1575 | } | ||
1576 | |||
1577 | // ============================================================================ | 1509 | // ============================================================================ |
1578 | // String/chat censoring functions | 1510 | // String/chat censoring functions |
1579 | // | 1511 | // |
@@ -2099,47 +2031,6 @@ std::string RlvHandler::getSharedPath(const LLViewerInventoryCategory* pFolder) | |||
2099 | // | 2031 | // |
2100 | 2032 | ||
2101 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | 2033 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d |
2102 | void RlvHandler::onForceDetach(const LLUUID& idObj, const std::string& strOption) const | ||
2103 | { | ||
2104 | U16 nParam; | ||
2105 | if (strOption.empty()) | ||
2106 | { | ||
2107 | // Simulate right-click / Take Off > Detach All | ||
2108 | LLAgent::userRemoveAllAttachments(NULL); | ||
2109 | } | ||
2110 | else if (m_AttachLookup.getExactMatchParam(strOption, nParam)) | ||
2111 | { | ||
2112 | // Simulate right-click / Take Off > Detach > ... | ||
2113 | LLVOAvatar* pAvatar; LLViewerJointAttachment* pAttachmentPt; | ||
2114 | if ( ((pAvatar = gAgent.getAvatarObject()) != NULL) && // Make sure we're actually wearing something on the attachment point | ||
2115 | ((pAttachmentPt = get_if_there(pAvatar->mAttachmentPoints, (S32)nParam, (LLViewerJointAttachment*)NULL)) != NULL) && | ||
2116 | (isStrippable(pAttachmentPt->getItemID())) ) // ... and that it's not marked as "nostrip" | ||
2117 | { | ||
2118 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
2119 | // If we're stripping something that's part of a composite folder then we should @detachthis instead | ||
2120 | if (isCompositeDescendent(pAttachmentPt->getItemID())) | ||
2121 | { | ||
2122 | std::string strCmd = "detachthis:" + strOption + "=force"; | ||
2123 | #ifdef RLV_DEBUG | ||
2124 | RLV_INFOS << "\t- '" << strOption << "' belongs to composite folder: @" << strCmd << LL_ENDL; | ||
2125 | #endif // RLV_DEBUG | ||
2126 | processForceCommand(idObj, RlvCommand(strCmd)); | ||
2127 | } | ||
2128 | else | ||
2129 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
2130 | { | ||
2131 | handle_detach_from_avatar(pAttachmentPt); | ||
2132 | } | ||
2133 | } | ||
2134 | } | ||
2135 | else | ||
2136 | { | ||
2137 | // Force detach single folder | ||
2138 | onForceWear(strOption, false, false); | ||
2139 | } | ||
2140 | } | ||
2141 | |||
2142 | // Checked: 2009-07-12 (RLVa-1.0.0h) | Modified: RLVa-0.2.0d | ||
2143 | void RlvHandler::onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const | 2034 | void RlvHandler::onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const |
2144 | { | 2035 | { |
2145 | EWearableType typeOption = LLWearable::typeNameToType(strOption), type; | 2036 | EWearableType typeOption = LLWearable::typeNameToType(strOption), type; |
@@ -2209,6 +2100,7 @@ bool RlvHandler::onForceSit(const LLUUID& idObj, const std::string& strOption) c | |||
2209 | return true; | 2100 | return true; |
2210 | } | 2101 | } |
2211 | 2102 | ||
2103 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Modified: RLVa-1.0.5a | ||
2212 | void RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const | 2104 | void RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const |
2213 | { | 2105 | { |
2214 | // See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items | 2106 | // See LLWearableBridge::wearOnAvatar(): don't wear anything until initial wearables are loaded, can destroy clothing items |
@@ -2281,22 +2173,11 @@ void RlvHandler::onForceWear(const std::string& strPath, bool fAttach, bool fMat | |||
2281 | // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog) | 2173 | // Simulate wearing an object to a specific attachment point (copy/paste to suppress replacement dialog) |
2282 | // LLAttachObject::handleEvent() => rez_attachment() | 2174 | // LLAttachObject::handleEvent() => rez_attachment() |
2283 | LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); | 2175 | LLViewerJointAttachment* pAttachPt = getAttachPoint(pItem, true); |
2284 | if ( (pAttachPt) && (isDetachable(pAttachPt)) ) | 2176 | if ( (pAttachPt) && // Need a specific attach pt that |
2177 | ( (!isLockedAttachment(pAttachPt->getObject(), RLV_LOCK_REMOVE)) && // doesn't have locked object | ||
2178 | (!isLockedAttachment(pAttachPt, RLV_LOCK_ADD)) ) ) // and that can be attached to | ||
2285 | { | 2179 | { |
2286 | #if RLV_TARGET < RLV_MAKE_TARGET(1, 23, 0) // Version: 1.22.11 | 2180 | RlvAttachmentManager::forceAttach(pItem->getUUID(), getAttachPointIndex(pAttachPt->getName(), true)); |
2287 | LLAttachmentRezAction* rez_action = new LLAttachmentRezAction; | ||
2288 | rez_action->mItemID = pItem->getUUID(); | ||
2289 | rez_action->mAttachPt = getAttachPointIndex(pAttachPt->getName(), true); | ||
2290 | |||
2291 | confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action); // (Will call delete on rez_action) | ||
2292 | #else // Version: 1.23.4 | ||
2293 | LLSD payload; | ||
2294 | payload["item_id"] = pItem->getUUID(); | ||
2295 | payload["attachment_point"] = getAttachPointIndex(pAttachPt->getName(), true); | ||
2296 | |||
2297 | LLNotifications::instance().forceResponse( | ||
2298 | LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/); | ||
2299 | #endif | ||
2300 | } | 2181 | } |
2301 | } | 2182 | } |
2302 | else | 2183 | else |
@@ -2504,6 +2385,7 @@ BOOL RlvHandler::setEnabled(BOOL fEnable) | |||
2504 | RlvSettings::fShowNameTags = gSavedSettings.getBOOL(RLV_SETTING_SHOWNAMETAGS); | 2385 | RlvSettings::fShowNameTags = gSavedSettings.getBOOL(RLV_SETTING_SHOWNAMETAGS); |
2505 | 2386 | ||
2506 | RlvCommand::initLookupTable(); | 2387 | RlvCommand::initLookupTable(); |
2388 | gRlvHandler.m_pAttachMgr = new RlvAttachmentManager(); | ||
2507 | gRlvHandler.addObserver(new RlvExtGetSet()); | 2389 | gRlvHandler.addObserver(new RlvExtGetSet()); |
2508 | 2390 | ||
2509 | if (LLStartUp::getStartupState() >= STATE_CLEANUP) | 2391 | if (LLStartUp::getStartupState() >= STATE_CLEANUP) |
@@ -2553,7 +2435,7 @@ void RlvHandler::clearState() | |||
2553 | while (m_Objects.size()) | 2435 | while (m_Objects.size()) |
2554 | { | 2436 | { |
2555 | idObj = m_Objects.begin()->first; // Need a copy since after @clear the data it points to will no longer exist | 2437 | idObj = m_Objects.begin()->first; // Need a copy since after @clear the data it points to will no longer exist |
2556 | fDetachable = ((pObj = gObjectList.findObject(idObj)) != NULL) ? isDetachable(pObj) : true; | 2438 | fDetachable = ((pObj = gObjectList.findObject(idObj)) != NULL) ? isLockedAttachment(pObj, RLV_LOCK_REMOVE) : true; |
2557 | 2439 | ||
2558 | processCommand(idObj, "clear", false); | 2440 | processCommand(idObj, "clear", false); |
2559 | if (!fDetachable) | 2441 | if (!fDetachable) |
@@ -2561,32 +2443,165 @@ void RlvHandler::clearState() | |||
2561 | } | 2443 | } |
2562 | 2444 | ||
2563 | // Sanity check - these should all be empty after we issue @clear on the last object | 2445 | // Sanity check - these should all be empty after we issue @clear on the last object |
2564 | if ( (!m_Objects.empty()) || !(m_Exceptions.empty()) || (!m_Attachments.empty()) ) | 2446 | if ( (!m_Objects.empty()) || !(m_Exceptions.empty()) || (!m_AttachAdd.empty()) || (!m_AttachRem.empty()) ) |
2565 | { | 2447 | { |
2566 | RLV_ERRS << "Object, exception or attachment map not empty after clearing state!" << LL_ENDL; | 2448 | RLV_ERRS << "Object, exception or attachment map not empty after clearing state!" << LL_ENDL; |
2567 | m_Objects.clear(); | 2449 | m_Objects.clear(); |
2568 | m_Exceptions.clear(); | 2450 | m_Exceptions.clear(); |
2569 | m_Attachments.clear(); | 2451 | m_AttachAdd.clear(); |
2452 | m_AttachRem.clear(); | ||
2570 | } | 2453 | } |
2571 | 2454 | ||
2572 | // These all need manual clearing | 2455 | // These all need manual clearing |
2573 | memset(m_LayersAdd, 0, sizeof(S16) * WT_COUNT); | 2456 | memset(m_LayersAdd, 0, sizeof(S16) * WT_COUNT); |
2574 | memset(m_LayersRem, 0, sizeof(S16) * WT_COUNT); | 2457 | memset(m_LayersRem, 0, sizeof(S16) * WT_COUNT); |
2575 | memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT); | 2458 | memset(m_Behaviours, 0, sizeof(S16) * RLV_BHVR_COUNT); |
2576 | m_AttachPending.clear(); | 2459 | m_Retained.clear(); |
2577 | m_Emitter.clearObservers(); // <- calls delete on all active observers | 2460 | m_Emitter.clearObservers(); // <- calls delete on all active observers |
2578 | 2461 | ||
2579 | // Clear dynamically allocated memory | 2462 | // Clear dynamically allocated memory |
2580 | if (m_pGCTimer) | 2463 | delete m_pGCTimer; |
2464 | m_pGCTimer = NULL; | ||
2465 | delete m_pWLSnapshot; | ||
2466 | m_pWLSnapshot = NULL; | ||
2467 | delete m_pAttachMgr; | ||
2468 | m_pAttachMgr = NULL; | ||
2469 | } | ||
2470 | |||
2471 | // ============================================================================ | ||
2472 | // Command handlers (RLV_TYPE_ADD and RLV_TYPE_REMOVE) | ||
2473 | // | ||
2474 | |||
2475 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a | ||
2476 | ERlvCmdRet RlvHandler::onAddRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount) | ||
2477 | { | ||
2478 | // Sanity check - if there's an option it should specify a valid attachment point name | ||
2479 | S32 idxAttachPt = getAttachPointIndex(rlvCmd.getOption(), true); | ||
2480 | if ( (!idxAttachPt) && (!rlvCmd.getOption().empty()) ) | ||
2481 | return RLV_RET_FAILED_OPTION; | ||
2482 | |||
2483 | LLVOAvatar* pAvatar = gAgent.getAvatarObject(); | ||
2484 | if (!pAvatar) | ||
2485 | return RLV_RET_FAILED; | ||
2486 | |||
2487 | ERlvLockMask eLock = (RLV_BHVR_REMATTACH == rlvCmd.getBehaviourType()) ? RLV_LOCK_REMOVE : RLV_LOCK_ADD; | ||
2488 | for (LLVOAvatar::attachment_map_t::const_iterator itAttach = pAvatar->mAttachmentPoints.begin(); | ||
2489 | itAttach != pAvatar->mAttachmentPoints.end(); ++itAttach) | ||
2581 | { | 2490 | { |
2582 | delete m_pGCTimer; | 2491 | if ( (0 == idxAttachPt) || (itAttach->first == idxAttachPt) ) |
2583 | m_pGCTimer = NULL; | 2492 | { |
2493 | if (RLV_TYPE_ADD == rlvCmd.getParamType()) | ||
2494 | addAttachmentLock(itAttach->first, idObj, eLock); | ||
2495 | else | ||
2496 | removeAttachmentLock(itAttach->first, idObj, eLock); | ||
2497 | } | ||
2584 | } | 2498 | } |
2585 | if (m_pWLSnapshot) | 2499 | |
2500 | // Refresh HUD visibility if needed | ||
2501 | if ( (RLV_BHVR_REMATTACH == rlvCmd.getBehaviourType()) && (hasLockedHUD()) ) | ||
2502 | LLPipeline::sShowHUDAttachments = TRUE; | ||
2503 | |||
2504 | fRefCount = rlvCmd.getOption().empty(); // Only reference count global locks | ||
2505 | return RLV_RET_NOERROR; | ||
2506 | } | ||
2507 | |||
2508 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a | ||
2509 | ERlvCmdRet RlvHandler::onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount) | ||
2510 | { | ||
2511 | S32 idxAttachPt = 0; | ||
2512 | if (rlvCmd.getOption().empty()) // @detach=n|y | ||
2586 | { | 2513 | { |
2587 | delete m_pWLSnapshot; | 2514 | // The object may or may not exist (it may not have rezzed yet, or it may have already been killed): |
2588 | m_pWLSnapshot = NULL; | 2515 | // * @detach=n: - if it has rezzed then we'll already have its attachment point |
2516 | // - if it hasn't rezzed yet then it's a @detach=n from a non-attachment and RlvHandler::onAttach() takes care of it | ||
2517 | // * @detach=y: - if it ever rezzed as an attachment we'll have cached its attach point | ||
2518 | // - if it never rezzed as an attachment there won't be a lock to remove | ||
2519 | rlv_object_map_t::const_iterator itObj = m_Objects.find(idObj); | ||
2520 | if (itObj != m_Objects.end()) | ||
2521 | idxAttachPt = itObj->second.m_idxAttachPt; | ||
2522 | } | ||
2523 | else // @detach:<attachpt>=n|y | ||
2524 | { | ||
2525 | idxAttachPt = getAttachPointIndex(rlvCmd.getOption(), true); | ||
2526 | } | ||
2527 | |||
2528 | // The attach point can be zero for @detach=n|y (i.e. non-attachment) but should always be non-zero for @detach:<attachpt>=n|y | ||
2529 | if (0 == idxAttachPt) | ||
2530 | return (rlvCmd.getOption().empty()) ? RLV_RET_NOERROR : RLV_RET_FAILED_OPTION; | ||
2531 | |||
2532 | // Actually lock the attachment point (@detach=n locks remove only; @detach:<attachpt>=n locks both remove and add) | ||
2533 | ERlvLockMask eLock = (rlvCmd.getOption().empty()) ? RLV_LOCK_REMOVE : (ERlvLockMask)(RLV_LOCK_ADD | RLV_LOCK_REMOVE); | ||
2534 | if (RLV_TYPE_ADD == rlvCmd.getParamType()) | ||
2535 | addAttachmentLock(idxAttachPt, idObj, eLock); | ||
2536 | else | ||
2537 | removeAttachmentLock(idxAttachPt, idObj, eLock); | ||
2538 | |||
2539 | // Refresh HUD visibility if needed | ||
2540 | if ( (RLV_TYPE_ADD == rlvCmd.getParamType()) && (hasLockedHUD()) ) | ||
2541 | LLPipeline::sShowHUDAttachments = TRUE; | ||
2542 | |||
2543 | fRefCount = false; // Don't reference count @detach[:<option>]=n | ||
2544 | return RLV_RET_NOERROR; | ||
2545 | } | ||
2546 | |||
2547 | // ============================================================================ | ||
2548 | // Command handlers (RLV_TYPE_FORCE) | ||
2549 | // | ||
2550 | |||
2551 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b | ||
2552 | ERlvCmdRet RlvHandler::onForceDetach(const LLUUID& idObj, const RlvCommand& rlvCmd) const | ||
2553 | { | ||
2554 | // TODO-RLVA: this still needs a rewrite to conform to the new event handler system | ||
2555 | if ( (rlvCmd.getOption().empty()) || (getAttachPointIndex(rlvCmd.getOption(), true)) ) | ||
2556 | { | ||
2557 | onForceRemAttach(idObj, rlvCmd); | ||
2558 | } | ||
2559 | else | ||
2560 | { | ||
2561 | // Force detach single folder | ||
2562 | onForceWear(rlvCmd.getOption(), false, false); | ||
2563 | } | ||
2564 | |||
2565 | return RLV_RET_NOERROR; | ||
2566 | } | ||
2567 | |||
2568 | // Checked: 2009-10-12 (RLVa-1.0.5b) | Added: RLVa-1.0.5b | ||
2569 | ERlvCmdRet RlvHandler::onForceRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd) const | ||
2570 | { | ||
2571 | S32 idxAttachPt = 0; | ||
2572 | if (rlvCmd.getOption().empty()) | ||
2573 | { | ||
2574 | // Simulate right-click / Take Off > Detach All | ||
2575 | LLAgent::userRemoveAllAttachments(NULL); | ||
2576 | return RLV_RET_NOERROR; | ||
2577 | } | ||
2578 | else if ((idxAttachPt = getAttachPointIndex(rlvCmd.getOption(), true)) != 0) | ||
2579 | { | ||
2580 | // Simulate right-click / Take Off > Detach > ... | ||
2581 | LLVOAvatar* pAvatar; LLViewerJointAttachment* pAttachmentPt; | ||
2582 | if ( ((pAvatar = gAgent.getAvatarObject()) != NULL) && // Make sure we're actually wearing something on the attachment point | ||
2583 | ((pAttachmentPt = get_if_there(pAvatar->mAttachmentPoints, (S32)idxAttachPt, (LLViewerJointAttachment*)NULL)) != NULL) && | ||
2584 | (isStrippable(pAttachmentPt->getItemID())) ) // ... and that it's not marked as "nostrip" | ||
2585 | { | ||
2586 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | ||
2587 | // If we're stripping something that's part of a composite folder then we should @detachthis instead | ||
2588 | if (isCompositeDescendent(pAttachmentPt->getItemID())) | ||
2589 | { | ||
2590 | std::string strCmd = "detachthis:" + strOption + "=force"; | ||
2591 | #ifdef RLV_DEBUG | ||
2592 | RLV_INFOS << "\t- '" << strOption << "' belongs to composite folder: @" << strCmd << LL_ENDL; | ||
2593 | #endif // RLV_DEBUG | ||
2594 | processForceCommand(idObj, RlvCommand(strCmd)); | ||
2595 | } | ||
2596 | else | ||
2597 | #endif // RLV_EXPERIMENTAL_COMPOSITES | ||
2598 | { | ||
2599 | handle_detach_from_avatar(pAttachmentPt); | ||
2600 | } | ||
2601 | } | ||
2602 | return RLV_RET_NOERROR; | ||
2589 | } | 2603 | } |
2604 | return RLV_RET_FAILED_OPTION; | ||
2590 | } | 2605 | } |
2591 | 2606 | ||
2592 | // ============================================================================ | 2607 | // ============================================================================ |
diff --git a/linden/indra/newview/rlvhandler.h b/linden/indra/newview/rlvhandler.h index 5295a72..6821149 100644 --- a/linden/indra/newview/rlvhandler.h +++ b/linden/indra/newview/rlvhandler.h | |||
@@ -16,9 +16,8 @@ | |||
16 | // ============================================================================ | 16 | // ============================================================================ |
17 | 17 | ||
18 | typedef std::map<LLUUID, RlvObject> rlv_object_map_t; | 18 | typedef std::map<LLUUID, RlvObject> rlv_object_map_t; |
19 | typedef std::multimap<S32, LLUUID> rlv_detach_map_t; | ||
20 | typedef std::map<S32, LLUUID> rlv_reattach_map_t; | ||
21 | typedef std::multimap<ERlvBehaviour, RlvException> rlv_exception_map_t; | 19 | typedef std::multimap<ERlvBehaviour, RlvException> rlv_exception_map_t; |
20 | typedef std::map<S32, LLUUID> rlv_attachlock_map_t; | ||
22 | 21 | ||
23 | class RlvHandler | 22 | class RlvHandler |
24 | { | 23 | { |
@@ -47,7 +46,9 @@ public: | |||
47 | /* | 46 | /* |
48 | * Rule checking functions | 47 | * Rule checking functions |
49 | */ | 48 | */ |
50 | // NOTE: - to check @detach=n -> hasLockedAttachment() / hasLockedHUD() / isDetachable() | 49 | // NOTE: - to check @detach=n -> hasLockedAttachment(RLV_LOCK_REMOVE) / hasLockedHUD() / isLockedAttachment(.., RLV_LOCK_REMOVE) |
50 | // - to check @addattach=n -> hasLockedAttachment(RLV_LOCK_ADD) / isLockedAttachment(.., RLV_LOCK_ADD) | ||
51 | // - to check @remattach=n -> (see @detach=n) | ||
51 | // - to check exceptions -> isException() | 52 | // - to check exceptions -> isException() |
52 | // - to check @addoutfit=n -> isWearable() | 53 | // - to check @addoutfit=n -> isWearable() |
53 | // - to check @remoutfit=n -> isRemovable() | 54 | // - to check @remoutfit=n -> isRemovable() |
@@ -59,20 +60,21 @@ public: | |||
59 | bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const; | 60 | bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUID& idObj) const; |
60 | bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const; | 61 | bool hasBehaviourExcept(ERlvBehaviour eBehaviour, const std::string& strOption, const LLUUID& idObj) const; |
61 | 62 | ||
62 | // Returns TRUE if there is at least 1 non-detachable attachment | 63 | // Adds an eLock type lock (held by idRlvObj) for the specified attachment point |
63 | bool hasLockedAttachment() const { return (0 != m_Attachments.size()); } | 64 | void addAttachmentLock(S32 idxAttachPt, const LLUUID& idRlvObj, ERlvLockMask eLock); |
65 | // Returns TRUE if there is at least 1 eLock type locked attachment (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE) | ||
66 | bool hasLockedAttachment(ERlvLockMask eLock) const; | ||
64 | // Returns TRUE if there is at least 1 non-detachable HUD attachment | 67 | // Returns TRUE if there is at least 1 non-detachable HUD attachment |
65 | bool hasLockedHUD() const; | 68 | bool hasLockedHUD() const; |
66 | // Returns TRUE if the specified attachment point is detachable | 69 | // Returns TRUE if the specified attachment point is eLock type locked (RLV_LOCK_ANY = RLV_LOCK_ADD *or* RLV_LOCK_REMOVE) |
67 | bool isDetachable(S32 idxAttachPt) const { return (idxAttachPt) && (m_Attachments.find(idxAttachPt) == m_Attachments.end()); } | 70 | bool isLockedAttachment(S32 idxAttachPt, ERlvLockMask eLock) const; |
68 | bool isDetachable(const LLInventoryItem* pItem) const; | 71 | bool isLockedAttachment(const LLInventoryItem* pItem, ERlvLockMask eLock) const; |
69 | bool isDetachable(LLViewerJointAttachment* pAttachPt) const; | 72 | bool isLockedAttachment(LLViewerJointAttachment* pAttachPt, ERlvLockMask eLock) const; |
70 | bool isDetachable(LLViewerObject* pObj) const; | 73 | bool isLockedAttachment(LLViewerObject* pObj, ERlvLockMask eLock) const; |
71 | // Returns TRUE if the specified attachment point is set non-detachable by anything other than pObj (or one of its children) | 74 | // Returns TRUE if the specified attachment point is eLock type locked by anything other than pObj (or one of its children) |
72 | bool isDetachableExcept(S32 idxAttachPt, LLViewerObject* pObj) const; | 75 | bool isLockedAttachmentExcept(S32 idxAttachPt, ERlvLockMask eLock, LLViewerObject* pObj) const; |
73 | // Marks the specified attachment point as (non-)detachable (return value indicates success ; used by unit tests) | 76 | // Adds an eLock type lock (held by idRlvObj) for the specified attachment point |
74 | bool setDetachable(S32 idxAttachPt, const LLUUID& idRlvObj, bool fDetachable); | 77 | void removeAttachmentLock(S32 idxAttachPt, const LLUUID& idRlovObj, ERlvLockMask eLock); |
75 | bool setDetachable(LLViewerObject* pObj, const LLUUID& idRlvObj, bool fDetachable); | ||
76 | 78 | ||
77 | // Adds or removes an exception for the specified behaviour | 79 | // Adds or removes an exception for the specified behaviour |
78 | void addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption); | 80 | void addException(const LLUUID& idObj, ERlvBehaviour eBhvr, const RlvExceptionOption& varOption); |
@@ -183,19 +185,28 @@ public: | |||
183 | void notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal); | 185 | void notifyBehaviourObservers(const RlvCommand& rlvCmd, bool fInternal); |
184 | 186 | ||
185 | // Externally invoked event handlers | 187 | // Externally invoked event handlers |
186 | void onAttach(LLViewerJointAttachment* pAttachPt, bool fFullyLoaded); // LLVOAvatar::attachObject() | 188 | void onAttach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::attachObject() |
187 | void onDetach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::detachObject() | 189 | void onDetach(LLViewerJointAttachment* pAttachPt); // LLVOAvatar::detachObject() |
188 | bool onGC(); // RlvGCTimer::tick() | 190 | bool onGC(); // RlvGCTimer::tick() |
189 | void onSavedAssetIntoInventory(const LLUUID& idItem); // LLInventoryModel::processSaveAssetIntoInventory() | 191 | void onSavedAssetIntoInventory(const LLUUID& idItem) { if (m_pAttachMgr) m_pAttachMgr->onSavedAssetIntoInventory(idItem); } |
192 | void onWearAttachment(const LLUUID& idItem) { if (m_pAttachMgr) m_pAttachMgr->onWearAttachment(idItem); } | ||
190 | protected: | 193 | protected: |
191 | BOOL processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); | 194 | BOOL processAddCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); |
192 | BOOL processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); | 195 | BOOL processRemoveCommand(const LLUUID& uuid, const RlvCommand& rlvCmd); |
193 | BOOL processClearCommand(const LLUUID& idObj, const RlvCommand& rlvCmd); | 196 | BOOL processClearCommand(const LLUUID idObj, const RlvCommand& rlvCmd); |
194 | BOOL processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const; | 197 | BOOL processReplyCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const; |
195 | BOOL processForceCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const; | 198 | BOOL processForceCommand(const LLUUID& uuid, const RlvCommand& rlvCmd) const; |
196 | 199 | ||
197 | // Command handlers (exist for no other reason than to keep the length of the processXXX functions down) | 200 | // Command handlers (exist for no other reason than to keep the length of the processXXX functions down) |
198 | void onForceDetach(const LLUUID& idObj, const std::string& strOption) const; | 201 | ERlvCmdRet onAddRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount); |
202 | ERlvCmdRet onAddRemDetach(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount); | ||
203 | ERlvCmdRet onAddRemOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd, bool& fRefCount); | ||
204 | ERlvCmdRet onForceDetach(const LLUUID& idObj, const RlvCommand& rlvCmd) const; | ||
205 | ERlvCmdRet onForceRemAttach(const LLUUID& idObj, const RlvCommand& rlvCmd) const; | ||
206 | ERlvCmdRet onForceRemOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd) const; | ||
207 | ERlvCmdRet onGetAttach(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply); | ||
208 | ERlvCmdRet onGetOutfit(const LLUUID& idObj, const RlvCommand& rlvCmd, std::string& strReply); | ||
209 | // Old style command handlers (need to be updated to return ERlvCmdRet) | ||
199 | void onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const; | 210 | void onForceRemOutfit(const LLUUID& idObj, const std::string& strOption) const; |
200 | bool onForceSit(const LLUUID& uuid, const std::string& strOption) const; | 211 | bool onForceSit(const LLUUID& uuid, const std::string& strOption) const; |
201 | void onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const; | 212 | void onForceWear(const std::string& strPath, bool fAttach, bool fMatchAll) const; |
@@ -221,29 +232,29 @@ public: | |||
221 | static const std::string cstrMsgTpLure; // Message sent to tplure sender when tplure restricted | 232 | static const std::string cstrMsgTpLure; // Message sent to tplure sender when tplure restricted |
222 | static const std::string cstrAnonyms[28]; | 233 | static const std::string cstrAnonyms[28]; |
223 | protected: | 234 | protected: |
224 | rlv_object_map_t m_Objects; // Map of objects that have active restrictions (by UUID) | 235 | rlv_object_map_t m_Objects; // Map of objects that have active restrictions (idObj -> RlvObject) |
225 | rlv_exception_map_t m_Exceptions; // Map of UUIDs that are exempt from the associated ERlvBehaviour | 236 | rlv_exception_map_t m_Exceptions; // Map of currently active restriction exceptions (ERlvBehaviour -> RlvException) |
226 | rlv_detach_map_t m_Attachments; // Map of locked attachments (attachment point index -> object that issued @detach=n) | 237 | rlv_attachlock_map_t m_AttachAdd; // Map of attachment points that can't be attached (idxAttachPt -> idObj) |
227 | S16 m_LayersAdd[WT_COUNT]; // Array of locked layers (reference counted) | 238 | rlv_attachlock_map_t m_AttachRem; // Map of attachment points that can't be detached (idxAttachPt -> idObj) |
228 | S16 m_LayersRem[WT_COUNT]; // Array of locked layers (reference counted) | 239 | S16 m_LayersAdd[WT_COUNT]; // Array of layers that can't be worn (reference counted) |
229 | S16 m_Behaviours[RLV_BHVR_COUNT]; | 240 | S16 m_LayersRem[WT_COUNT]; // Array of layers that can't be removed (reference counted) |
230 | 241 | S16 m_Behaviours[RLV_BHVR_COUNT]; | |
231 | rlv_retained_list_t m_Retained; | 242 | |
232 | rlv_reattach_map_t m_AttachPending; | 243 | rlv_retained_list_t m_Retained; |
233 | rlv_reattach_map_t m_DetachPending; | 244 | RlvGCTimer* m_pGCTimer; |
234 | RlvGCTimer* m_pGCTimer; | 245 | RlvWLSnapshot* m_pWLSnapshot; |
235 | RlvWLSnapshot* m_pWLSnapshot; | 246 | RlvAttachmentManager* m_pAttachMgr; |
236 | 247 | ||
237 | RlvCommand* m_pCurCommand; // Convenience (see @tpto) | 248 | RlvCommand* m_pCurCommand; // Convenience (see @tpto) |
238 | LLUUID m_idCurObject; // Convenience (see @tpto) | 249 | LLUUID m_idCurObject; // Convenience (see @tpto) |
239 | 250 | ||
240 | mutable RlvEventEmitter<RlvObserver> m_Emitter; | 251 | mutable RlvEventEmitter<RlvObserver> m_Emitter; |
241 | mutable std::list<RlvBehaviourObserver*> m_BhvrObservers; | 252 | mutable std::list<RlvBehaviourObserver*> m_BhvrObservers; |
242 | RlvBehaviourNotifyObserver* m_pBhvrNotify; | 253 | RlvBehaviourNotifyObserver* m_pBhvrNotify; |
243 | 254 | ||
244 | static BOOL m_fEnabled; // Use setEnabled() to toggle this | 255 | static BOOL m_fEnabled; // Use setEnabled() to toggle this |
245 | static BOOL m_fFetchStarted; // TRUE if we fired off an inventory fetch | 256 | static BOOL m_fFetchStarted; // TRUE if we fired off an inventory fetch |
246 | static BOOL m_fFetchComplete; // TRUE if everything was fetched | 257 | static BOOL m_fFetchComplete; // TRUE if everything was fetched |
247 | static RlvMultiStringSearch m_AttachLookup; // Lookup table for attachment names (lower case) | 258 | static RlvMultiStringSearch m_AttachLookup; // Lookup table for attachment names (lower case) |
248 | 259 | ||
249 | bool m_fCanCancelTp; | 260 | bool m_fCanCancelTp; |
@@ -258,8 +269,8 @@ protected: | |||
258 | */ | 269 | */ |
259 | public: | 270 | public: |
260 | const rlv_object_map_t* getObjectMap() const { return &m_Objects; } | 271 | const rlv_object_map_t* getObjectMap() const { return &m_Objects; } |
261 | const rlv_exception_map_t* getExceptionMap() const { return &m_Exceptions; } | 272 | //const rlv_exception_map_t* getExceptionMap() const { return &m_Exceptions; } |
262 | const rlv_detach_map_t* getDetachMap() const { return &m_Attachments; } | 273 | //const rlv_detach_map_t* getDetachMap() const { return &m_Attachments; } |
263 | #ifdef RLV_DEBUG_TESTS | 274 | #ifdef RLV_DEBUG_TESTS |
264 | const S16* getAddLayers() const { return m_LayersAdd; } | 275 | const S16* getAddLayers() const { return m_LayersAdd; } |
265 | const S16* getRemLayers() const { return m_LayersRem; } | 276 | const S16* getRemLayers() const { return m_LayersRem; } |
@@ -345,6 +356,13 @@ inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUI | |||
345 | return hasBehaviourExcept(eBehaviour, std::string(), idObj); | 356 | return hasBehaviourExcept(eBehaviour, std::string(), idObj); |
346 | } | 357 | } |
347 | 358 | ||
359 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a | ||
360 | inline bool RlvHandler::hasLockedAttachment(ERlvLockMask eLock) const | ||
361 | { | ||
362 | // Remove locks are more common so check those first | ||
363 | return ( (eLock & RLV_LOCK_REMOVE) && (!m_AttachRem.empty()) ) || ( (eLock & RLV_LOCK_ADD) && (!m_AttachAdd.empty()) ); | ||
364 | } | ||
365 | |||
348 | #ifdef RLV_EXPERIMENTAL_COMPOSITES | 366 | #ifdef RLV_EXPERIMENTAL_COMPOSITES |
349 | // Checked: | 367 | // Checked: |
350 | inline bool RlvHandler::isCompositeFolder(const LLInventoryCategory* pFolder) const | 368 | inline bool RlvHandler::isCompositeFolder(const LLInventoryCategory* pFolder) const |
@@ -359,20 +377,6 @@ inline bool RlvHandler::hasBehaviourExcept(ERlvBehaviour eBehaviour, const LLUUI | |||
359 | } | 377 | } |
360 | #endif // RLV_EXPERIMENTAL_COMPOSITES | 378 | #endif // RLV_EXPERIMENTAL_COMPOSITES |
361 | 379 | ||
362 | // Checked: 2009-09-08 (RLVa-1.0.2c) | Added: RLVa-1.0.2c | ||
363 | inline bool RlvHandler::isDetachable(LLViewerJointAttachment *pAttachPt) const | ||
364 | { | ||
365 | // If there's an attached object it's faster to just use that; otherwise look up the attachment index because it might be locked empty | ||
366 | return (pAttachPt == NULL) || | ||
367 | ( (pAttachPt->getObject() != NULL) && isDetachable(pAttachPt->getObject()) ) || (isDetachable(getAttachPointIndex(pAttachPt))); | ||
368 | } | ||
369 | |||
370 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
371 | inline bool RlvHandler::isDetachable(LLViewerObject* pObj) const | ||
372 | { | ||
373 | return (pObj == NULL) || (!pObj->isAttachment()) || (isDetachable(getAttachPointIndex(pObj))); | ||
374 | } | ||
375 | |||
376 | inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const | 380 | inline bool RlvHandler::isPermissive(ERlvBehaviour eBhvr) const |
377 | { | 381 | { |
378 | return (RlvCommand::hasStrictVariant(eBhvr)) | 382 | return (RlvCommand::hasStrictVariant(eBhvr)) |
@@ -395,6 +399,29 @@ inline bool RlvHandler::isFoldedFolder(const LLInventoryCategory* pFolder, bool | |||
395 | ); | 399 | ); |
396 | } | 400 | } |
397 | 401 | ||
402 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a | ||
403 | inline bool RlvHandler::isLockedAttachment(S32 idxAttachPt, ERlvLockMask eLock) const | ||
404 | { | ||
405 | return ( (eLock & RLV_LOCK_REMOVE) && (m_AttachRem.find(idxAttachPt) != m_AttachRem.end()) ) || | ||
406 | ( (eLock & RLV_LOCK_ADD) && (m_AttachAdd.find(idxAttachPt) != m_AttachAdd.end()) ); | ||
407 | } | ||
408 | |||
409 | |||
410 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a | ||
411 | inline bool RlvHandler::isLockedAttachment(LLViewerJointAttachment *pAttachPt, ERlvLockMask eLock) const | ||
412 | { | ||
413 | // If there's an attached object it's faster to just use that; otherwise look up the attachment index because it might be locked empty | ||
414 | return (pAttachPt != NULL) && | ||
415 | ( ( (pAttachPt->getObject() != NULL) && (isLockedAttachment(pAttachPt->getObject(), eLock)) ) || | ||
416 | (isLockedAttachment(getAttachPointIndex(pAttachPt), eLock)) ); | ||
417 | } | ||
418 | |||
419 | // Checked: 2009-10-10 (RLVa-1.0.5a) | Added: RLVa-1.0.5a | ||
420 | inline bool RlvHandler::isLockedAttachment(LLViewerObject* pObj, ERlvLockMask eLock) const | ||
421 | { | ||
422 | return (pObj != NULL) && (pObj->isAttachment()) && (isLockedAttachment(getAttachPointIndex(pObj), eLock)); | ||
423 | } | ||
424 | |||
398 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Added: RLVa-0.2.0d | 425 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Added: RLVa-0.2.0d |
399 | inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idObj) const | 426 | inline bool RlvHandler::isRemovableExcept(EWearableType type, const LLUUID& idObj) const |
400 | { | 427 | { |
@@ -434,12 +461,6 @@ inline void RlvHandler::retainCommand(const std::string& strObj, const LLUUID& i | |||
434 | m_Retained.push_back(RlvRetainedCommand(strObj, idObj, strCmd)); | 461 | m_Retained.push_back(RlvRetainedCommand(strObj, idObj, strCmd)); |
435 | } | 462 | } |
436 | 463 | ||
437 | // Checked: 2009-05-23 (RLVa-0.2.0d) | Modified: RLVa-0.2.0d | ||
438 | inline bool RlvHandler::setDetachable(LLViewerObject* pObj, const LLUUID& idRlvObj, bool fDetachable) | ||
439 | { | ||
440 | return setDetachable(getAttachPointIndex(pObj), idRlvObj, fDetachable); // getAttachPointIndex() has a NULL pointer check | ||
441 | } | ||
442 | |||
443 | // ============================================================================ | 464 | // ============================================================================ |
444 | 465 | ||
445 | #endif // RLV_HANDLER_H | 466 | #endif // RLV_HANDLER_H |
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 | // ========================================================================= | ||
diff --git a/linden/indra/newview/rlvhelper.h b/linden/indra/newview/rlvhelper.h index 42d10b8..25d8174 100644 --- a/linden/indra/newview/rlvhelper.h +++ b/linden/indra/newview/rlvhelper.h | |||
@@ -109,6 +109,80 @@ protected: | |||
109 | }; | 109 | }; |
110 | 110 | ||
111 | // ============================================================================ | 111 | // ============================================================================ |
112 | // RlvAttachmentManager - Self contained helper class that automagically takes care of the nitty gritty of force detaching/reattaching | ||
113 | // | ||
114 | |||
115 | class RlvAttachmentManager | ||
116 | { | ||
117 | public: | ||
118 | RlvAttachmentManager() : m_pTimer(NULL) {} | ||
119 | ~RlvAttachmentManager() { delete m_pTimer; } | ||
120 | |||
121 | /* | ||
122 | * Member functions | ||
123 | */ | ||
124 | public: | ||
125 | static void forceAttach(const LLUUID& idItem, S32 idxAttachPt); | ||
126 | static void forceDetach(LLViewerJointAttachment* pAttachPt); | ||
127 | protected: | ||
128 | void startTimer() { if (!m_pTimer) m_pTimer = new RlvAttachmentManagerTimer(this); } | ||
129 | |||
130 | /* | ||
131 | * Event handlers | ||
132 | */ | ||
133 | public: | ||
134 | void onAttach(LLViewerJointAttachment* pAttachPt); | ||
135 | void onDetach(LLViewerJointAttachment* pAttachPt); | ||
136 | void onSavedAssetIntoInventory(const LLUUID& idItem); | ||
137 | BOOL onTimer(); | ||
138 | void onWearAttachment(const LLUUID& idItem); | ||
139 | |||
140 | /* | ||
141 | * Member variables | ||
142 | */ | ||
143 | protected: | ||
144 | typedef std::map<S32, LLUUID> rlv_detach_map_t; | ||
145 | rlv_detach_map_t m_PendingDetach; | ||
146 | |||
147 | struct RlvReattachInfo | ||
148 | { | ||
149 | RlvReattachInfo(const LLUUID& itemid) : idItem(itemid), fAssetSaved(false), tsAttach(0) | ||
150 | { tsDetach = LLFrameTimer::getElapsedSeconds(); } | ||
151 | |||
152 | LLUUID idItem; | ||
153 | bool fAssetSaved; | ||
154 | F64 tsDetach; | ||
155 | F64 tsAttach; | ||
156 | protected: | ||
157 | RlvReattachInfo(); | ||
158 | }; | ||
159 | typedef std::map<S32, RlvReattachInfo> rlv_attach_map_t; | ||
160 | rlv_attach_map_t m_PendingAttach; | ||
161 | |||
162 | struct RlvWearInfo | ||
163 | { | ||
164 | RlvWearInfo(LLUUID itemid) : idItem(itemid) { tsWear = LLFrameTimer::getElapsedSeconds(); } | ||
165 | |||
166 | LLUUID idItem; | ||
167 | F64 tsWear; | ||
168 | std::map<S32, LLUUID> attachPts; | ||
169 | protected: | ||
170 | RlvWearInfo(); | ||
171 | }; | ||
172 | typedef std::map<LLUUID, RlvWearInfo> rlv_wear_map_t; | ||
173 | rlv_wear_map_t m_PendingWear; | ||
174 | |||
175 | class RlvAttachmentManagerTimer : public LLEventTimer | ||
176 | { | ||
177 | public: | ||
178 | RlvAttachmentManagerTimer(RlvAttachmentManager* pMgr) : LLEventTimer(10), m_pMgr(pMgr) {} | ||
179 | virtual ~RlvAttachmentManagerTimer() { m_pMgr->m_pTimer = NULL; } | ||
180 | virtual BOOL tick() { return m_pMgr->onTimer(); } | ||
181 | RlvAttachmentManager* m_pMgr; | ||
182 | } *m_pTimer; | ||
183 | }; | ||
184 | |||
185 | // ============================================================================ | ||
112 | // RlvCriteriaCategoryCollector - Criteria based folder matching filter used by @findfolder and @findfolders | 186 | // RlvCriteriaCategoryCollector - Criteria based folder matching filter used by @findfolder and @findfolders |
113 | // | 187 | // |
114 | 188 | ||
@@ -295,7 +369,10 @@ public: | |||
295 | 369 | ||
296 | struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor | 370 | struct RlvSelectHasLockedAttach : public LLSelectedNodeFunctor |
297 | { | 371 | { |
372 | RlvSelectHasLockedAttach(ERlvLockMask eLock) : m_eLock(eLock) {} | ||
298 | virtual bool apply(LLSelectNode* pNode); | 373 | virtual bool apply(LLSelectNode* pNode); |
374 | protected: | ||
375 | ERlvLockMask m_eLock; | ||
299 | }; | 376 | }; |
300 | 377 | ||
301 | struct RlvSelectIsOwnedByOrGroupOwned : public LLSelectedNodeFunctor | 378 | struct RlvSelectIsOwnedByOrGroupOwned : public LLSelectedNodeFunctor |
@@ -324,7 +401,6 @@ bool rlvIsEmote(const std::string& strUTF8Text); | |||
324 | bool rlvIsValidReplyChannel(S32 nChannel); | 401 | bool rlvIsValidReplyChannel(S32 nChannel); |
325 | bool rlvIsWearingItem(const LLInventoryItem* pItem); | 402 | bool rlvIsWearingItem(const LLInventoryItem* pItem); |
326 | 403 | ||
327 | void rlvForceDetach(LLViewerJointAttachment* pAttachPt); | ||
328 | void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null); | 404 | void rlvSendBusyMessage(const LLUUID& idTo, const std::string& strMsg, const LLUUID& idSession = LLUUID::null); |
329 | bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply); | 405 | bool rlvSendChatReply(const std::string& strChannel, const std::string& strReply); |
330 | bool rlvSendChatReply(S32 nChannel, const std::string& strReply); | 406 | bool rlvSendChatReply(S32 nChannel, const std::string& strReply); |