diff options
-rw-r--r-- | doc/contributions.txt | 2 | ||||
-rw-r--r-- | indra/newview/llappearancemgr.cpp | 48 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.cpp | 112 | ||||
-rw-r--r-- | indra/newview/llinventorybridge.h | 2 | ||||
-rw-r--r-- | indra/newview/llinventorymodel.cpp | 3 | ||||
-rw-r--r-- | indra/newview/lltooldraganddrop.cpp | 19 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.cpp | 2 | ||||
-rw-r--r-- | indra/newview/llviewerinventory.h | 6 | ||||
-rw-r--r-- | indra/newview/llviewermenu.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llvoavatarself.cpp | 60 | ||||
-rw-r--r-- | indra/newview/llwearable.cpp | 2 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/menu_inventory.xml | 8 |
12 files changed, 104 insertions, 165 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..9da47c9214 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -656,15 +656,41 @@ 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<LLInventoryCallback> 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 (gAgentWearables.areWearablesLoaded()) + { + S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType()); + 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. @@ -676,7 +702,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); } @@ -1559,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; i<item_array.count(); i++) { // Are these links to the same object? @@ -1576,15 +1603,22 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update } // Are these links to different items of the same body part // type? If so, new item will replace old. - // TODO: MULTI-WEARABLE: check for wearable limit for clothing types - else if (is_body_part && (vitem->isWearableType()) && (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/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0e63c21e16..3a9c5ba698 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*); @@ -4277,33 +4276,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; @@ -4619,21 +4591,7 @@ void LLWearableBridge::wearOnAvatar() LLViewerInventoryItem* item = getItem(); if(item) { - if(!isAgentInventory()) - { - LLPointer<LLInventoryCallback> 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); } } @@ -4650,21 +4608,7 @@ void LLWearableBridge::wearAddOnAvatar() LLViewerInventoryItem* item = getItem(); if(item) { - if(!isAgentInventory()) - { - LLPointer<LLInventoryCallback> 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); } } @@ -5189,41 +5133,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<LLInventoryCallback> 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: @@ -5262,21 +5172,7 @@ void LLWearableBridgeAction::wearOnAvatar() LLViewerInventoryItem* item = getItem(); if(item) { - if(!isAgentInventory()) - { - LLPointer<LLInventoryCallback> 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 310fd7fb1d..a342a2da14 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -591,8 +591,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<LLInventoryCallback> 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/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<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,0)); + // MULTI-WEARABLES: assuming user wanted to remove top shirt. + U32 wearable_index = gAgentWearables.getWearableCount(type) - 1; + LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index)); LLWearableBridge::removeItemFromAvatar(item); } diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index e18b617120..c838a8820f 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1977,37 +1977,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); } } 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 @@ -662,6 +662,14 @@ parameter="wear" /> </menu_item_call> <menu_item_call + label="Add" + layout="topleft" + name="Wearable Add"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="wear_add" /> + </menu_item_call> + <menu_item_call label="Take Off" layout="topleft" name="Take Off"> |