diff options
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r-- | indra/newview/llagentwearables.cpp | 219 |
1 files changed, 134 insertions, 85 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 2cfa8d2a54..a26b799d3d 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -46,6 +46,7 @@ #include "llwearablelist.h" #include "llgesturemgr.h" #include "llappearancemgr.h" +#include "lltexlayer.h" #include <boost/scoped_ptr.hpp> @@ -65,11 +66,10 @@ public: struct InitialWearableData { EWearableType mType; - U32 mIndex; LLUUID mItemID; LLUUID mAssetID; - InitialWearableData(EWearableType type, U32 index, LLUUID itemID, LLUUID assetID) : - mType(type), mIndex(index), 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; @@ -139,11 +139,6 @@ LLAgentWearables::LLAgentWearables() : mWearablesLoaded(FALSE), mAvatarObject(NULL) { - // MULTI-WEARABLE: TODO remove null entries. - for (U32 i = 0; i < WT_COUNT; i++) - { - mWearableDatas[(EWearableType)i].push_back(NULL); - } } LLAgentWearables::~LLAgentWearables() @@ -237,10 +232,16 @@ void LLAgentWearables::addWearabletoAgentInventoryDone(const S32 type, { wearable->setItemID(item_id); } - setWearable((EWearableType)type,index,wearable); if (old_item_id.notNull()) + { gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); + setWearable((EWearableType)type,index,wearable); + } + else + { + pushWearable((EWearableType)type,wearable); + } gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); LLViewerInventoryItem* item = gInventory.getItem(item_id); if (item && wearable) @@ -260,11 +261,11 @@ void LLAgentWearables::sendAgentWearablesUpdate() { // MULTI-WEARABLE: call i "type" or something. // First make sure that we have inventory items for each wearable - for (S32 i=0; i < WT_COUNT; ++i) + for (S32 type=0; type < WT_COUNT; ++type) { - for (U32 j=0; j < getWearableCount((EWearableType)i); j++) + for (U32 j=0; j < getWearableCount((EWearableType)type); ++j) { - LLWearable* wearable = getWearable((EWearableType)i,j); + LLWearable* wearable = getWearable((EWearableType)type,j); if (wearable) { if (wearable->getItemID().isNull()) @@ -272,7 +273,7 @@ void LLAgentWearables::sendAgentWearablesUpdate() LLPointer<LLInventoryCallback> cb = new addWearableToAgentInventoryCallback( LLPointer<LLRefCount>(NULL), - i, + type, j, wearable, addWearableToAgentInventoryCallback::CALL_NONE); @@ -299,15 +300,15 @@ void LLAgentWearables::sendAgentWearablesUpdate() lldebugs << "sendAgentWearablesUpdate()" << llendl; // MULTI-WEARABLE: update for multi-wearables after server-side support is in. - for (S32 i=0; i < WT_COUNT; ++i) + for (S32 type=0; type < WT_COUNT; ++type) { gMessageSystem->nextBlockFast(_PREHASH_WearableData); - U8 type_u8 = (U8)i; + U8 type_u8 = (U8)type; gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8); // MULTI-WEARABLE: TODO: hacked index to 0, needs to loop over all once messages support this. - LLWearable* wearable = getWearable((EWearableType)i, 0); + LLWearable* wearable = getWearable((EWearableType)type, 0); if (wearable) { //llinfos << "Sending wearable " << wearable->getName() << llendl; @@ -327,19 +328,18 @@ void LLAgentWearables::sendAgentWearablesUpdate() gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null); } - lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl; + lldebugs << " " << LLWearableDictionary::getTypeLabel((EWearableType)type) << ": " << (wearable ? wearable->getAssetID() : LLUUID::null) << llendl; } gAgent.sendReliableMessage(); } -// MULTI-WEARABLE: add index. 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())) { LLUUID old_item_id = old_wearable->getItemID(); - LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar(old_wearable); + LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()? setWearable(type,index,new_wearable); @@ -391,7 +391,6 @@ void LLAgentWearables::saveWearable(const EWearableType type, const U32 index, B } } -// MULTI-WEARABLE: add index void LLAgentWearables::saveWearableAs(const EWearableType type, const U32 index, const std::string& new_name, @@ -417,7 +416,7 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, } std::string trunc_name(new_name); LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); - LLWearable* new_wearable = LLWearableList::instance().createCopyFromAvatar( + LLWearable* new_wearable = LLWearableList::instance().createCopy( old_wearable, trunc_name); LLPointer<LLInventoryCallback> cb = @@ -451,10 +450,8 @@ void LLAgentWearables::saveWearableAs(const EWearableType type, void LLAgentWearables::revertWearable(const EWearableType type, const U32 index) { LLWearable* wearable = getWearable(type, index); - if (wearable) - { - wearable->writeToAvatar(TRUE); - } + wearable->revertValues(); + gAgent.sendAgentSetAppearance(); } @@ -604,13 +601,10 @@ void LLAgentWearables::sendAgentWearablesRequest() gAgent.sendReliableMessage(); } -// MULTI-WEARABLE: update for multiple items per type. -// Used to enable/disable menu items. // static BOOL LLAgentWearables::selfHasWearable(EWearableType type) { - // MULTI-WEARABLE: TODO could be getWearableCount > 0, once null entries have been eliminated. - return gAgentWearables.getWearable(type,0) != NULL; + return (gAgentWearables.getWearableCount(type) > 0); } LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) @@ -633,6 +627,11 @@ LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable) { + if (!getWearable(type,index)) + { + pushWearable(type,wearable); + return; + } wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); if (wearable_iter == mWearableDatas.end()) { @@ -650,6 +649,59 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab } } +U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearable) +{ + if (wearable == NULL) + { + // no null wearables please! + //TODO: insert llwarns + return MAX_ATTACHMENTS_PER_TYPE; + } + if (type < WT_COUNT) + { + mWearableDatas[type].push_back(wearable); + return mWearableDatas[type].size()-1; + } + return MAX_ATTACHMENTS_PER_TYPE; +} + +void LLAgentWearables::popWearable(const EWearableType type, LLWearable *wearable) +{ + U32 index = getWearableIndex(type, wearable); + if (index < MAX_ATTACHMENTS_PER_TYPE && index < getWearableCount(type)) + { + popWearable(type, index); + } +} + +void LLAgentWearables::popWearable(const EWearableType type, U32 index) +{ + if (getWearable(type, index)) + { + mWearableDatas[type].erase(mWearableDatas[type].begin() + index); + } +} + +U32 LLAgentWearables::getWearableIndex(const EWearableType type, LLWearable *wearable) +{ + 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; + } + const wearableentry_vec_t& wearable_vec = wearable_iter->second; + for(U32 index = 0; index < wearable_vec.size(); index++) + { + if (wearable_vec[index] == wearable) + { + return index; + } + } + + return MAX_ATTACHMENTS_PER_TYPE; +} + const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index) const { wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); @@ -668,7 +720,17 @@ const LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 in } } -//MULTI-WEARABLE: this will give wrong values until we get rid of the "always one empty object" scheme. +LLWearable* LLAgentWearables::getTopWearable(const EWearableType type) +{ + U32 count = getWearableCount(type); + if ( count == 0) + { + return NULL; + } + + return getWearable(type, count-1); +} + U32 LLAgentWearables::getWearableCount(const EWearableType type) const { wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type); @@ -680,6 +742,13 @@ U32 LLAgentWearables::getWearableCount(const EWearableType type) const return wearable_vec.size(); } +U32 LLAgentWearables::getWearableCount(const U32 tex_index) const +{ + const EWearableType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index); + return getWearableCount(wearable_type); +} + + BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const { return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end(); @@ -798,7 +867,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs // 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, 0, item_id, asset_id); // MULTI-WEARABLE: update + LLInitialWearablesFetch::InitialWearableData wearable_data(type, item_id, asset_id); // MULTI-WEARABLE: update outfit->mAgentInitialWearables.push_back(wearable_data); } @@ -832,7 +901,7 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* { boost::scoped_ptr<LLInitialWearablesFetch::InitialWearableData> wear_data((LLInitialWearablesFetch::InitialWearableData*)userdata); const EWearableType type = wear_data->mType; - const U32 index = wear_data->mIndex; + U32 index = 0; LLVOAvatarSelf* avatar = gAgent.getAvatarObject(); if (!avatar) @@ -843,22 +912,19 @@ void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* if (wearable) { llassert(type == wearable->getType()); - // MULTI-WEARABLE: is this always zeroth element? Change sometime. wearable->setItemID(wear_data->mItemID); - gAgentWearables.setWearable(type, index, wearable); + index = gAgentWearables.pushWearable(type, wearable); gAgentWearables.mItemsAwaitingWearableUpdate.erase(wear_data->mItemID); // disable composites if initial textures are baked avatar->setupComposites(); - wearable->writeToAvatar(FALSE); avatar->setCompositeUpdatesEnabled(TRUE); gInventory.addChangedMask(LLInventoryObserver::LABEL, wearable->getItemID()); } else { // Somehow the asset doesn't exist in the database. - // MULTI-WEARABLE: assuming zeroth elt gAgentWearables.recoverMissingWearable(type,index); } @@ -898,7 +964,7 @@ void LLAgentWearables::recoverMissingWearable(const EWearableType type, U32 inde S32 type_s32 = (S32) type; setWearable(type,index,new_wearable); - new_wearable->writeToAvatar(TRUE); + //new_wearable->writeToAvatar(TRUE); // Add a new one in the lost and found folder. // (We used to overwrite the "not found" one, but that could potentially @@ -938,8 +1004,8 @@ void LLAgentWearables::addLocalTextureObject(const EWearableType wearable_type, { llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl; } - - wearable->setLocalTextureObject(texture_type, new LLLocalTextureObject()); + LLLocalTextureObject* lto = new LLLocalTextureObject(); + wearable->setLocalTextureObject(texture_type, lto); } void LLAgentWearables::createStandardWearables(BOOL female) @@ -982,17 +1048,15 @@ void LLAgentWearables::createStandardWearables(BOOL female) once = true; donecb = new createStandardWearablesAllDoneCallback; } - // MULTI_WEARABLE: only elt 0, may be the right thing? - llassert(getWearable((EWearableType)i,0) == NULL); + llassert(getWearableCount((EWearableType)i) == 0); LLWearable* wearable = LLWearableList::instance().createNewWearable((EWearableType)i); - setWearable((EWearableType)i,0,wearable); + U32 index = pushWearable((EWearableType)i,wearable); // no need to update here... - // MULTI_WEARABLE: hardwired index = 0 here. LLPointer<LLInventoryCallback> cb = new addWearableToAgentInventoryCallback( donecb, i, - 0, + index, wearable, addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE); addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE); @@ -1002,11 +1066,9 @@ void LLAgentWearables::createStandardWearables(BOOL female) void LLAgentWearables::createStandardWearablesDone(S32 type, U32 index) { - LLWearable* wearable = getWearable((EWearableType)type, index); - - if (wearable) + if (mAvatarObject) { - wearable->writeToAvatar(TRUE); + mAvatarObject->updateVisualParams(); } } @@ -1023,12 +1085,12 @@ void LLAgentWearables::createStandardWearablesAllDone() mAvatarObject->onFirstTEMessageReceived(); } +// MULTI-WEARABLE: Properly handle multiwearables later. void LLAgentWearables::getAllWearablesArray(LLDynamicArray<S32>& wearables) { for( S32 i = 0; i < WT_COUNT; ++i ) { - // MULTI-WEARABLE: Properly handle multiwearables later. - if (getWearable( (EWearableType) i, 0 ) != NULL) + if (getWearableCount( (EWearableType) i) != 0 ) { wearables.push_back(i); } @@ -1233,6 +1295,13 @@ 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)) + { + // 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 (do_remove_all) { @@ -1240,16 +1309,8 @@ void LLAgentWearables::removeWearable(const EWearableType type, bool do_remove_a } else { -// MULTI_WEARABLE: handle vector changes from arbitrary removal. LLWearable* old_wearable = getWearable(type,index); - if ((gAgent.isTeen()) - && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS)) - { - // Can't take off underclothing in simple UI mode or on PG accounts - return; - } - if (old_wearable) { if (old_wearable->isDirty()) @@ -1308,26 +1369,22 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem { LLWearable* old_wearable = getWearable(type,i); gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,i)); - setWearable(type,i,NULL); + popWearable(type,i); //queryWearableCache(); // moved below - // MULTI_WEARABLE: FIXME - currently we keep a null entry, so can't delete the last one. - if (i>0) - { - mWearableDatas[type].pop_back(); - } if (old_wearable) { old_wearable->removeFromAvatar(TRUE); } } + mWearableDatas[type].clear(); } else { LLWearable* old_wearable = getWearable(type, index); gInventory.addChangedMask(LLInventoryObserver::LABEL, getWearableItemID(type,index)); - setWearable(type,index,NULL); + popWearable(type, index); //queryWearableCache(); // moved below @@ -1335,16 +1392,6 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem { old_wearable->removeFromAvatar(TRUE); } - - // MULTI_WEARABLE: logic changes if null entries go away - if (getWearableCount(type)>1) - { - // Have to shrink the vector and clean up the item. - wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type); - llassert_always(wearable_iter != mWearableDatas.end()); - wearableentry_vec_t& wearable_vec = wearable_iter->second; - wearable_vec.erase( wearable_vec.begin() + index ); - } } queryWearableCache(); @@ -1429,7 +1476,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { wearables_being_removed.push_back(wearable); } - setWearable((EWearableType)i,0,NULL); + removeWearable((EWearableType)i,true,0); } } @@ -1450,9 +1497,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it } } - for (i = 0; i < count; i++) + if (mAvatarObject) { - wearables[i]->writeToAvatar(TRUE); + mAvatarObject->updateVisualParams(); } // Start rendering & update the server @@ -1578,7 +1625,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n //llinfos << "LLVOAvatar::setWearableItem()" << llendl; queryWearableCache(); - new_wearable->writeToAvatar(TRUE); + //new_wearable->writeToAvatar(TRUE); updateServer(); } @@ -1612,13 +1659,16 @@ void LLAgentWearables::queryWearableCache() LLUUID hash; for (U8 i=0; i < baked_dict->mWearables.size(); i++) { - // EWearableType baked_type = gBakedWearableMap[baked_index][baked_num]; const EWearableType baked_type = baked_dict->mWearables[i]; - // MULTI_WEARABLE: assuming 0th - const LLWearable* wearable = getWearable(baked_type,0); - if (wearable) + // MULTI_WEARABLE: not order-dependent + const U32 num_wearables = getWearableCount(baked_type); + for (U32 index = 0; index < num_wearables; ++index) { - hash ^= wearable->getAssetID(); + const LLWearable* wearable = getWearable(baked_type,index); + if (wearable) + { + hash ^= wearable->getAssetID(); + } } } if (hash.notNull()) @@ -1672,7 +1722,6 @@ void LLAgentWearables::userRemoveAllClothes(void* userdata) } // static -// MULTI_WEARABLE: removing all here. void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed) { if (proceed) |