From d895fc2497bdf458d479178d622cd8032d67361f Mon Sep 17 00:00:00 2001 From: Kitty Barnett Date: Wed, 13 Feb 2013 20:33:21 +0100 Subject: [PATCH] - internal : restore RLVa code in LLAgentWearables --HG-- branch : RLVa --- indra/llappearance/llwearabledata.cpp | 46 +++++--- indra/llappearance/llwearabledata.h | 2 +- indra/newview/llagentwearables.cpp | 156 ++++++++++++++++---------- indra/newview/llagentwearables.h | 9 +- 4 files changed, 137 insertions(+), 76 deletions(-) diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp index 68fdcca782..ae67f36194 100644 --- a/indra/llappearance/llwearabledata.cpp +++ b/indra/llappearance/llwearabledata.cpp @@ -102,16 +102,36 @@ U32 LLWearableData::pushWearable(const LLWearableType::EType type, llwarns << "Null wearable sent for type " << type << llendl; return MAX_CLOTHING_PER_TYPE; } - if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) +// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0) + if ( (type < LLWearableType::WT_COUNT) && (mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) ) { - mWearableDatas[type].push_back(wearable); + // Don't add the same wearable twice + U32 idxWearable = getWearableIndex(wearable); + llassert(MAX_CLOTHING_PER_TYPE == idxWearable); // pushWearable() on an already added wearable is a bug *somewhere* + if (MAX_CLOTHING_PER_TYPE == idxWearable) + { + mWearableDatas[type].push_back(wearable); + idxWearable = mWearableDatas[type].size() - 1; + } + if (trigger_updated) { const BOOL removed = FALSE; wearableUpdated(wearable, removed); } - return mWearableDatas[type].size()-1; + return idxWearable; } +// [/RLVa:KB] +// if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE) +// { +// mWearableDatas[type].push_back(wearable); +// if (trigger_updated) +// { +// const BOOL removed = FALSE; +// wearableUpdated(wearable, removed); +// } +// return mWearableDatas[type].size()-1; +// } return MAX_CLOTHING_PER_TYPE; } @@ -160,16 +180,16 @@ void LLWearableData::popWearable(const LLWearableType::EType type, U32 index) } } -void LLWearableData::clearWearableType(const LLWearableType::EType type) -{ - wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); - if (wearable_iter == mWearableDatas.end()) - { - return; - } - wearableentry_vec_t& wearable_vec = wearable_iter->second; - wearable_vec.clear(); -} +//void LLWearableData::clearWearableType(const LLWearableType::EType type) +//{ +// wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); +// if (wearable_iter == mWearableDatas.end()) +// { +// return; +// } +// wearableentry_vec_t& wearable_vec = wearable_iter->second; +// wearable_vec.clear(); +//} bool LLWearableData::swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b) { diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h index 3e92f2ead8..3817b27b3c 100644 --- a/indra/llappearance/llwearabledata.h +++ b/indra/llappearance/llwearabledata.h @@ -77,7 +77,7 @@ protected: virtual void wearableUpdated(LLWearable *wearable, BOOL removed); void popWearable(LLWearable *wearable); void popWearable(const LLWearableType::EType type, U32 index); - void clearWearableType(const LLWearableType::EType type); +// void clearWearableType(const LLWearableType::EType type); bool swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b); private: diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index f02735851c..ad858f4dae 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -49,7 +49,7 @@ #include "llvoavatarself.h" #include "llviewerwearable.h" #include "llwearablelist.h" -// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) +// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1) #include "rlvhandler.h" #include "rlvlocks.h" // [/RLVa:KB] @@ -771,7 +771,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 return LLUUID(); } -// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f +// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0) void LLAgentWearables::getWearableItemIDs(uuid_vec_t& idItems) const { for (wearableentry_map_t::const_iterator itWearableType = mWearableDatas.begin(); @@ -786,8 +786,8 @@ void LLAgentWearables::getWearableItemIDs(LLWearableType::EType eType, uuid_vec_ wearableentry_map_t::const_iterator itWearableType = mWearableDatas.find(eType); if (mWearableDatas.end() != itWearableType) { - for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin(), endWearable = itWearableType->second.end(); - itWearable != endWearable; ++itWearable) + for (wearableentry_vec_t::const_iterator itWearable = itWearableType->second.begin(); + itWearable != itWearableType->second.end(); ++itWearable) { const LLViewerWearable* pWearable = dynamic_cast(*itWearable); if (pWearable) @@ -1180,7 +1180,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_ LLViewerWearable* old_wearable = getViewerWearable(type,index); // if (old_wearable) -// [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0c) | Modified: RLVa-1.2.0g +// [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0) // NOTE: we block actual removal in removeWearableFinal(); all we really want here is to avoid showing the save notice if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) ) // [/RLVa:KB] @@ -1242,7 +1242,7 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo LLViewerWearable* old_wearable = getViewerWearable(type,i); //queryWearableCache(); // moved below // if (old_wearable) -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g +// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0) if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) ) // [/RLVa:KB] { @@ -1251,7 +1251,7 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo } } // clearWearableType(type); -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g +// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0) // The line above shouldn't be needed and would cause issues if we block removing one of the wearables RLV_VERIFY( ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.hasLockedWearable(type))) ? 0 == getWearableCount(type) : true ); // [/RLVa:KB] @@ -1262,7 +1262,7 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo //queryWearableCache(); // moved below // if (old_wearable) -// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0g) | Added: RLVa-1.2.0g +// [RLVa:KB] - Checked: 2010-05-14 (RLVa-1.2.0) if ( (old_wearable) && ((!rlv_handler_t::isEnabled()) || (!gRlvWearableLocks.isLockedWearable(old_wearable))) ) // [/RLVa:KB] { @@ -1302,6 +1302,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it S32 count = wearables.count(); llassert(items.count() == count); +// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g + // If the user is @add/remoutfit restricted in any way then this function won't just work as-is, so instead of removing and re-adding + // we're stuck with any wearable type potentially having left-over (remove locked) clothing that we'll need to reorder in-place + S32 idxCurPerType[LLWearableType::WT_COUNT] = { 0 }; +// [/RLVa:KB] + S32 i; for (i = 0; i < count; i++) { @@ -1321,10 +1327,52 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it // exactly one wearable per body part setWearable(type,0,new_wearable); } - else +// else +// { +// pushWearable(type,new_wearable); +// } +// [RLVa:KB] - Checked: 2010-06-08 (RLVa-1.2.0g) | Added: RLVa-1.2.0g + else if ( (!rlv_handler_t::isEnabled()) || (!remove) || + ((gRlvWearableLocks.canWear(type)) && (!gRlvWearableLocks.hasLockedWearable(type))) ) { + // Sanity check: there shouldn't be any worn wearables for this type the first time we encounter it + RLV_ASSERT( (!remove) || (0 != idxCurPerType[type]) || (0 == getWearableCount(type)) ); pushWearable(type,new_wearable); } + else + { + // Get the current index of the wearable (or add it if doesn't exist yet) + S32 idxCur = getWearableIndex(new_wearable); + if (MAX_CLOTHING_PER_TYPE == idxCur) + { + // Skip adding if @addoutfit=n restricted *unless* the wearable made it into COF [see LLAppMgr::updateAgentWearables()] + if ( (RLV_WEAR_LOCKED == gRlvWearableLocks.canWear(type)) && + (!LLAppearanceMgr::instance().isLinkInCOF(new_wearable->getItemID())) ) + { + continue; + } + idxCur = pushWearable(type,new_wearable); + } + + // Since we're moving up from index 0 we just swap the two wearables and things will work out in the end (hopefully) + if (idxCurPerType[type] != idxCur) + { + wearableentry_map_t::iterator itWearable = mWearableDatas.find(type); + RLV_ASSERT(itWearable != mWearableDatas.end()); + if (itWearable == mWearableDatas.end()) continue; + wearableentry_vec_t& typeWearable = itWearable->second; + RLV_ASSERT(typeWearable.size() >= 2); + if (typeWearable.size() < 2) continue; + + typeWearable[idxCur] = typeWearable[idxCurPerType[type]]; + typeWearable[idxCurPerType[type]] = new_wearable; + //wearableUpdated(new_wearable); + //checkWearableAgainstInventory(new_wearable); + } + } + idxCurPerType[type]++; +// [/RLVa:KB] + const BOOL removed = FALSE; wearableUpdated(new_wearable, removed); } @@ -1368,56 +1416,46 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } -// User has picked "wear on avatar" from a menu. -void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) -{ - //LLAgentDumper dumper("setWearableItem"); - if (isWearingItem(new_item->getUUID())) - { - llwarns << "wearable " << new_item->getUUID() << " is already worn" << llendl; - return; - } - - const LLWearableType::EType type = new_wearable->getType(); - -// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0a) | Modified: RLVa-1.2.0g - // TODO-RLVa: [RLVa-1.2.1] This looks like dead code in SL-2.0.2 so we can't really check to see if it works :| - if (rlv_handler_t::isEnabled()) - { - ERlvWearMask eWear = gRlvWearableLocks.canWear(type); - if ( (RLV_WEAR_LOCKED == eWear) || ((!do_append) && (!(eWear & RLV_WEAR_REPLACE))) ) - return; - } -// [/RLVa:KB] - - if (!do_append) - { - // Remove old wearable, if any - // MULTI_WEARABLE: hardwired to 0 - LLViewerWearable* old_wearable = getViewerWearable(type,0); - if (old_wearable) - { - const LLUUID& old_item_id = old_wearable->getItemID(); - if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && - (old_item_id == new_item->getUUID())) - { - lldebugs << "No change to wearable asset and item: " << LLWearableType::getTypeName(type) << llendl; - return; - } - - if (old_wearable->isDirty()) - { - // Bring up modal dialog: Save changes? Yes, No, Cancel - LLSD payload; - payload["item_id"] = new_item->getUUID(); - LLNotificationsUtil::add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable)); - return; - } - } - } - - setWearableFinal(new_item, new_wearable, do_append); -} +//// User has picked "wear on avatar" from a menu. +//void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) +//{ +// //LLAgentDumper dumper("setWearableItem"); +// if (isWearingItem(new_item->getUUID())) +// { +// llwarns << "wearable " << new_item->getUUID() << " is already worn" << llendl; +// return; +// } +// +// const LLWearableType::EType type = new_wearable->getType(); +// +// if (!do_append) +// { +// // Remove old wearable, if any +// // MULTI_WEARABLE: hardwired to 0 +// LLViewerWearable* old_wearable = getViewerWearable(type,0); +// if (old_wearable) +// { +// const LLUUID& old_item_id = old_wearable->getItemID(); +// if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && +// (old_item_id == new_item->getUUID())) +// { +// lldebugs << "No change to wearable asset and item: " << LLWearableType::getTypeName(type) << llendl; +// return; +// } +// +// if (old_wearable->isDirty()) +// { +// // Bring up modal dialog: Save changes? Yes, No, Cancel +// LLSD payload; +// payload["item_id"] = new_item->getUUID(); +// LLNotificationsUtil::add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable)); +// return; +// } +// } +// } +// +// setWearableFinal(new_item, new_wearable, do_append); +//} // static bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable) diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 7e68602db4..c522f80a84 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -93,7 +93,7 @@ public: // Accessors //-------------------------------------------------------------------- public: -// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0f) | Added: RLVa-1.3.0f +// [RLVa:KB] - Checked: 2011-03-31 (RLVa-1.3.0) void getWearableItemIDs(uuid_vec_t& idItems) const; void getWearableItemIDs(LLWearableType::EType eType, uuid_vec_t& idItems) const; // [/RLVa:KB] @@ -113,7 +113,7 @@ public: private: /*virtual*/void wearableUpdated(LLWearable *wearable, BOOL removed); public: - void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false); +// void setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false); void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove); void setWearableName(const LLUUID& item_id, const std::string& new_name); // *TODO: Move this into llappearance/LLWearableData ? @@ -153,8 +153,11 @@ private: // Removing wearables //-------------------------------------------------------------------- public: - void removeWearable(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/); +// void removeWearable(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/); private: +// [RLVa:KB] - Checked: 2010-05-11 (RLVa-1.2.0) + void removeWearable(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/); +// [/RLVa:KB] void removeWearableFinal(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/); protected: static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response);