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.cpp884
1 files changed, 424 insertions, 460 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index a1ce556458..9d3b5763e8 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -2,25 +2,31 @@
* @file llagentwearables.cpp
* @brief LLAgentWearables class implementation
*
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
*
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
@@ -33,6 +39,7 @@
#include "llagentwearablesfetch.h"
#include "llappearancemgr.h"
#include "llcallbacklist.h"
+#include "llfloatercustomize.h"
#include "llfolderview.h"
#include "llgesturemgr.h"
#include "llinventorybridge.h"
@@ -41,8 +48,7 @@
#include "llinventorypanel.h"
#include "llmd5.h"
#include "llnotificationsutil.h"
-#include "lloutfitobserver.h"
-#include "llsidepanelappearance.h"
+#include "llpaneloutfitsinventory.h"
#include "llsidetray.h"
#include "lltexlayer.h"
#include "llviewerregion.h"
@@ -58,25 +64,6 @@ BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
using namespace LLVOAvatarDefines;
-///////////////////////////////////////////////////////////////////////////////
-
-// Callback to wear and start editing an item that has just been created.
-class LLWearAndEditCallback : public LLInventoryCallback
-{
- void fire(const LLUUID& inv_item)
- {
- if (inv_item.isNull()) return;
-
- // Request editing the item after it gets worn.
- gAgentWearables.requestEditingWearable(inv_item);
-
- // Wear it.
- LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
// HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look"
// Some db items are corrupted, have inventory flags = 0, implying wearable type = shape, even though
// wearable type stored in asset is some other value.
@@ -113,13 +100,13 @@ void checkWearableAgainstInventory(LLWearable *wearable)
void LLAgentWearables::dump()
{
llinfos << "LLAgentWearablesDump" << llendl;
- for (S32 i = 0; i < LLWearableType::WT_COUNT; i++)
+ for (S32 i = 0; i < WT_COUNT; i++)
{
- U32 count = getWearableCount((LLWearableType::EType)i);
+ U32 count = getWearableCount((EWearableType)i);
llinfos << "Type: " << i << " count " << count << llendl;
for (U32 j=0; j<count; j++)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)i,j);
+ LLWearable* wearable = getWearable((EWearableType)i,j);
if (wearable == NULL)
{
llinfos << " " << j << " NULL wearable" << llendl;
@@ -138,6 +125,7 @@ void LLAgentWearables::dump()
}
}
+// MULTI-WEARABLE: debugging
struct LLAgentDumper
{
LLAgentDumper(std::string name):
@@ -160,7 +148,6 @@ struct LLAgentDumper
LLAgentWearables::LLAgentWearables() :
mWearablesLoaded(FALSE)
-, mCOFChangeInProgress(false)
{
}
@@ -173,14 +160,6 @@ void LLAgentWearables::cleanup()
{
}
-// static
-void LLAgentWearables::initClass()
-{
- // this can not be called from constructor because its instance is global and is created too early.
- // Subscribe to "COF is Saved" signal to notify observers about this (Loading indicator for ex.).
- LLOutfitObserver::instance().addCOFSavedCallback(boost::bind(&LLAgentWearables::notifyLoadingFinished, &gAgentWearables));
-}
-
void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
{
if (avatar)
@@ -212,7 +191,7 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
* @param todo Bitmask of actions to take on completion.
*/
LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
- LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) :
+ LLPointer<LLRefCount> cb, S32 type, U32 index, LLWearable* wearable, U32 todo) :
mType(type),
mIndex(index),
mWearable(wearable),
@@ -261,7 +240,7 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
}
}
-void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type,
+void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type,
const U32 index,
const LLUUID& item_id,
LLWearable* wearable)
@@ -271,7 +250,7 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::ETy
if (item_id.isNull())
return;
- LLUUID old_item_id = getWearableItemID(type,index);
+ LLUUID old_item_id = getWearableItemID((EWearableType)type,index);
if (wearable)
{
@@ -280,11 +259,11 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::ETy
if (old_item_id.notNull())
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
- setWearable(type,index,wearable);
+ setWearable((EWearableType)type,index,wearable);
}
else
{
- pushWearable(type,wearable);
+ pushWearable((EWearableType)type,wearable);
}
}
@@ -306,12 +285,13 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::ETy
void LLAgentWearables::sendAgentWearablesUpdate()
{
+ // MULTI-WEARABLE: call i "type" or something.
// First make sure that we have inventory items for each wearable
- for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
+ for (S32 type=0; type < WT_COUNT; ++type)
{
- for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
+ for (U32 j=0; j < getWearableCount((EWearableType)type); ++j)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)type,index);
+ LLWearable* wearable = getWearable((EWearableType)type,j);
if (wearable)
{
if (wearable->getItemID().isNull())
@@ -319,8 +299,8 @@ void LLAgentWearables::sendAgentWearablesUpdate()
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
- (LLWearableType::EType)type,
- index,
+ type,
+ j,
wearable,
addWearableToAgentInventoryCallback::CALL_NONE);
addWearableToAgentInventory(cb, wearable);
@@ -345,15 +325,16 @@ void LLAgentWearables::sendAgentWearablesUpdate()
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
lldebugs << "sendAgentWearablesUpdate()" << llendl;
- // MULTI-WEARABLE: DEPRECATED: HACK: index to 0- server database tables don't support concept of multiwearables.
- for (S32 type=0; type < LLWearableType::WT_COUNT; ++type)
+ // MULTI-WEARABLE: update for multi-wearables after server-side support is in.
+ for (S32 type=0; type < WT_COUNT; ++type)
{
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
U8 type_u8 = (U8)type;
gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8);
- LLWearable* wearable = getWearable((LLWearableType::EType)type, 0);
+ // MULTI-WEARABLE: TODO: hacked index to 0, needs to loop over all once messages support this.
+ LLWearable* wearable = getWearable((EWearableType)type, 0);
if (wearable)
{
//llinfos << "Sending wearable " << wearable->getName() << llendl;
@@ -369,17 +350,16 @@ void LLAgentWearables::sendAgentWearablesUpdate()
}
else
{
- //llinfos << "Not wearing wearable type " << LLWearableType::getTypeName((LLWearableType::EType)i) << llendl;
+ //llinfos << "Not wearing wearable type " << LLWearableDictionary::getInstance()->getWearable((EWearableType)i) << llendl;
gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null);
}
- lldebugs << " " << LLWearableType::getTypeLabel((LLWearableType::EType)type) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl;
+ lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)type) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl;
}
gAgent.sendReliableMessage();
}
-void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,
- const std::string new_name)
+void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, BOOL send_update)
{
LLWearable* old_wearable = getWearable(type, index);
if (old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()))
@@ -397,14 +377,6 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
LLInventoryItem* item = gInventory.getItem(old_item_id);
if (item)
{
- std::string item_name = item->getName();
- bool name_changed = false;
- if (!new_name.empty() && (new_name != item->getName()))
- {
- llinfos << "saveWearable changing name from " << item->getName() << " to " << new_name << llendl;
- item_name = new_name;
- name_changed = true;
- }
// Update existing inventory item
LLPointer<LLViewerInventoryItem> template_item =
new LLViewerInventoryItem(item->getUUID(),
@@ -413,7 +385,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
new_wearable->getAssetID(),
new_wearable->getAssetType(),
item->getInventoryType(),
- item_name,
+ item->getName(),
item->getDescription(),
item->getSaleInfo(),
item->getFlags(),
@@ -421,10 +393,6 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
template_item->setTransactionID(new_wearable->getTransactionID());
template_item->updateServer(FALSE);
gInventory.updateItem(template_item);
- if (name_changed)
- {
- gInventory.notifyObservers();
- }
}
else
{
@@ -437,7 +405,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
- type,
+ (S32)type,
index,
new_wearable,
todo);
@@ -454,7 +422,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
}
}
-void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
+void LLAgentWearables::saveWearableAs(const EWearableType type,
const U32 index,
const std::string& new_name,
BOOL save_in_lost_and_found)
@@ -515,14 +483,10 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
old_wearable->revertValues();
}
-void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
+void LLAgentWearables::revertWearable(const EWearableType type, const U32 index)
{
LLWearable* wearable = getWearable(type, index);
- llassert(wearable);
- if (wearable)
- {
- wearable->revertValues();
- }
+ wearable->revertValues();
gAgent.sendAgentSetAppearance();
}
@@ -534,10 +498,10 @@ void LLAgentWearables::saveAllWearables()
// return;
//}
- for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
+ for (S32 i=0; i < WT_COUNT; i++)
{
- for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
- saveWearable((LLWearableType::EType)i, j, FALSE);
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
+ saveWearable((EWearableType)i, j, FALSE);
}
sendAgentWearablesUpdate();
}
@@ -545,16 +509,15 @@ void LLAgentWearables::saveAllWearables()
// Called when the user changes the name of a wearable inventory item that is currently being worn.
void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string& new_name)
{
- for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
+ for (S32 i=0; i < WT_COUNT; i++)
{
- for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
{
- LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j);
+ LLUUID curr_item_id = getWearableItemID((EWearableType)i,j);
if (curr_item_id == item_id)
{
- LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j);
+ LLWearable* old_wearable = getWearable((EWearableType)i,j);
llassert(old_wearable);
- if (!old_wearable) continue;
std::string old_name = old_wearable->getName();
old_wearable->setName(new_name);
@@ -567,7 +530,7 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&
}
old_wearable->setName(old_name);
- setWearable((LLWearableType::EType)i,j,new_wearable);
+ setWearable((EWearableType)i,j,new_wearable);
sendAgentWearablesUpdate();
break;
}
@@ -576,18 +539,12 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&
}
-BOOL LLAgentWearables::isWearableModifiable(LLWearableType::EType type, U32 index) const
+BOOL LLAgentWearables::isWearableModifiable(EWearableType type, U32 index) const
{
LLUUID item_id = getWearableItemID(type, index);
- return item_id.notNull() ? isWearableModifiable(item_id) : FALSE;
-}
-
-BOOL LLAgentWearables::isWearableModifiable(const LLUUID& item_id) const
-{
- const LLUUID& linked_id = gInventory.getLinkedItemID(item_id);
- if (linked_id.notNull())
+ if (!item_id.isNull())
{
- LLInventoryItem* item = gInventory.getItem(linked_id);
+ LLInventoryItem* item = gInventory.getItem(item_id);
if (item && item->getPermissions().allowModifyBy(gAgent.getID(),
gAgent.getGroupID()))
{
@@ -597,7 +554,7 @@ BOOL LLAgentWearables::isWearableModifiable(const LLUUID& item_id) const
return FALSE;
}
-BOOL LLAgentWearables::isWearableCopyable(LLWearableType::EType type, U32 index) const
+BOOL LLAgentWearables::isWearableCopyable(EWearableType type, U32 index) const
{
LLUUID item_id = getWearableItemID(type, index);
if (!item_id.isNull())
@@ -613,7 +570,7 @@ BOOL LLAgentWearables::isWearableCopyable(LLWearableType::EType type, U32 index)
}
/*
- U32 LLAgentWearables::getWearablePermMask(LLWearableType::EType type)
+ U32 LLAgentWearables::getWearablePermMask(EWearableType type)
{
LLUUID item_id = getWearableItemID(type);
if (!item_id.isNull())
@@ -628,7 +585,7 @@ BOOL LLAgentWearables::isWearableCopyable(LLWearableType::EType type, U32 index)
}
*/
-LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::EType type, U32 index)
+LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type, U32 index)
{
LLUUID item_id = getWearableItemID(type,index);
LLInventoryItem* item = NULL;
@@ -641,30 +598,12 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp
const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
{
- const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
- for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
+ for (S32 i=0; i < WT_COUNT; i++)
{
- for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
{
- const LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
- if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
- {
- return curr_wearable;
- }
- }
- }
- return NULL;
-}
-
-LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
-{
- const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
- for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
- {
- for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
- {
- LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
- if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
+ const LLWearable * curr_wearable = getWearable((EWearableType)i, j);
+ if (curr_wearable && (curr_wearable->getItemID() == item_id))
{
return curr_wearable;
}
@@ -675,11 +614,11 @@ LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
LLWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id)
{
- for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
+ for (S32 i=0; i < WT_COUNT; i++)
{
- for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
+ for (U32 j=0; j < getWearableCount((EWearableType)i); j++)
{
- LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+ LLWearable * curr_wearable = getWearable((EWearableType)i, j);
if (curr_wearable && (curr_wearable->getAssetID() == asset_id))
{
return curr_wearable;
@@ -699,12 +638,12 @@ void LLAgentWearables::sendAgentWearablesRequest()
}
// static
-BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
+BOOL LLAgentWearables::selfHasWearable(EWearableType type)
{
return (gAgentWearables.getWearableCount(type) > 0);
}
-LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index)
+LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index)
{
wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
@@ -722,7 +661,7 @@ LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32
}
}
-void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
+void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable)
{
LLWearable *old_wearable = getWearable(type,index);
@@ -752,27 +691,27 @@ void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index,
}
}
-U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable)
+U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearable)
{
if (wearable == NULL)
{
// no null wearables please!
llwarns << "Null wearable sent for type " << type << llendl;
- return MAX_CLOTHING_PER_TYPE;
+ return MAX_WEARABLES_PER_TYPE;
}
- if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
+ if (type < WT_COUNT || mWearableDatas[type].size() < MAX_WEARABLES_PER_TYPE)
{
mWearableDatas[type].push_back(wearable);
wearableUpdated(wearable);
checkWearableAgainstInventory(wearable);
return mWearableDatas[type].size()-1;
}
- return MAX_CLOTHING_PER_TYPE;
+ return MAX_WEARABLES_PER_TYPE;
}
void LLAgentWearables::wearableUpdated(LLWearable *wearable)
{
- gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);
+ gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE);
wearable->refreshName();
wearable->setLabelUpdated();
@@ -802,15 +741,15 @@ void LLAgentWearables::popWearable(LLWearable *wearable)
}
U32 index = getWearableIndex(wearable);
- LLWearableType::EType type = wearable->getType();
+ EWearableType type = wearable->getType();
- if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
+ if (index < MAX_WEARABLES_PER_TYPE && index < getWearableCount(type))
{
popWearable(type, index);
}
}
-void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)
+void LLAgentWearables::popWearable(const EWearableType type, U32 index)
{
LLWearable *wearable = getWearable(type, index);
if (wearable)
@@ -825,15 +764,15 @@ U32 LLAgentWearables::getWearableIndex(LLWearable *wearable)
{
if (wearable == NULL)
{
- return MAX_CLOTHING_PER_TYPE;
+ return MAX_WEARABLES_PER_TYPE;
}
- const LLWearableType::EType type = wearable->getType();
+ 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_CLOTHING_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++)
@@ -844,10 +783,10 @@ U32 LLAgentWearables::getWearableIndex(LLWearable *wearable)
}
}
- return MAX_CLOTHING_PER_TYPE;
+ return MAX_WEARABLES_PER_TYPE;
}
-const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const
+const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const
{
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
@@ -865,7 +804,7 @@ const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type
}
}
-LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type)
+LLWearable* LLAgentWearables::getTopWearable(const EWearableType type)
{
U32 count = getWearableCount(type);
if ( count == 0)
@@ -876,17 +815,7 @@ LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type)
return getWearable(type, count-1);
}
-LLWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type)
-{
- if (getWearableCount(type) == 0)
- {
- return NULL;
- }
-
- return getWearable(type, 0);
-}
-
-U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const
+U32 LLAgentWearables::getWearableCount(const EWearableType type) const
{
wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
if (wearable_iter == mWearableDatas.end())
@@ -899,7 +828,7 @@ U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const
U32 LLAgentWearables::getWearableCount(const U32 tex_index) const
{
- const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index);
+ const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index);
return getWearableCount(wearable_type);
}
@@ -914,7 +843,7 @@ U32 LLAgentWearables::itemUpdatePendingCount() const
return mItemsAwaitingWearableUpdate.size();
}
-const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const
+const LLUUID LLAgentWearables::getWearableItemID(EWearableType type, U32 index) const
{
const LLWearable *wearable = getWearable(type,index);
if (wearable)
@@ -923,7 +852,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32
return LLUUID();
}
-const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const
+const LLUUID LLAgentWearables::getWearableAssetID(EWearableType type, U32 index) const
{
const LLWearable *wearable = getWearable(type,index);
if (wearable)
@@ -934,26 +863,25 @@ const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U3
BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const
{
- return getWearableFromItemID(item_id) != NULL;
+ const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
+ if (getWearableFromItemID(base_item_id) != NULL)
+ {
+ return TRUE;
+ }
+ return FALSE;
}
-// MULTI-WEARABLE: DEPRECATED (see backwards compatibility)
+// MULTI-WEARABLE: update for multiple
// static
// ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume
// that viewers have a Current Outfit Folder and won't need this message, and thus
-// we can remove/ignore this whole function. EXCEPT gAgentWearables.notifyLoadingStarted
+// we can remove/ignore this whole function.
void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data)
{
// We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates
// that may result from AgentWearablesRequest having been sent more than once.
if (mInitialWearablesUpdateReceived)
return;
-
- // notify subscribers that wearables started loading. See EXT-7777
- // *TODO: find more proper place to not be called from deprecated method.
- // Seems such place is found: LLInitialWearablesFetch::processContents()
- gAgentWearables.notifyLoadingStarted();
-
mInitialWearablesUpdateReceived = true;
LLUUID agent_id;
@@ -977,22 +905,23 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
// Get the UUID of the current outfit folder (will be created if it doesn't exist)
const LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- LLInitialWearablesFetch* outfit = new LLInitialWearablesFetch(current_outfit_id);
+
+ LLInitialWearablesFetch* outfit = new LLInitialWearablesFetch();
//lldebugs << "processAgentInitialWearablesUpdate()" << llendl;
// Add wearables
- // MULTI-WEARABLE: DEPRECATED: Message only supports one wearable per type, will be ignored in future.
+ // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
gAgentWearables.mItemsAwaitingWearableUpdate.clear();
for (S32 i=0; i < num_wearables; i++)
{
// Parse initial wearables data from message system
U8 type_u8 = 0;
gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i);
- if (type_u8 >= LLWearableType::WT_COUNT)
+ if (type_u8 >= WT_COUNT)
{
continue;
}
- const LLWearableType::EType type = (LLWearableType::EType) type_u8;
+ const EWearableType type = (EWearableType) type_u8;
LLUUID item_id;
gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i);
@@ -1005,26 +934,28 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
}
else
{
- LLAssetType::EType asset_type = LLWearableType::getAssetType(type);
+ LLAssetType::EType asset_type = LLWearableDictionary::getAssetType(type);
if (asset_type == LLAssetType::AT_NONE)
{
continue;
}
- // MULTI-WEARABLE: DEPRECATED: this message only supports one wearable per type. Should be ignored in future versions
+ // MULTI-WEARABLE: TODO: update once messages change. Currently use results to populate the zeroth element.
// Store initial wearables data until we know whether we have the current outfit folder or need to use the data.
- LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id);
+ LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id); // MULTI-WEARABLE: update
outfit->add(wearable_data);
}
- lldebugs << " " << LLWearableType::getTypeLabel(type) << llendl;
+ lldebugs << " " << LLWearableDictionary::getTypeLabel(type) << llendl;
}
// Get the complete information on the items in the inventory and set up an observer
// that will trigger when the complete information is fetched.
- outfit->startFetch();
- if(outfit->isFinished())
+ uuid_vec_t folders;
+ folders.push_back(current_outfit_id);
+ outfit->fetch(folders);
+ if(outfit->isEverythingComplete())
{
// everything is already here - call done.
outfit->done();
@@ -1042,13 +973,14 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
// Normally, all wearables referred to "AgentWearablesUpdate" will correspond to actual assets in the
// database. If for some reason, we can't load one of those assets, we can try to reconstruct it so that
// the user isn't left without a shape, for example. (We can do that only after the inventory has loaded.)
-void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type, U32 index)
+void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 index)
{
// Try to recover by replacing missing wearable with a new one.
LLNotificationsUtil::add("ReplacedMissingWearable");
- lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
+ lldebugs << "Wearable " << LLWearableDictionary::getTypeLabel(type) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
+ S32 type_s32 = (S32) type;
setWearable(type,index,new_wearable);
//new_wearable->writeToAvatar(TRUE);
@@ -1059,7 +991,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
LLPointer<LLInventoryCallback> cb =
new addWearableToAgentInventoryCallback(
LLPointer<LLRefCount>(NULL),
- type,
+ type_s32,
index,
new_wearable,
addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
@@ -1082,9 +1014,9 @@ void LLAgentWearables::recoverMissingWearableDone()
}
}
-void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
+void LLAgentWearables::addLocalTextureObject(const EWearableType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
{
- LLWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index);
+ LLWearable* wearable = getWearable((EWearableType)wearable_type, wearable_index);
if (!wearable)
{
llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl;
@@ -1098,7 +1030,7 @@ class OnWearableItemCreatedCB: public LLInventoryCallback
{
public:
OnWearableItemCreatedCB():
- mWearablesAwaitingItems(LLWearableType::WT_COUNT,NULL)
+ mWearablesAwaitingItems(WT_COUNT,NULL)
{
llinfos << "created callback" << llendl;
}
@@ -1124,8 +1056,8 @@ public:
llwarns << "no wearable" << llendl;
return;
}
- LLWearableType::EType type = wearable->getType();
- if (type<LLWearableType::WT_COUNT)
+ EWearableType type = wearable->getType();
+ if (type<WT_COUNT)
{
mWearablesAwaitingItems[type] = wearable;
}
@@ -1149,8 +1081,8 @@ public:
}
if (item && item->isWearableType())
{
- LLWearableType::EType type = item->getWearableType();
- if (type < LLWearableType::WT_COUNT)
+ EWearableType type = item->getWearableType();
+ if (type < WT_COUNT)
{
LLWearable *wearable = mWearablesAwaitingItems[type];
if (wearable)
@@ -1177,30 +1109,30 @@ void LLAgentWearables::createStandardWearables(BOOL female)
gAgentAvatarp->setSex(female ? SEX_FEMALE : SEX_MALE);
- const BOOL create[LLWearableType::WT_COUNT] =
+ const BOOL create[WT_COUNT] =
{
- TRUE, //LLWearableType::WT_SHAPE
- TRUE, //LLWearableType::WT_SKIN
- TRUE, //LLWearableType::WT_HAIR
- TRUE, //LLWearableType::WT_EYES
- TRUE, //LLWearableType::WT_SHIRT
- TRUE, //LLWearableType::WT_PANTS
- TRUE, //LLWearableType::WT_SHOES
- TRUE, //LLWearableType::WT_SOCKS
- FALSE, //LLWearableType::WT_JACKET
- FALSE, //LLWearableType::WT_GLOVES
- TRUE, //LLWearableType::WT_UNDERSHIRT
- TRUE, //LLWearableType::WT_UNDERPANTS
- FALSE //LLWearableType::WT_SKIRT
+ TRUE, //WT_SHAPE
+ TRUE, //WT_SKIN
+ TRUE, //WT_HAIR
+ TRUE, //WT_EYES
+ TRUE, //WT_SHIRT
+ TRUE, //WT_PANTS
+ TRUE, //WT_SHOES
+ TRUE, //WT_SOCKS
+ FALSE, //WT_JACKET
+ FALSE, //WT_GLOVES
+ TRUE, //WT_UNDERSHIRT
+ TRUE, //WT_UNDERPANTS
+ FALSE //WT_SKIRT
};
LLPointer<LLInventoryCallback> cb = new OnWearableItemCreatedCB;
- for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
+ for (S32 i=0; i < WT_COUNT; i++)
{
if (create[i])
{
- llassert(getWearableCount((LLWearableType::EType)i) == 0);
- LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i);
+ llassert(getWearableCount((EWearableType)i) == 0);
+ LLWearable* wearable = LLWearableList::instance().createNewWearable((EWearableType)i);
((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
// no need to update here...
LLUUID category_id = LLUUID::null;
@@ -1235,7 +1167,6 @@ void LLAgentWearables::createStandardWearablesAllDone()
mWearablesLoaded = TRUE;
checkWearablesLoaded();
- notifyLoadingFinished();
updateServer();
@@ -1243,9 +1174,217 @@ void LLAgentWearables::createStandardWearablesAllDone()
gAgentAvatarp->onFirstTEMessageReceived();
}
+// MULTI-WEARABLE: Properly handle multiwearables later.
+void LLAgentWearables::getAllWearablesArray(LLDynamicArray<S32>& wearables)
+{
+ for( S32 i = 0; i < WT_COUNT; ++i )
+ {
+ if (getWearableCount((EWearableType) i) != 0)
+ {
+ wearables.push_back(i);
+ }
+ }
+}
+
+// Note: wearables_to_include should be a list of EWearableType types
+// attachments_to_include should be a list of attachment points
+void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
+ const LLDynamicArray<S32>& wearables_to_include,
+ const LLDynamicArray<S32>& attachments_to_include,
+ BOOL rename_clothing)
+{
+ if (!isAgentAvatarValid()) return;
+
+ // First, make a folder in the Clothes directory.
+ LLUUID folder_id = gInventory.createNewCategory(
+ gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING),
+ LLFolderType::FT_NONE,
+ new_folder_name);
+
+ bool found_first_item = false;
+
+ ///////////////////
+ // Wearables
+
+ if (wearables_to_include.count())
+ {
+ // Then, iterate though each of the wearables and save copies of them in the folder.
+ S32 i;
+ S32 count = wearables_to_include.count();
+ LLDynamicArray<LLUUID> delete_items;
+ LLPointer<LLRefCount> cbdone = NULL;
+ for (i = 0; i < count; ++i)
+ {
+ const S32 type = wearables_to_include[i];
+ for (U32 j=0; j<getWearableCount((EWearableType)i); j++)
+ {
+ LLWearable* old_wearable = getWearable((EWearableType)type, j);
+ if (old_wearable)
+ {
+ std::string new_name;
+ LLWearable* new_wearable;
+ new_wearable = LLWearableList::instance().createCopy(old_wearable);
+ if (rename_clothing)
+ {
+ new_name = new_folder_name;
+ new_name.append(" ");
+ new_name.append(old_wearable->getTypeLabel());
+ LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
+ new_wearable->setName(new_name);
+ }
+
+ LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType)type,j));
+ S32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
+ if (!found_first_item)
+ {
+ found_first_item = true;
+ /* set the focus to the first item */
+ todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE;
+ /* send the agent wearables update when done */
+ cbdone = new sendAgentWearablesUpdateCallback;
+ }
+ LLPointer<LLInventoryCallback> cb =
+ new addWearableToAgentInventoryCallback(
+ cbdone,
+ type,
+ j,
+ new_wearable,
+ todo);
+ llassert(item);
+ if (item)
+ {
+ if (isWearableCopyable((EWearableType)type, j))
+ {
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ folder_id,
+ new_name,
+ cb);
+ }
+ else
+ {
+ move_inventory_item(
+ gAgent.getID(),
+ gAgent.getSessionID(),
+ item->getUUID(),
+ folder_id,
+ new_name,
+ cb);
+ }
+ }
+ }
+ }
+ }
+ gInventory.notifyObservers();
+ }
+
+
+ ///////////////////
+ // Attachments
+
+ if (attachments_to_include.count())
+ {
+ BOOL msg_started = FALSE;
+ LLMessageSystem* msg = gMessageSystem;
+ for (S32 i = 0; i < attachments_to_include.count(); i++)
+ {
+ S32 attachment_pt = attachments_to_include[i];
+ LLViewerJointAttachment* attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachment_pt, (LLViewerJointAttachment*)NULL);
+ 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 = (*attachment_iter)->getItemID();
+ if(item_id.isNull()) continue;
+ LLInventoryItem* item = gInventory.getItem(item_id);
+ if(!item) continue;
+ if(!msg_started)
+ {
+ msg_started = TRUE;
+ msg->newMessage("CreateNewOutfitAttachments");
+ msg->nextBlock("AgentData");
+ msg->addUUID("AgentID", gAgent.getID());
+ msg->addUUID("SessionID", gAgent.getSessionID());
+ msg->nextBlock("HeaderData");
+ msg->addUUID("NewFolderID", folder_id);
+ }
+ msg->nextBlock("ObjectData");
+ msg->addUUID("OldItemID", item_id);
+ msg->addUUID("OldFolderID", item->getParentUUID());
+ }
+ }
+
+ if (msg_started)
+ {
+ gAgent.sendReliableMessage();
+ }
+
+ }
+}
+
+class LLShowCreatedOutfit: public LLInventoryCallback
+{
+public:
+ LLShowCreatedOutfit(LLUUID& folder_id):
+ mFolderID(folder_id)
+ {
+ }
+
+ virtual ~LLShowCreatedOutfit()
+ {
+ LLSD key;
+ LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key);
+ LLPanelOutfitsInventory *outfit_panel =
+ dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
+ if (outfit_panel)
+ {
+ outfit_panel->getRootFolder()->clearSelection();
+ outfit_panel->getRootFolder()->setSelectionByID(mFolderID, TRUE);
+ }
+ LLAccordionCtrlTab* tab_outfits = outfit_panel ? outfit_panel->findChild<LLAccordionCtrlTab>("tab_outfits") : 0;
+ if (tab_outfits && !tab_outfits->getDisplayChildren())
+ {
+ tab_outfits->changeOpenClose(tab_outfits->getDisplayChildren());
+ }
+
+ LLAppearanceMgr::instance().updateIsDirty();
+ LLAppearanceMgr::instance().updatePanelOutfitName("");
+ }
+
+ virtual void fire(const LLUUID&)
+ {
+ }
+
+private:
+ LLUUID mFolderID;
+};
+
+LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)
+{
+ if (!isAgentAvatarValid()) return LLUUID::null;
+
+ // First, make a folder in the My Outfits directory.
+ const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+ LLUUID folder_id = gInventory.createNewCategory(
+ parent_id,
+ LLFolderType::FT_OUTFIT,
+ new_folder_name);
+
+ LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id);
+ LLAppearanceMgr::instance().shallowCopyCategoryContents(LLAppearanceMgr::instance().getCOF(),folder_id, cb);
+ LLAppearanceMgr::instance().createBaseOutfitLink(folder_id, cb);
+
+ return folder_id;
+}
+
void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
{
- LLUUID first_item_id = getWearableItemID((LLWearableType::EType)type, index);
+ LLUUID first_item_id = getWearableItemID((EWearableType)type, index);
// Open the inventory and select the first item we added.
if (first_item_id.notNull())
{
@@ -1276,10 +1415,10 @@ void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback
cb);
}
-void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_remove_all, U32 index)
+void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_all, U32 index)
{
if (gAgent.isTeen() &&
- (type == LLWearableType::WT_UNDERSHIRT || type == LLWearableType::WT_UNDERPANTS))
+ (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
@@ -1323,7 +1462,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_
bool LLAgentWearables::onRemoveWearableDialog(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
- LLWearableType::EType type = (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger();
+ EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger();
S32 index = (S32)notification["payload"]["wearable_index"].asInteger();
switch(option)
{
@@ -1347,7 +1486,7 @@ bool LLAgentWearables::onRemoveWearableDialog(const LLSD& notification, const LL
}
// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal.
-void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, bool do_remove_all, U32 index)
+void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_remove_all, U32 index)
{
//LLAgentDumper dumper("removeWearable");
if (do_remove_all)
@@ -1396,11 +1535,11 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
{
// note: shirt is the first non-body part wearable item. Update if wearable order changes.
// This loop should remove all clothing, but not any body parts
- for (S32 type = 0; type < (S32)LLWearableType::WT_COUNT; type++)
+ for (S32 type = 0; type < (S32)WT_COUNT; type++)
{
- if (LLWearableType::getAssetType((LLWearableType::EType)type) == LLAssetType::AT_CLOTHING)
+ if (LLWearableDictionary::getAssetType((EWearableType)type) == LLAssetType::AT_CLOTHING)
{
- removeWearable((LLWearableType::EType)type, true, 0);
+ removeWearable((EWearableType)type, true, 0);
}
}
}
@@ -1417,12 +1556,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
llassert(new_wearable);
if (new_wearable)
{
- const LLWearableType::EType type = new_wearable->getType();
+ const EWearableType type = new_wearable->getType();
new_wearable->setName(new_item->getName());
new_wearable->setItemID(new_item->getUUID());
- if (LLWearableType::getAssetType(type) == LLAssetType::AT_BODYPART)
+ if (LLWearableDictionary::getAssetType(type) == LLAssetType::AT_BODYPART)
{
// exactly one wearable per body part
setWearable(type,0,new_wearable);
@@ -1448,12 +1587,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// Start rendering & update the server
mWearablesLoaded = TRUE;
checkWearablesLoaded();
- notifyLoadingFinished();
queryWearableCache();
updateServer();
- gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");
-
lldebugs << "setWearableOutfit() end" << llendl;
}
@@ -1468,7 +1604,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
return;
}
- const LLWearableType::EType type = new_wearable->getType();
+ const EWearableType type = new_wearable->getType();
if (!do_append)
{
@@ -1481,7 +1617,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
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;
+ lldebugs << "No change to wearable asset and item: " << LLWearableDictionary::getInstance()->getWearableEntry(type) << llendl;
return;
}
@@ -1538,7 +1674,7 @@ bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD&
// MULTI_WEARABLE: unify code after null objects are gone.
void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
{
- const LLWearableType::EType type = new_wearable->getType();
+ const EWearableType type = new_wearable->getType();
if (do_append && getWearableItemID(type,0).notNull())
{
@@ -1603,18 +1739,37 @@ void LLAgentWearables::queryWearableCache()
S32 num_queries = 0;
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
{
- LLUUID hash_id = computeBakedTextureHash((EBakedTextureIndex) baked_index);
- if (hash_id.notNull())
+ const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+ LLMD5 hash;
+ bool hash_computed = false;
+ for (U8 i=0; i < baked_dict->mWearables.size(); i++)
{
+ const EWearableType baked_type = baked_dict->mWearables[i];
+ const U32 num_wearables = getWearableCount(baked_type);
+ for (U32 index = 0; index < num_wearables; ++index)
+ {
+ const LLWearable* wearable = getWearable(baked_type,index);
+ if (wearable)
+ {
+ LLUUID asset_id = wearable->getAssetID();
+ hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
+ hash_computed = true;
+ }
+ }
+ }
+ hash.finalize();
+ if (hash_computed)
+ {
+ LLUUID hash_id;
+ hash.raw_digest(hash_id.mData);
+ hash_id ^= baked_dict->mWearablesHashID;
num_queries++;
// *NOTE: make sure at least one request gets packed
- ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
-
//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
gMessageSystem->addUUIDFast(_PREHASH_ID, hash_id);
- gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)te_index);
+ gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index);
}
gAgentQueryManager.mActiveCacheQueries[baked_index] = gAgentQueryManager.mWearablesCacheQueryID;
@@ -1626,64 +1781,22 @@ void LLAgentWearables::queryWearableCache()
gAgentQueryManager.mWearablesCacheQueryID++;
}
-LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
- BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
-{
- LLUUID hash_id;
- bool hash_computed = false;
- LLMD5 hash;
- const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
-
- for (U8 i=0; i < baked_dict->mWearables.size(); i++)
- {
- const LLWearableType::EType baked_type = baked_dict->mWearables[i];
- const U32 num_wearables = getWearableCount(baked_type);
- for (U32 index = 0; index < num_wearables; ++index)
- {
- const LLWearable* wearable = getWearable(baked_type,index);
- if (wearable)
- {
- LLUUID asset_id = wearable->getAssetID();
- hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
- hash_computed = true;
- }
- }
- }
- if (hash_computed)
- {
- hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
-
- // Add some garbage into the hash so that it becomes invalid.
- if (!generate_valid_hash)
- {
- if (isAgentAvatarValid())
- {
- hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
- }
- }
- hash.finalize();
- hash.raw_digest(hash_id.mData);
- }
-
- return hash_id;
-}
-
// User has picked "remove from avatar" from a menu.
// static
-void LLAgentWearables::userRemoveWearable(const LLWearableType::EType &type, const U32 &index)
+void LLAgentWearables::userRemoveWearable(const EWearableType &type, const U32 &index)
{
- if (!(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES)) //&&
- //!((!gAgent.isTeen()) && (type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT)))
+ if (!(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES)) //&&
+ //!((!gAgent.isTeen()) && (type==WT_UNDERPANTS || type==WT_UNDERSHIRT)))
{
gAgentWearables.removeWearable(type,false,index);
}
}
//static
-void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &type)
+void LLAgentWearables::userRemoveWearablesOfType(const EWearableType &type)
{
- if (!(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES)) //&&
- //!((!gAgent.isTeen()) && (type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT)))
+ if (!(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR || type==WT_EYES)) //&&
+ //!((!gAgent.isTeen()) && (type==WT_UNDERPANTS || type==WT_UNDERSHIRT)))
{
gAgentWearables.removeWearable(type,true,0);
}
@@ -1693,12 +1806,14 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty
void LLAgentWearables::userRemoveAllClothes()
{
// We have to do this up front to avoid having to deal with the case of multiple wearables being dirty.
- if (gAgentCamera.cameraCustomizeAvatar())
+ if (gFloaterCustomize)
+ {
+ gFloaterCustomize->askToSaveIfDirty(userRemoveAllClothesStep2);
+ }
+ else
{
- // switching to outfit editor should automagically save any currently edited wearable
- LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD().with("type", "edit_outfit"));
+ userRemoveAllClothesStep2(TRUE);
}
- userRemoveAllClothesStep2(TRUE);
}
// static
@@ -1706,17 +1821,17 @@ void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed)
{
if (proceed)
{
- gAgentWearables.removeWearable(LLWearableType::WT_SHIRT,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_PANTS,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_SHOES,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_SOCKS,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_JACKET,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_GLOVES,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_UNDERSHIRT,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_UNDERPANTS,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_SKIRT,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_ALPHA,true,0);
- gAgentWearables.removeWearable(LLWearableType::WT_TATTOO,true,0);
+ gAgentWearables.removeWearable(WT_SHIRT,true,0);
+ gAgentWearables.removeWearable(WT_PANTS,true,0);
+ gAgentWearables.removeWearable(WT_SHOES,true,0);
+ gAgentWearables.removeWearable(WT_SOCKS,true,0);
+ gAgentWearables.removeWearable(WT_JACKET,true,0);
+ gAgentWearables.removeWearable(WT_GLOVES,true,0);
+ 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);
}
}
@@ -1879,10 +1994,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra
msg->nextBlockFast(_PREHASH_ObjectData );
msg->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
msg->addUUIDFast(_PREHASH_OwnerID, item->getPermissions().getOwner());
- if (gSavedSettings.getBOOL("MultipleAttachments"))
- msg->addU8Fast(_PREHASH_AttachmentPt, 0 | ATTACHMENT_ADD );
- else
- msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
+ msg->addU8Fast(_PREHASH_AttachmentPt, 0 ); // Wear at the previous or default attachment point
pack_permissions_slam(msg, item->getFlags(), item->getPermissions());
msg->addStringFast(_PREHASH_Name, item->getName());
msg->addStringFast(_PREHASH_Description, item->getDescription());
@@ -1906,166 +2018,39 @@ void LLAgentWearables::checkWearablesLoaded() const
#endif
}
-// Returns false if the given wearable is already topmost/bottommost
-// (depending on closer_to_body parameter).
-bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body)
-{
- const LLWearable* wearable = getWearableFromItemID(item_id);
- if (!wearable) return false;
-
- LLWearableType::EType wtype = wearable->getType();
- const LLWearable* marginal_wearable = closer_to_body ? getBottomWearable(wtype) : getTopWearable(wtype);
- if (!marginal_wearable) return false;
-
- return wearable != marginal_wearable;
-}
-
BOOL LLAgentWearables::areWearablesLoaded() const
{
checkWearablesLoaded();
return mWearablesLoaded;
}
-// MULTI-WEARABLE: DEPRECATED: item pending count relies on old messages that don't support multi-wearables. do not trust to be accurate
+// MULTI-WEARABLE: update for multiple indices.
void LLAgentWearables::updateWearablesLoaded()
{
mWearablesLoaded = (itemUpdatePendingCount()==0);
- if (mWearablesLoaded)
- {
- notifyLoadingFinished();
- }
}
bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const
{
if (!wearable) return false;
- LLWearableType::EType type = wearable->getType();
+ EWearableType type = wearable->getType();
// Make sure the user always has at least one shape, skin, eyes, and hair type currently worn.
- return !(((type == LLWearableType::WT_SHAPE) || (type == LLWearableType::WT_SKIN) || (type == LLWearableType::WT_HAIR) || (type == LLWearableType::WT_EYES))
+ return !(((type == WT_SHAPE) || (type == WT_SKIN) || (type == WT_HAIR) || (type == WT_EYES))
&& (getWearableCount(type) <= 1) );
}
void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)
{
- for( S32 type = 0; type < LLWearableType::WT_COUNT; ++type )
+ for( S32 type = 0; type < WT_COUNT; ++type )
{
- for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count)
+ for (S32 count = 0; count < (S32)getWearableCount((EWearableType)type); ++count)
{
- LLWearable *wearable = getWearable((LLWearableType::EType)type,count);
- llassert(wearable);
- if (wearable)
- {
- wearable->animateParams(delta, upload_bake);
- }
+ LLWearable *wearable = getWearable((EWearableType)type,count);
+ wearable->animateParams(delta, upload_bake);
}
}
}
-bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool closer_to_body)
-{
- if (!item) return false;
- if (!item->isWearableType()) return false;
-
- wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType());
- if (wearable_iter == mWearableDatas.end()) return false;
-
- wearableentry_vec_t& wearable_vec = wearable_iter->second;
- if (wearable_vec.empty()) return false;
-
- const LLUUID& asset_id = item->getAssetUUID();
-
- //nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body)
- if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false;
- if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false;
-
- for (U32 i = 0; i < wearable_vec.size(); ++i)
- {
- LLWearable* wearable = wearable_vec[i];
- if (!wearable) continue;
- if (wearable->getAssetID() != asset_id) continue;
-
- //swapping wearables
- U32 swap_i = closer_to_body ? i-1 : i+1;
- wearable_vec[i] = wearable_vec[swap_i];
- wearable_vec[swap_i] = wearable;
- return true;
- }
-
- return false;
-}
-
-// static
-void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id)
-{
- if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return;
-
- LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
- LLAssetType::EType asset_type = wearable->getAssetType();
- LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
- LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL;
- LLUUID folder_id;
-
- if (parent_id.notNull())
- {
- folder_id = parent_id;
- }
- else
- {
- LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type);
- folder_id = gInventory.findCategoryUUIDForType(folder_type);
- }
-
- create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
- folder_id, wearable->getTransactionID(), wearable->getName(),
- wearable->getDescription(), asset_type, inv_type, wearable->getType(),
- wearable->getPermissions().getMaskNextOwner(),
- cb);
-}
-
-// static
-void LLAgentWearables::editWearable(const LLUUID& item_id)
-{
- LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id);
- if (!item)
- {
- llwarns << "Failed to get linked item" << llendl;
- return;
- }
-
- LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
- if (!wearable)
- {
- llwarns << "Cannot get wearable" << llendl;
- return;
- }
-
- if (!gAgentWearables.isWearableModifiable(item->getUUID()))
- {
- llwarns << "Cannot modify wearable" << llendl;
- return;
- }
-
- LLPanel* panel = LLSideTray::getInstance()->getPanel("sidepanel_appearance");
- LLSidepanelAppearance::editWearable(wearable, panel);
-}
-
-// Request editing the item after it gets worn.
-void LLAgentWearables::requestEditingWearable(const LLUUID& item_id)
-{
- mItemToEdit = gInventory.getLinkedItemID(item_id);
-}
-
-// Start editing the item if previously requested.
-void LLAgentWearables::editWearableIfRequested(const LLUUID& item_id)
-{
- if (mItemToEdit.notNull() &&
- mItemToEdit == gInventory.getLinkedItemID(item_id))
- {
- LLAgentWearables::editWearable(item_id);
- mItemToEdit.setNull();
- }
-}
-
void LLAgentWearables::updateServer()
{
sendAgentWearablesUpdate();
@@ -2076,39 +2061,18 @@ void LLAgentWearables::populateMyOutfitsFolder(void)
{
llinfos << "starting outfit population" << llendl;
- const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
- LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch(my_outfits_id);
- outfits->mMyOutfitsID = my_outfits_id;
+ LLLibraryOutfitsFetch* outfits = new LLLibraryOutfitsFetch();
// Get the complete information on the items in the inventory and
// setup an observer that will wait for that to happen.
+ uuid_vec_t folders;
+ outfits->mMyOutfitsID = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+
+ folders.push_back(outfits->mMyOutfitsID);
gInventory.addObserver(outfits);
- outfits->startFetch();
- if (outfits->isFinished())
+ outfits->fetch(folders);
+ if (outfits->isEverythingComplete())
{
outfits->done();
}
}
-
-boost::signals2::connection LLAgentWearables::addLoadingStartedCallback(loading_started_callback_t cb)
-{
- return mLoadingStartedSignal.connect(cb);
-}
-
-boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_t cb)
-{
- return mLoadedSignal.connect(cb);
-}
-
-void LLAgentWearables::notifyLoadingStarted()
-{
- mCOFChangeInProgress = true;
- mLoadingStartedSignal();
-}
-
-void LLAgentWearables::notifyLoadingFinished()
-{
- mCOFChangeInProgress = false;
- mLoadedSignal();
-}
-// EOF