From 2caa710a46d3baa1e6a884961f1ff756d35ef5df Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Thu, 3 Jun 2010 20:06:25 -0400 Subject: VWR-19699 WIP Correct operations for wear and replace on wearables Resident-submitted patch, cleaned up so it matches style and compiles/builds well. Appears to work for stated goals but will need some more UI work to ensure consistency. WIP checkin, will be code reviewed before pushing. --- doc/contributions.txt | 2 + indra/newview/llappearancemgr.cpp | 33 +++++- indra/newview/llinventorybridge.cpp | 112 +-------------------- indra/newview/llinventorybridge.h | 2 - indra/newview/llinventorymodel.cpp | 3 +- indra/newview/lltooldraganddrop.cpp | 19 +--- indra/newview/llviewerinventory.cpp | 2 +- indra/newview/llviewerinventory.h | 6 ++ .../skins/default/xui/en/menu_inventory.xml | 8 ++ 9 files changed, 53 insertions(+), 134 deletions(-) diff --git a/doc/contributions.txt b/doc/contributions.txt index 3f33763ce0..5667b69c28 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -323,6 +323,8 @@ Khyota Wulluf VWR-8885 VWR-9256 VWR-9966 +Kitty Barnett + VWR-19699 Kunnis Basiat VWR-82 VWR-102 diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e6f363028a..5071b1c14a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -656,15 +656,40 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up { if (item_id_to_wear.isNull()) return false; - //only the item from a user's inventory is allowed - if (!gInventory.isObjectDescendentOf(item_id_to_wear, gInventory.getRootFolderID())) return false; - LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); if (!item_to_wear) return false; + if (!item_to_wear->isFinished()) + { + LLNotificationsUtil::add("CannotWearInfoNotComplete"); + return false; + } + else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) + { + LLPointer cb = new WearOnAvatarCallback(replace); + copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb); + return false; + } + else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID())) + { + return false; // not in library and not in agent's inventory + } + else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) + { + LLNotificationsUtil::add("CannotWearTrash"); + } + switch (item_to_wear->getType()) { case LLAssetType::AT_CLOTHING: + if (replace && gAgentWearables.areWearablesLoaded()) + { + S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType()); + if (wearable_count != 0) + { + removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false); + } + } case LLAssetType::AT_BODYPART: // Don't wear anything until initial wearables are loaded, can // destroy clothing items. @@ -676,7 +701,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up // Remove the existing wearables of the same type. // Remove existing body parts anyway because we must not be able to wear e.g. two skins. - if (replace || item_to_wear->getType() == LLAssetType::AT_BODYPART) + if (item_to_wear->getType() == LLAssetType::AT_BODYPART) { removeCOFLinksOfType(item_to_wear->getWearableType(), false); } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b7495f7dbe..827688ec29 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -103,7 +103,6 @@ void dec_busy_count() } // Function declarations -void wear_add_inventory_item_on_avatar(LLInventoryItem* item); void remove_inventory_category_from_avatar(LLInventoryCategory* category); void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id); bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*); @@ -4295,33 +4294,6 @@ LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory, mInvType = inv_type; } -// *NOTE: hack to get from avatar inventory to avatar -void wear_inventory_item_on_avatar( LLInventoryItem* item ) -{ - if(item) - { - lldebugs << "wear_inventory_item_on_avatar( " << item->getName() - << " )" << llendl; - - LLAppearanceMgr::getInstance()->wearItemOnAvatar(item->getUUID(), true, false); - } -} - -void wear_add_inventory_item_on_avatar( LLInventoryItem* item ) -{ - if(item) - { - lldebugs << "wear_add_inventory_item_on_avatar( " << item->getName() - << " )" << llendl; - - LLWearableList::instance().getAsset(item->getAssetUUID(), - item->getName(), - item->getType(), - LLWearableBridge::onWearAddOnAvatarArrived, - new LLUUID(item->getUUID())); - } -} - void remove_inventory_category_from_avatar( LLInventoryCategory* category ) { if(!category) return; @@ -4637,21 +4609,7 @@ void LLWearableBridge::wearOnAvatar() LLViewerInventoryItem* item = getItem(); if(item) { - if(!isAgentInventory()) - { - LLPointer cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else - { - wear_inventory_item_on_avatar(item); - } + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true); } } @@ -4668,21 +4626,7 @@ void LLWearableBridge::wearAddOnAvatar() LLViewerInventoryItem* item = getItem(); if(item) { - if(!isAgentInventory()) - { - LLPointer cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else - { - wear_add_inventory_item_on_avatar(item); - } + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, false); } } @@ -5207,41 +5151,7 @@ class LLWearableBridgeAction: public LLInvFVBridgeAction public: virtual void doIt() { - if(isItemInTrash()) - { - LLNotificationsUtil::add("CannotWearTrash"); - } - else if(isAgentInventory()) - { - if(!get_is_item_worn(mUUID)) - { - wearOnAvatar(); - } - } - else - { - // must be in the inventory library. copy it to our inventory - // and put it on right away. - LLViewerInventoryItem* item = getItem(); - if(item && item->isFinished()) - { - LLPointer cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else if(item) - { - // *TODO: We should fetch the item details, and then do - // the operation above. - LLNotificationsUtil::add("CannotWearInfoNotComplete"); - } - } - LLInvFVBridgeAction::doIt(); + wearOnAvatar(); } virtual ~LLWearableBridgeAction(){} protected: @@ -5280,21 +5190,7 @@ void LLWearableBridgeAction::wearOnAvatar() LLViewerInventoryItem* item = getItem(); if(item) { - if(!isAgentInventory()) - { - LLPointer cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else - { - wear_inventory_item_on_avatar(item); - } + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true); } } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 59c1f3d6fb..dcf0487250 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -592,8 +592,6 @@ public: U32 flags = 0x00) const; }; -void wear_inventory_item_on_avatar(LLInventoryItem* item); - void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 2e1c5238d3..6fc5804a48 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -35,6 +35,7 @@ #include "llagent.h" #include "llagentwearables.h" +#include "llappearancemgr.h" #include "llinventorypanel.h" #include "llinventorybridge.h" #include "llinventoryfunctions.h" @@ -2561,7 +2562,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**) { LLViewerInventoryItem* wearable_item; wearable_item = gInventory.getItem(wearable_ids[i]); - wear_inventory_item_on_avatar(wearable_item); + LLAppearanceMgr::instance().wearItemOnAvatar(wearable_item->getUUID(), true, true); } } diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index bc77ac5fd1..c862c02b82 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1878,24 +1878,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem( LLNotificationsUtil::add("CanNotChangeAppearanceUntilLoaded"); return ACCEPT_NO; } - - if (mSource == SOURCE_LIBRARY) - { - // create item based on that one, and put it on if that - // was a success. - LLPointer cb = new WearOnAvatarCallback(); - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - LLUUID::null, - std::string(), - cb); - } - else - { - wear_inventory_item_on_avatar( item ); - } + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(),true, !(mask & MASK_CONTROL)); } return ACCEPT_YES_MULTI; } diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d745356dcd..face7124c2 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -875,7 +875,7 @@ void WearOnAvatarCallback::fire(const LLUUID& inv_item) LLViewerInventoryItem *item = gInventory.getItem(inv_item); if (item) { - wear_inventory_item_on_avatar(item); + LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace); } } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 8ab7c9710d..d0d3ad693e 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -243,7 +243,13 @@ public: class WearOnAvatarCallback : public LLInventoryCallback { +public: + WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {} + void fire(const LLUUID& inv_item); + +protected: + bool mReplace; }; class ModifiedCOFCallback : public LLInventoryCallback diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 11459ad0e6..221457ac1f 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -661,6 +661,14 @@ function="Inventory.DoToSelected" parameter="wear" /> + + + Date: Thu, 3 Jun 2010 21:09:49 -0400 Subject: AVP-44 WIP Multi-wearables architecture One step closer to full support of multi-wearables architecture code will be reviewed before pushing. --- indra/newview/llappearancemgr.cpp | 21 ++++++++++---- indra/newview/llviewermenu.cpp | 5 ++-- indra/newview/llvoavatarself.cpp | 60 +++++++++++++++++++++++---------------- indra/newview/llwearable.cpp | 2 +- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5071b1c14a..9da47c9214 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -682,14 +682,15 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up switch (item_to_wear->getType()) { case LLAssetType::AT_CLOTHING: - if (replace && gAgentWearables.areWearablesLoaded()) + if (gAgentWearables.areWearablesLoaded()) { S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType()); - if (wearable_count != 0) + if ((replace && wearable_count != 0) || + (wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) ) { removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false); } - } + } case LLAssetType::AT_BODYPART: // Don't wear anything until initial wearables are loaded, can // destroy clothing items. @@ -1584,6 +1585,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update item_array, LLInventoryModel::EXCLUDE_TRASH); bool linked_already = false; + U32 count = 0; for (S32 i=0; iisWearableType()) && (vitem->getWearableType() == wearable_type)) + else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type)) { - if (inv_item->getIsLinkType() && (vitem->getWearableType() == wearable_type)) + if (is_body_part && inv_item->getIsLinkType() && (vitem->getWearableType() == wearable_type)) + { + gInventory.purgeObject(inv_item->getUUID()); + } + ++count; + + // MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE + if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) { gInventory.purgeObject(inv_item->getUUID()); } } } + if (linked_already) { if (do_update) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a1b909c609..23fb97a358 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7497,8 +7497,9 @@ class LLEditTakeOff : public view_listener_t LLWearableType::EType type = LLWearableType::typeNameToType(clothing); if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT) { - // MULTI-WEARABLES - LLViewerInventoryItem *item = dynamic_cast(gAgentWearables.getWearableInventoryItem(type,0)); + // MULTI-WEARABLES: assuming user wanted to remove top shirt. + U32 wearable_index = gAgentWearables.getWearableCount(type) - 1; + LLViewerInventoryItem *item = dynamic_cast(gAgentWearables.getWearableInventoryItem(type,wearable_index)); LLWearableBridge::removeItemFromAvatar(item); } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 462c442954..af042b4e3e 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1975,37 +1975,47 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const ++iter) { const ETextureIndex t_index = (*iter); - lldebugs << "Checking index " << (U32) t_index << llendl; - // MULTI-WEARABLE: old method. replace. - const LLUUID& texture_id = getTEImage( t_index )->getID(); - if (texture_id != IMG_DEFAULT_AVATAR) - { - // Search inventory for this texture. - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(texture_id); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - - BOOL can_grab = FALSE; - lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl; - if (items.count()) + LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(t_index); + U32 count = gAgentWearables.getWearableCount(wearable_type); + lldebugs << "Checking index " << (U32) t_index << " count: " << count << llendl; + + for (U32 wearable_index = 0; wearable_index < count; ++wearable_index) + { + LLWearable *wearable = gAgentWearables.getWearable(wearable_type, wearable_index); + if (wearable) { - // search for full permissions version - for (S32 i = 0; i < items.count(); i++) + const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index); + const LLUUID& texture_id = texture->getID(); + if (texture_id != IMG_DEFAULT_AVATAR) { - LLViewerInventoryItem* itemp = items[i]; - if (itemp->getIsFullPerm()) + // Search inventory for this texture. + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(texture_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + BOOL can_grab = FALSE; + lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl; + if (items.count()) { - can_grab = TRUE; - break; + // search for full permissions version + for (S32 i = 0; i < items.count(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp->getIsFullPerm()) + { + can_grab = TRUE; + break; + } + } } + if (!can_grab) return FALSE; } } - if (!can_grab) return FALSE; } } diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 9e9b46473e..121e691710 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -656,7 +656,7 @@ void LLWearable::writeToAvatar() image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te); } LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE ); - // MULTI-WEARABLE: replace hard-coded 0 + // MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this. gAgentAvatarp->setLocalTextureTE(te, image, 0); } } -- cgit v1.2.3 From 244321e70cf341ca0542a9963d9e1e68cafca8d5 Mon Sep 17 00:00:00 2001 From: "Nyx (Neal Orman)" Date: Fri, 4 Jun 2010 17:34:46 -0400 Subject: AVP-44 VWR-19699 FIX Multi-wearables and wearable replacement logic Cleaned up a few things upon code review. Code reviewed by vir for this checkin as well as following previous commits: a801af3728ee af42810b946c --- indra/newview/llappearancemgr.cpp | 15 +++++---------- indra/newview/llviewermenu.cpp | 4 +++- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 9da47c9214..a899926938 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -659,12 +659,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear); if (!item_to_wear) return false; - if (!item_to_wear->isFinished()) - { - LLNotificationsUtil::add("CannotWearInfoNotComplete"); - return false; - } - else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) + if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID())) { LLPointer cb = new WearOnAvatarCallback(replace); copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb); @@ -677,6 +672,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) { LLNotificationsUtil::add("CannotWearTrash"); + return false; } switch (item_to_wear->getType()) @@ -1605,15 +1601,14 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update // type? If so, new item will replace old. else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type)) { + ++count; if (is_body_part && inv_item->getIsLinkType() && (vitem->getWearableType() == wearable_type)) { gInventory.purgeObject(inv_item->getUUID()); } - ++count; - - // MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE - if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) + else if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) { + // MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE gInventory.purgeObject(inv_item->getUUID()); } } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 23fb97a358..2c7ae539ce 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7495,7 +7495,9 @@ class LLEditTakeOff : public view_listener_t else { LLWearableType::EType type = LLWearableType::typeNameToType(clothing); - if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT) + if (type >= LLWearableType::WT_SHAPE + && type < LLWearableType::WT_COUNT + && (gAgentWearables.getWearableCount(type) > 0)) { // MULTI-WEARABLES: assuming user wanted to remove top shirt. U32 wearable_index = gAgentWearables.getWearableCount(type) - 1; -- cgit v1.2.3