summaryrefslogtreecommitdiff
path: root/indra/newview/llagentwearables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r--indra/newview/llagentwearables.cpp118
1 files changed, 102 insertions, 16 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 538dcb6f3d..18a8396451 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -41,6 +41,7 @@
#include "llinventorybridge.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
+#include "llnotificationsutil.h"
#include "llnotify.h"
#include "llviewerregion.h"
#include "llvoavatarself.h"
@@ -675,7 +676,7 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab
{
wearable_vec[index] = wearable;
old_wearable->setLabelUpdated();
- mAvatarObject->wearableUpdated(wearable->getType());
+ wearableUpdated(wearable);
}
}
@@ -690,13 +691,32 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl
if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE)
{
mWearableDatas[type].push_back(wearable);
- mAvatarObject->wearableUpdated(wearable->getType());
- wearable->setLabelUpdated();
+ wearableUpdated(wearable);
return mWearableDatas[type].size()-1;
}
return MAX_WEARABLES_PER_TYPE;
}
+void LLAgentWearables::wearableUpdated(LLWearable *wearable)
+{
+ mAvatarObject->wearableUpdated(wearable->getType());
+ wearable->setLabelUpdated();
+
+ // Hack pt 2. If the wearable we just loaded has definition version 24,
+ // then force a re-save of this wearable after slamming the version number to 22.
+ // This number was incorrectly incremented for internal builds before release, and
+ // this fix will ensure that the affected wearables are re-saved with the right version number.
+ // the versions themselves are compatible. This code can be removed before release.
+ if( wearable->getDefinitionVersion() == 24 )
+ {
+ wearable->setDefinitionVersion(22);
+ U32 index = getWearableIndex(wearable);
+ llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
+ saveWearable(wearable->getType(),index,TRUE);
+ }
+
+}
+
void LLAgentWearables::popWearable(LLWearable *wearable)
{
if (wearable == NULL)
@@ -998,7 +1018,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void*
void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 index)
{
// Try to recover by replacing missing wearable with a new one.
- LLNotifications::instance().add("ReplacedMissingWearable");
+ LLNotificationsUtil::add("ReplacedMissingWearable");
lldebugs << "Wearable " << LLWearableDictionary::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
@@ -1367,7 +1387,7 @@ void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_a
LLSD payload;
payload["wearable_type"] = (S32)type;
// Bring up view-modal dialog: Save changes? Yes, No, Cancel
- LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgentWearables::onRemoveWearableDialog);
+ LLNotificationsUtil::add("WearableSave", LLSD(), payload, &LLAgentWearables::onRemoveWearableDialog);
return;
}
else
@@ -1384,7 +1404,7 @@ void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_a
// static
bool LLAgentWearables::onRemoveWearableDialog(const LLSD& notification, const LLSD& response)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger();
switch(option)
{
@@ -1528,7 +1548,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
gInventory.notifyObservers();
- queryWearableCache();
std::vector<LLWearable*>::iterator wearable_iter;
@@ -1551,6 +1570,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// Start rendering & update the server
mWearablesLoaded = TRUE;
checkWearablesLoaded();
+ queryWearableCache();
updateServer();
lldebugs << "setWearableOutfit() end" << llendl;
@@ -1589,7 +1609,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
// Bring up modal dialog: Save changes? Yes, No, Cancel
LLSD payload;
payload["item_id"] = new_item->getUUID();
- LLNotifications::instance().add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable));
+ LLNotificationsUtil::add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable));
return;
}
}
@@ -1601,7 +1621,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
// static
bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable)
{
- S32 option = LLNotification::getSelectedOption(notification, response);
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
if (!new_item)
{
@@ -2155,7 +2175,6 @@ void LLLibraryOutfitsFetch::contentsDone(void)
LLInitialWearablesFetch::~LLInitialWearablesFetch()
{
- llinfos << "~LLInitialWearablesFetch" << llendl;
}
// virtual
@@ -2185,17 +2204,50 @@ void LLInitialWearablesFetch::processContents()
else
{
processWearablesMessage();
- // Create links for attachments that may have arrived before the COF existed.
- LLAppearanceManager::instance().linkRegisteredAttachments();
}
delete this;
}
+class LLFetchAndLinkObserver: public LLInventoryFetchObserver
+{
+public:
+ LLFetchAndLinkObserver(LLInventoryFetchObserver::item_ref_t& ids):
+ m_ids(ids),
+ LLInventoryFetchObserver(true)
+ {
+ }
+ ~LLFetchAndLinkObserver()
+ {
+ }
+ virtual void done()
+ {
+ gInventory.removeObserver(this);
+ // Link to all fetched items in COF.
+ for (LLInventoryFetchObserver::item_ref_t::iterator it = m_ids.begin();
+ it != m_ids.end();
+ ++it)
+ {
+ LLUUID id = *it;
+ LLViewerInventoryItem *item = gInventory.getItem(*it);
+ if (!item)
+ {
+ llwarns << "fetch failed!" << llendl;
+ continue;
+ }
+ link_inventory_item(gAgent.getID(), item->getLinkedUUID(), LLAppearanceManager::instance().getCOF(), item->getName(),
+ LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+ }
+ }
+private:
+ LLInventoryFetchObserver::item_ref_t m_ids;
+};
+
void LLInitialWearablesFetch::processWearablesMessage()
{
if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
{
- const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+ const LLUUID current_outfit_id = LLAppearanceManager::instance().getCOF();
+ LLInventoryFetchObserver::item_ref_t ids;
for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
{
// Populate the current outfit folder with links to the wearables passed in the message
@@ -2204,9 +2256,7 @@ void LLInitialWearablesFetch::processWearablesMessage()
if (wearable_data->mAssetID.notNull())
{
#ifdef USE_CURRENT_OUTFIT_FOLDER
- const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
- link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
- LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+ ids.push_back(wearable_data->mItemID);
#endif
// Fetch the wearables
LLWearableList::instance().getAsset(wearable_data->mAssetID,
@@ -2220,6 +2270,42 @@ void LLInitialWearablesFetch::processWearablesMessage()
<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
}
}
+
+ // Add all current attachments to the requested items as well.
+ LLVOAvatarSelf* avatar = gAgent.getAvatarObject();
+ if( avatar )
+ {
+ for (LLVOAvatar::attachment_map_t::const_iterator iter = avatar->mAttachmentPoints.begin();
+ iter != avatar->mAttachmentPoints.end(); ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (!attachment) continue;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = (*attachment_iter);
+ if (!attached_object) continue;
+ const LLUUID& item_id = attached_object->getItemID();
+ if (item_id.isNull()) continue;
+ ids.push_back(item_id);
+ }
+ }
+ }
+
+ // Need to fetch the inventory items for ids, then create links to them after they arrive.
+ LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
+ fetcher->fetchItems(ids);
+ // If no items to be fetched, done will never be triggered.
+ // TODO: Change LLInventoryFetchObserver::fetchItems to trigger done() on this condition.
+ if (fetcher->isEverythingComplete())
+ {
+ fetcher->done();
+ }
+ else
+ {
+ gInventory.addObserver(fetcher);
+ }
}
else
{