diff options
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r-- | indra/newview/llagentwearables.cpp | 131 |
1 files changed, 83 insertions, 48 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 223f8779ec..3fc1055acd 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -39,6 +39,7 @@ #include "llfloaterinventory.h" #include "llinventorybridge.h" #include "llinventorymodel.h" +#include "llinventorypanel.h" #include "llnotify.h" #include "llviewerregion.h" #include "llvoavatarself.h" @@ -68,8 +69,11 @@ public: EWearableType mType; LLUUID mItemID; LLUUID mAssetID; - InitialWearableData(EWearableType type, LLUUID itemID, LLUUID assetID) : - mType(type), mItemID(itemID), mAssetID(assetID) { } + InitialWearableData(EWearableType type, LLUUID& itemID, LLUUID& assetID) : + mType(type), + mItemID(itemID), + mAssetID(assetID) + {} }; typedef std::vector<InitialWearableData> initial_wearable_data_vec_t; @@ -430,7 +434,7 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, if (save_in_lost_and_found) { category_id = gInventory.findCategoryUUIDForType( - LLAssetType::AT_LOST_AND_FOUND); + LLFolderType::FT_LOST_AND_FOUND); } else { @@ -646,6 +650,7 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab else { wearable_vec[index] = wearable; + mAvatarObject->wearableUpdated(wearable->getType()); } } @@ -654,21 +659,30 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl if (wearable == NULL) { // no null wearables please! - //TODO: insert llwarns - return MAX_ATTACHMENTS_PER_TYPE; + llwarns << "Null wearable sent for type " << type << llendl; + return MAX_WEARABLES_PER_TYPE; } - if (type < WT_COUNT) + if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE) { mWearableDatas[type].push_back(wearable); + mAvatarObject->wearableUpdated(wearable->getType()); return mWearableDatas[type].size()-1; } - return MAX_ATTACHMENTS_PER_TYPE; + return MAX_WEARABLES_PER_TYPE; } -void LLAgentWearables::popWearable(const EWearableType type, LLWearable *wearable) +void LLAgentWearables::popWearable(LLWearable *wearable) { - U32 index = getWearableIndex(type, wearable); - if (index < MAX_ATTACHMENTS_PER_TYPE && index < getWearableCount(type)) + if (wearable == NULL) + { + // nothing to do here. move along. + return; + } + + U32 index = getWearableIndex(wearable); + EWearableType type = wearable->getType(); + + if (index < MAX_WEARABLES_PER_TYPE && index < getWearableCount(type)) { popWearable(type, index); } @@ -676,19 +690,27 @@ void LLAgentWearables::popWearable(const EWearableType type, LLWearable *wearabl void LLAgentWearables::popWearable(const EWearableType type, U32 index) { - if (getWearable(type, index)) + LLWearable *wearable = getWearable(type, index); + if (wearable) { mWearableDatas[type].erase(mWearableDatas[type].begin() + index); + mAvatarObject->wearableUpdated(wearable->getType()); } } -U32 LLAgentWearables::getWearableIndex(const EWearableType type, LLWearable *wearable) +U32 LLAgentWearables::getWearableIndex(LLWearable *wearable) { + if (wearable == NULL) + { + return MAX_WEARABLES_PER_TYPE; + } + + const EWearableType type = wearable->getType(); wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); if (wearable_iter == mWearableDatas.end()) { llwarns << "tried to get wearable index with an invalid type!" << llendl; - return MAX_ATTACHMENTS_PER_TYPE; + return MAX_WEARABLES_PER_TYPE; } const wearableentry_vec_t& wearable_vec = wearable_iter->second; for(U32 index = 0; index < wearable_vec.size(); index++) @@ -699,7 +721,7 @@ U32 LLAgentWearables::getWearableIndex(const EWearableType type, LLWearable *wea } } - return MAX_ATTACHMENTS_PER_TYPE; + return MAX_WEARABLES_PER_TYPE; } const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const @@ -777,22 +799,12 @@ const LLUUID LLAgentWearables::getWearableAssetID(EWearableType type, U32 index) return LLUUID(); } -// Warning: include_linked_items = TRUE makes this operation expensive. -BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_items) const +BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const { - if (getWearableFromItemID(item_id) != NULL) return TRUE; - if (include_linked_items) + const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id); + if (getWearableFromItemID(base_item_id) != NULL) { - LLInventoryModel::item_array_t item_array; - gInventory.collectLinkedItems(item_id, item_array); - for (LLInventoryModel::item_array_t::iterator iter = item_array.begin(); - iter != item_array.end(); - iter++) - { - LLViewerInventoryItem *linked_item = (*iter); - const LLUUID &linked_item_id = linked_item->getUUID(); - if (getWearableFromItemID(linked_item_id) != NULL) return TRUE; - } + return TRUE; } return FALSE; } @@ -828,7 +840,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs } // Get the UUID of the current outfit folder (will be created if it doesn't exist) - LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); + const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); LLInitialWearablesFetch* outfit = new LLInitialWearablesFetch(); @@ -969,8 +981,7 @@ void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 inde // Add a new one in the lost and found folder. // (We used to overwrite the "not found" one, but that could potentially // destory content.) JC - LLUUID lost_and_found_id = - gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); + const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); LLPointer<LLInventoryCallback> cb = new addWearableToAgentInventoryCallback( LLPointer<LLRefCount>(NULL), @@ -1090,7 +1101,7 @@ void LLAgentWearables::getAllWearablesArray(LLDynamicArray<S32>& wearables) { for( S32 i = 0; i < WT_COUNT; ++i ) { - if (getWearableCount( (EWearableType) i) != 0 ) + if (getWearableCount((EWearableType) i) != 0) { wearables.push_back(i); } @@ -1111,8 +1122,8 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name, // First, make a folder in the Clothes directory. LLUUID folder_id = gInventory.createNewCategory( - gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING), - LLAssetType::AT_NONE, + gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING), + LLFolderType::FT_NONE, new_folder_name); bool found_first_item = false; @@ -1245,10 +1256,10 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name) } // First, make a folder in the My Outfits directory. - LLUUID parent_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_MY_OUTFITS); + const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); LLUUID folder_id = gInventory.createNewCategory( parent_id, - LLAssetType::AT_OUTFIT, + LLFolderType::FT_OUTFIT, new_folder_name); LLAppearanceManager::shallowCopyCategory(LLAppearanceManager::getCOF(),folder_id, NULL); @@ -1300,13 +1311,18 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_all, U32 index) { - if ((gAgent.isTeen()) - && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS)) + if (gAgent.isTeen() && + (type == WT_UNDERSHIRT || type == WT_UNDERPANTS)) { // Can't take off underclothing in simple UI mode or on PG accounts // TODO: enable the removing of a single undershirt/underpants if multiple are worn. - Nyx return; } + if (getWearableCount(type) == 0) + { + // no wearables to remove + return; + } if (do_remove_all) { @@ -1373,8 +1389,10 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem for (S32 i=max_entry; i>=0; i--) { LLWearable* old_wearable = getWearable(type,i); - gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,i)); + const LLUUID &item_id = getWearableItemID(type,i); popWearable(type,i); + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + LLAppearanceManager::removeItemLinks(item_id,false); //queryWearableCache(); // moved below if (old_wearable) @@ -1388,8 +1406,10 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem { LLWearable* old_wearable = getWearable(type, index); - gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,index)); + const LLUUID &item_id = getWearableItemID(type,index); popWearable(type, index); + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + LLAppearanceManager::removeItemLinks(item_id,false); //queryWearableCache(); // moved below @@ -1428,6 +1448,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) & remove; wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) & remove; wearables_to_remove[WT_SKIRT] = remove; + wearables_to_remove[WT_ALPHA] = remove; + wearables_to_remove[WT_TATTOO] = remove; + S32 count = wearables.count(); llassert(items.count() == count); @@ -1454,7 +1477,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - // Assumes existing wearables are not dirty. if (old_wearable->isDirty()) { @@ -1476,7 +1498,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { // MULTI_WEARABLE: assuming 0th LLWearable* wearable = getWearable((EWearableType)i, 0); - gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID((EWearableType)i,0)); + const LLUUID &item_id = getWearableItemID((EWearableType)i,0); + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); if (wearable) { wearables_being_removed.push_back(wearable); @@ -1700,10 +1723,8 @@ void LLAgentWearables::queryWearableCache() // MULTI_WEARABLE: need a way to specify by wearable rather than by type. // User has picked "remove from avatar" from a menu. // static -void LLAgentWearables::userRemoveWearable(void* userdata) +void LLAgentWearables::userRemoveWearable(EWearableType& type) { - EWearableType type = (EWearableType)(intptr_t)userdata; - if (!(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR)) //&& //!((!gAgent.isTeen()) && (type==WT_UNDERPANTS || type==WT_UNDERSHIRT))) { @@ -1713,7 +1734,7 @@ void LLAgentWearables::userRemoveWearable(void* userdata) } // static -void LLAgentWearables::userRemoveAllClothes(void* userdata) +void LLAgentWearables::userRemoveAllClothes() { // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty. if (gFloaterCustomize) @@ -1740,6 +1761,8 @@ void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed) gAgentWearables.removeWearable(WT_UNDERSHIRT,true,0); gAgentWearables.removeWearable(WT_UNDERPANTS,true,0); gAgentWearables.removeWearable(WT_SKIRT,true,0); + gAgentWearables.removeWearable(WT_ALPHA,true,0); + gAgentWearables.removeWearable(WT_TATTOO,true,0); } } @@ -1962,6 +1985,17 @@ bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const return !(((type == WT_SHAPE) || (type == WT_SKIN) || (type == WT_HAIR) || (type == WT_EYES)) && (getWearableCount(type) <= 1) ); } +void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL set_by_user) +{ + for( S32 type = 0; type < WT_COUNT; ++type ) + { + for (S32 count = 0; count < (S32)getWearableCount((EWearableType)type); ++count) + { + LLWearable *wearable = getWearable((EWearableType)type,count); + wearable->animateParams(delta, set_by_user); + } + } +} void LLAgentWearables::updateServer() { @@ -1980,7 +2014,8 @@ void LLInitialWearablesFetch::done() LLFindWearables is_wearable; gInventory.collectDescendentsIf(mCompleteFolders.front(), cat_array, wearable_array, LLInventoryModel::EXCLUDE_TRASH, is_wearable); - + + LLAppearanceManager::setAttachmentInvLinkEnable(true); if (wearable_array.count() > 0) { LLAppearanceManager::instance().updateAppearanceFromCOF(); @@ -1996,7 +2031,7 @@ void LLInitialWearablesFetch::processWearablesMessage() { if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead. { - LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT); + const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); for (U8 i = 0; i < mAgentInitialWearables.size(); ++i) { // Populate the current outfit folder with links to the wearables passed in the message |