diff options
Diffstat (limited to 'indra/newview/llappearancemgr.cpp')
-rw-r--r-- | indra/newview/llappearancemgr.cpp | 142 |
1 files changed, 107 insertions, 35 deletions
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 5c21be8c32..f2d15757c9 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -436,9 +436,9 @@ void LLWearableHoldingPattern::checkMissingWearables() } } + mWaitTime.reset(); if (!pollMissingWearables()) { - mWaitTime.reset(); doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this)); } } @@ -494,11 +494,12 @@ bool LLWearableHoldingPattern::pollFetchCompletion() bool completed = isFetchCompleted(); bool timed_out = isTimedOut(); bool done = completed || timed_out; - - llinfos << "polling, done status: " << completed << " timed out " << timed_out << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; if (done) { + llinfos << "polling, done status: " << completed << " timed out " << timed_out + << " elapsed " << mWaitTime.getElapsedTimeF32() << llendl; + mFired = true; if (timed_out) @@ -807,47 +808,91 @@ void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID void LLAppearanceManager::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, LLPointer<LLInventoryCallback> cb) { - LLInventoryModel::cat_array_t cats; - LLInventoryModel::item_array_t items; - gInventory.collectDescendents(src_id, cats, items, - LLInventoryModel::EXCLUDE_TRASH); - for (S32 i = 0; i < items.count(); ++i) + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(src_id, cats, items); + for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); + iter != items->end(); + ++iter) { - const LLViewerInventoryItem* item = items.get(i).get(); - if (item->getActualType() == LLAssetType::AT_LINK) - { - link_inventory_item(gAgent.getID(), - item->getLinkedUUID(), - dst_id, - item->getName(), - LLAssetType::AT_LINK, cb); - } - else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER) + const LLViewerInventoryItem* item = (*iter); + switch (item->getActualType()) { - LLViewerInventoryCategory *catp = item->getLinkedCategory(); - // Skip copying outfit links. - if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT) + case LLAssetType::AT_LINK: { link_inventory_item(gAgent.getID(), item->getLinkedUUID(), dst_id, item->getName(), - LLAssetType::AT_LINK_FOLDER, cb); + LLAssetType::AT_LINK, cb); + break; + } + case LLAssetType::AT_LINK_FOLDER: + { + LLViewerInventoryCategory *catp = item->getLinkedCategory(); + // Skip copying outfit links. + if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT) + { + link_inventory_item(gAgent.getID(), + item->getLinkedUUID(), + dst_id, + item->getName(), + LLAssetType::AT_LINK_FOLDER, cb); + } + break; + } + case LLAssetType::AT_CLOTHING: + case LLAssetType::AT_OBJECT: + case LLAssetType::AT_BODYPART: + case LLAssetType::AT_GESTURE: + { + copy_inventory_item(gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + dst_id, + item->getName(), + cb); + break; } + default: + // Ignore non-outfit asset types + break; } - else + } +} + +BOOL LLAppearanceManager::getCanMakeFolderIntoOutfit(const LLUUID& folder_id) +{ + // These are the wearable items that are required for considering this + // folder as containing a complete outfit. + U32 required_wearables = 0; + required_wearables |= 1LL << WT_SHAPE; + required_wearables |= 1LL << WT_SKIN; + required_wearables |= 1LL << WT_HAIR; + required_wearables |= 1LL << WT_EYES; + + // These are the wearables that the folder actually contains. + U32 folder_wearables = 0; + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(folder_id, cats, items); + for (LLInventoryModel::item_array_t::const_iterator iter = items->begin(); + iter != items->end(); + ++iter) + { + const LLViewerInventoryItem* item = (*iter); + if (item->isWearableType()) { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - dst_id, - item->getName(), - cb); + const EWearableType wearable_type = item->getWearableType(); + folder_wearables |= 1LL << wearable_type; } } + + // If the folder contains the required wearables, return TRUE. + return ((required_wearables & folder_wearables) == required_wearables); } + void LLAppearanceManager::purgeBaseOutfitLink(const LLUUID& category) { LLInventoryModel::cat_array_t cats; @@ -1085,6 +1130,22 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, // dec_busy_count(); } +static void remove_non_link_items(LLInventoryModel::item_array_t &items) +{ + LLInventoryModel::item_array_t pruned_items; + for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); + iter != items.end(); + ++iter) + { + const LLViewerInventoryItem *item = (*iter); + if (item && item->getIsLinkType()) + { + pruned_items.push_back((*iter)); + } + } + items = pruned_items; +} + void LLAppearanceManager::updateAppearanceFromCOF() { // update dirty flag to see if the state of the COF matches @@ -1098,13 +1159,17 @@ void LLAppearanceManager::updateAppearanceFromCOF() bool follow_folder_links = true; LLUUID current_outfit_id = getCOF(); - // Find all the wearables that are in the COF's subtree. + // Find all the wearables that are in the COF's subtree. lldebugs << "LLAppearanceManager::updateFromCOF()" << llendl; LLInventoryModel::item_array_t wear_items; LLInventoryModel::item_array_t obj_items; LLInventoryModel::item_array_t gest_items; getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items, follow_folder_links); - + // Get rid of non-links in case somehow the COF was corrupted. + remove_non_link_items(wear_items); + remove_non_link_items(obj_items); + remove_non_link_items(gest_items); + if(!wear_items.count()) { LLNotificationsUtil::add("CouldNotPutOnOutfit"); @@ -1128,7 +1193,7 @@ void LLAppearanceManager::updateAppearanceFromCOF() { LLViewerInventoryItem *item = wear_items.get(i); LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL; - if (item && linked_item) + if (item && item->getIsLinkType() && linked_item) { LLFoundData found(linked_item->getUUID(), linked_item->getAssetUUID(), @@ -1155,11 +1220,11 @@ void LLAppearanceManager::updateAppearanceFromCOF() { if (!item) { - llwarns << "attempt to wear a null item " << llendl; + llwarns << "Attempt to wear a null item " << llendl; } else if (!linked_item) { - llwarns << "attempt to wear a broken link " << item->getName() << llendl; + llwarns << "Attempt to wear a broken link [ name:" << item->getName() << " ] " << llendl; } } } @@ -1689,6 +1754,13 @@ BOOL LLAppearanceManager::getIsProtectedCOFItem(const LLUUID& obj_id) const { if (!getIsInCOF(obj_id)) return FALSE; + // If a non-link somehow ended up in COF, allow deletion. + const LLInventoryObject *obj = gInventory.getObject(obj_id); + if (obj && !obj->getIsLinkType()) + { + return FALSE; + } + // For now, don't allow direct deletion from the COF. Instead, force users // to choose "Detach" or "Take Off". return TRUE; |