From 18ac6dcb605f982740e6a4765bbd913794843d52 Mon Sep 17 00:00:00 2001 From: Shyotl Date: Sun, 12 Jul 2015 02:35:14 -0500 Subject: [PATCH] Fix 'Wear' action if a wearable of that asset id is already worn; option should now be disabled if there's already a worn wearable with a matching assetid that would NOT be replaced by said 'Wear' action. (It should work otherwise). --- indra/llappearance/llwearabledata.cpp | 5 ++- indra/newview/llagentwearables.cpp | 59 +++++++++++++++++++-------- indra/newview/llappearancemgr.cpp | 6 +++ indra/newview/llinventorybridge.cpp | 17 ++++---- 4 files changed, 61 insertions(+), 26 deletions(-) diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp index f81e7eee9..24c011d6f 100644 --- a/indra/llappearance/llwearabledata.cpp +++ b/indra/llappearance/llwearabledata.cpp @@ -88,7 +88,10 @@ void LLWearableData::setWearable(const LLWearableType::EType type, U32 index, LL else { wearable_vec[index] = wearable; - old_wearable->setUpdated(); + if (old_wearable != wearable) //Avoid redundant update + { + old_wearable->setUpdated(); + } const BOOL removed = FALSE; wearableUpdated(wearable, removed); } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 5e4cd8f3a..379fe7243 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1389,7 +1389,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it llassert(items.size() == count); // Check for whether outfit already matches the one requested - S32 matched = 0, mismatched = 0; + S32 matched = 0, mismatched = 0, local_updates = 0; const S32 arr_size = LLWearableType::WT_COUNT; S32 type_counts[arr_size]; std::fill(type_counts,type_counts+arr_size,0); @@ -1408,9 +1408,38 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it S32 index = type_counts[type]; type_counts[type]++; - LLViewerWearable *curr_wearable = dynamic_cast(getWearable(type,index)); - if (!new_wearable || !curr_wearable || - new_wearable->getAssetID() != curr_wearable->getAssetID()) + LLViewerWearable *curr_wearable = dynamic_cast(getWearable(type, index)); + + const LLUUID curr_id = curr_wearable ? curr_wearable->getItemID() : LLUUID::null; + const std::string curr_name = curr_wearable ? curr_wearable->getName() : std::string(); + + if (curr_id == new_item->getUUID()) //Nothing to do. No change.. + { + matched++; + continue; + } + + new_wearable->setName(new_item->getName()); + new_wearable->setItemID(new_item->getUUID()); + + bool matching_asset = new_wearable && curr_wearable && new_wearable->getAssetID() == curr_wearable->getAssetID(); + + if (matching_asset || LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART) + { + //Simple replacement at index. + setWearable(type, index, new_wearable); //Stomp the old wearable, but don't increment mismatched. setWearable calls wearableUpdate. + if (new_wearable == curr_wearable) //If both new and cur are the same underlying wearable, then the old id got overwritten in the setItemId call above. + //Need to manually call addChangedMasked on the prior id. + { + gInventory.addChangedMask(LLInventoryObserver::LABEL, curr_id); + } + if (matching_asset) + local_updates++; + else + mismatched++; //Need to update visual parameters and such things. + continue; + } + else { LL_DEBUGS("Avatar") << "mismatch, type " << type << " index " << index << " names " << (curr_wearable ? curr_wearable->getName() : "NONE") << "," @@ -1451,6 +1480,11 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL; mCOFChangeInProgress = false; + if (local_updates) + { + LL_DEBUGS("Avatar") << "local_updates " << local_updates << " wearable itemIDs" << LL_ENDL; + gInventory.notifyObservers(); + } return; } @@ -1475,22 +1509,11 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it if (new_wearable) { const LLWearableType::EType type = new_wearable->getType(); - - new_wearable->setName(new_item->getName()); - new_wearable->setDescription(new_item->getDescription()); - new_wearable->setItemID(new_item->getUUID()); - - if (LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART) + + if (LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING) { - // exactly one wearable per body part - setWearable(type,0,new_wearable); + pushWearable(type,new_wearable); //pushWearable calls wearableUpdate. } - else - { - pushWearable(type,new_wearable); - } - const BOOL removed = FALSE; - wearableUpdated(new_wearable, removed); } } diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index b4ddfc50f..956557af3 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -1460,6 +1460,12 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear, { continue; } + else if (item_to_wear->isWearableType()) + { + LLViewerWearable* wearable = gAgentWearables.getWearableFromAssetID(item_to_wear->getAssetUUID()); + if (wearable && (!replace || wearable != gAgentWearables.getTopWearable(item_to_wear->getWearableType()))) + continue; + } // [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8) replace |= (LLAssetType::AT_BODYPART == item_to_wear->getType()); // Body parts should always replace diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0d94cc4ec..28fe64695 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -5932,6 +5932,8 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Take Off")); // Fallthrough since clothing and bodypart share wear options case LLAssetType::AT_BODYPART: + items.push_back(std::string("Wearable And Object Wear")); + if (get_is_item_worn(item->getUUID())) { disabled_items.push_back(std::string("Wearable And Object Wear")); @@ -5943,10 +5945,15 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) } else { - items.push_back(std::string("Wearable And Object Wear")); disabled_items.push_back(std::string("Take Off")); disabled_items.push_back(std::string("Wearable Edit")); - + if (gAgentWearables.getWearableFromAssetID(item->getAssetUUID())) + { + disabled_items.push_back(std::string("Wearable Add")); + LLViewerWearable* wearable = gAgentWearables.getWearableFromAssetID(item->getAssetUUID()); + if (cof_pending || (wearable && wearable != gAgentWearables.getTopWearable(mWearableType))) + disabled_items.push_back(std::string("Wearable And Object Wear")); + } // [RLVa:KB] - Checked: 2010-06-09 (RLVa-1.2.0g) | Modified: RLVa-1.2.0g if (rlv_handler_t::isEnabled()) { @@ -5971,11 +5978,7 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) if(!is_worn || !gAgentWearables.canMoveWearable(item->getUUID(),true)) disabled_items.push_back(std::string("Wearable Move Back")); -// if (!gAgentWearables.canAddWearable(mWearableType)) -// [SL:KB] - Patch: Appearance-WearableDuplicateAssets | Checked: 2011-07-24 (Catznip-2.6.0e) | Added: Catznip-2.6.0e - if (!gAgentWearables.canAddWearable(mWearableType) || - (gAgentWearables.getWearableFromAssetID(item->getAssetUUID())) ) -// [/SL:KB] + if (!gAgentWearables.canAddWearable(mWearableType)) { disabled_items.push_back(std::string("Wearable Add")); }