diff options
Diffstat (limited to 'indra/newview/llagentwearables.cpp')
-rw-r--r-- | indra/newview/llagentwearables.cpp | 2476 |
1 files changed, 1238 insertions, 1238 deletions
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index db99f20775..d2046c0f83 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llagentwearables.cpp * @brief LLAgentWearables class implementation * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, 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. - * + * * 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. - * + * * 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 - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -64,56 +64,56 @@ using namespace LLAvatarAppearanceDefines; void set_default_permissions(LLViewerInventoryItem* item) { - llassert(item); - LLPermissions perm = item->getPermissions(); - if (perm.getMaskNextOwner() != LLFloaterPerms::getNextOwnerPerms("Wearables") - || perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Wearables") - || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Wearables")) - { - perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables")); - perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables")); - perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); + llassert(item); + LLPermissions perm = item->getPermissions(); + if (perm.getMaskNextOwner() != LLFloaterPerms::getNextOwnerPerms("Wearables") + || perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Wearables") + || perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Wearables")) + { + perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables")); + perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables")); + perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables")); - item->setPermissions(perm); + item->setPermissions(perm); - item->updateServer(FALSE); - } + item->updateServer(FALSE); + } } // Callback to wear and start editing an item that has just been created. void wear_and_edit_cb(const LLUUID& inv_item) { - if (inv_item.isNull()) return; - - LLViewerInventoryItem* item = gInventory.getItem(inv_item); - if (!item) return; + if (inv_item.isNull()) return; + + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (!item) return; - set_default_permissions(item); + set_default_permissions(item); - // item was just created, update even if permissions did not changed - gInventory.updateItem(item); - gInventory.notifyObservers(); + // item was just created, update even if permissions did not changed + gInventory.updateItem(item); + gInventory.notifyObservers(); - // Request editing the item after it gets worn. - gAgentWearables.requestEditingWearable(inv_item); - - // Wear it. - LLAppearanceMgr::instance().wearItemOnAvatar(inv_item,true); + // Request editing the item after it gets worn. + gAgentWearables.requestEditingWearable(inv_item); + + // Wear it. + LLAppearanceMgr::instance().wearItemOnAvatar(inv_item,true); } void wear_cb(const LLUUID& inv_item) { - if (!inv_item.isNull()) - { - LLViewerInventoryItem* item = gInventory.getItem(inv_item); - if (item) - { - set_default_permissions(item); - - gInventory.updateItem(item); - gInventory.notifyObservers(); - } - } + if (!inv_item.isNull()) + { + LLViewerInventoryItem* item = gInventory.getItem(inv_item); + if (item) + { + set_default_permissions(item); + + gInventory.updateItem(item); + gInventory.notifyObservers(); + } + } } /////////////////////////////////////////////////////////////////////////////// @@ -125,83 +125,83 @@ void wear_cb(const LLUUID& inv_item) // turns up in other inventories. void checkWearableAgainstInventory(LLViewerWearable *wearable) { - if (wearable->getItemID().isNull()) - return; - - // Check for wearable type consistent with inventory item wearable type. - LLViewerInventoryItem *item = gInventory.getItem(wearable->getItemID()); - if (item) - { - if (!item->isWearableType()) - { - LL_WARNS() << "wearable associated with non-wearable item" << LL_ENDL; - } - if (item->getWearableType() != wearable->getType()) - { - LL_WARNS() << "type mismatch: wearable " << wearable->getName() - << " has type " << wearable->getType() - << " but inventory item " << item->getName() - << " has type " << item->getWearableType() << LL_ENDL; - } - } - else - { - LL_WARNS() << "wearable inventory item not found" << wearable->getName() - << " itemID " << wearable->getItemID().asString() << LL_ENDL; - } + if (wearable->getItemID().isNull()) + return; + + // Check for wearable type consistent with inventory item wearable type. + LLViewerInventoryItem *item = gInventory.getItem(wearable->getItemID()); + if (item) + { + if (!item->isWearableType()) + { + LL_WARNS() << "wearable associated with non-wearable item" << LL_ENDL; + } + if (item->getWearableType() != wearable->getType()) + { + LL_WARNS() << "type mismatch: wearable " << wearable->getName() + << " has type " << wearable->getType() + << " but inventory item " << item->getName() + << " has type " << item->getWearableType() << LL_ENDL; + } + } + else + { + LL_WARNS() << "wearable inventory item not found" << wearable->getName() + << " itemID " << wearable->getItemID().asString() << LL_ENDL; + } } void LLAgentWearables::dump() { - LL_INFOS() << "LLAgentWearablesDump" << LL_ENDL; - for (S32 i = 0; i < LLWearableType::WT_COUNT; i++) - { - U32 count = getWearableCount((LLWearableType::EType)i); - LL_INFOS() << "Type: " << i << " count " << count << LL_ENDL; - for (U32 j=0; j<count; j++) - { - LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)i,j); - if (wearable == NULL) - { - LL_INFOS() << " " << j << " NULL wearable" << LL_ENDL; - } - LL_INFOS() << " " << j << " Name " << wearable->getName() - << " description " << wearable->getDescription() << LL_ENDL; - - } - } + LL_INFOS() << "LLAgentWearablesDump" << LL_ENDL; + for (S32 i = 0; i < LLWearableType::WT_COUNT; i++) + { + U32 count = getWearableCount((LLWearableType::EType)i); + LL_INFOS() << "Type: " << i << " count " << count << LL_ENDL; + for (U32 j=0; j<count; j++) + { + LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)i,j); + if (wearable == NULL) + { + LL_INFOS() << " " << j << " NULL wearable" << LL_ENDL; + } + LL_INFOS() << " " << j << " Name " << wearable->getName() + << " description " << wearable->getDescription() << LL_ENDL; + + } + } } struct LLAgentDumper { - LLAgentDumper(std::string name): - mName(name) - { - LL_INFOS() << LL_ENDL; - LL_INFOS() << "LLAgentDumper " << mName << LL_ENDL; - gAgentWearables.dump(); - } - - ~LLAgentDumper() - { - LL_INFOS() << LL_ENDL; - LL_INFOS() << "~LLAgentDumper " << mName << LL_ENDL; - gAgentWearables.dump(); - } - - std::string mName; + LLAgentDumper(std::string name): + mName(name) + { + LL_INFOS() << LL_ENDL; + LL_INFOS() << "LLAgentDumper " << mName << LL_ENDL; + gAgentWearables.dump(); + } + + ~LLAgentDumper() + { + LL_INFOS() << LL_ENDL; + LL_INFOS() << "~LLAgentDumper " << mName << LL_ENDL; + gAgentWearables.dump(); + } + + std::string mName; }; LLAgentWearables::LLAgentWearables() : - LLWearableData(), - mWearablesLoaded(FALSE) -, mCOFChangeInProgress(false) + LLWearableData(), + mWearablesLoaded(FALSE) +, mCOFChangeInProgress(false) { } LLAgentWearables::~LLAgentWearables() { - cleanup(); + cleanup(); } void LLAgentWearables::cleanup() @@ -211,15 +211,15 @@ 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)); + // 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) { - llassert(avatar); - setAvatarAppearance(avatar); + llassert(avatar); + setAvatarAppearance(avatar); } /** @@ -233,300 +233,300 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar) * @param todo Bitmask of actions to take on completion. */ LLAgentWearables::AddWearableToAgentInventoryCallback::AddWearableToAgentInventoryCallback( - LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) : - mType(type), - mIndex(index), - mWearable(wearable), - mTodo(todo), - mCB(cb), - mDescription(description) + LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) : + mType(type), + mIndex(index), + mWearable(wearable), + mTodo(todo), + mCB(cb), + mDescription(description) { - LL_INFOS() << "constructor" << LL_ENDL; + LL_INFOS() << "constructor" << LL_ENDL; } void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& inv_item) { - if (inv_item.isNull()) - return; + if (inv_item.isNull()) + return; - gAgentWearables.addWearabletoAgentInventoryDone(mType, mIndex, inv_item, mWearable); + gAgentWearables.addWearabletoAgentInventoryDone(mType, mIndex, inv_item, mWearable); - /* - * Do this for every one in the loop - */ - if (mTodo & CALL_MAKENEWOUTFITDONE) - { - gAgentWearables.makeNewOutfitDone(mType, mIndex); - } - if (mTodo & CALL_WEARITEM) - { - LLAppearanceMgr::instance().addCOFItemLink(inv_item, - new LLUpdateAppearanceAndEditWearableOnDestroy(inv_item), mDescription); - editWearable(inv_item); - } + /* + * Do this for every one in the loop + */ + if (mTodo & CALL_MAKENEWOUTFITDONE) + { + gAgentWearables.makeNewOutfitDone(mType, mIndex); + } + if (mTodo & CALL_WEARITEM) + { + LLAppearanceMgr::instance().addCOFItemLink(inv_item, + new LLUpdateAppearanceAndEditWearableOnDestroy(inv_item), mDescription); + editWearable(inv_item); + } } void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type, - const U32 index, - const LLUUID& item_id, - LLViewerWearable* wearable) -{ - LL_INFOS() << "type " << type << " index " << index << " item " << item_id.asString() << LL_ENDL; - - if (item_id.isNull()) - return; - - LLUUID old_item_id = getWearableItemID(type,index); - - if (wearable) - { - wearable->setItemID(item_id); - - if (old_item_id.notNull()) - { - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - setWearable(type,index,wearable); - } - else - { - pushWearable(type,wearable); - } - } - - gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); - - LLViewerInventoryItem* item = gInventory.getItem(item_id); - if (item && wearable) - { - // We're changing the asset id, so we both need to set it - // locally via setAssetUUID() and via setTransactionID() which - // will be decoded on the server. JC - item->setAssetUUID(wearable->getAssetID()); - item->setTransactionID(wearable->getTransactionID()); - gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id); - item->updateServer(FALSE); - } - gInventory.notifyObservers(); + const U32 index, + const LLUUID& item_id, + LLViewerWearable* wearable) +{ + LL_INFOS() << "type " << type << " index " << index << " item " << item_id.asString() << LL_ENDL; + + if (item_id.isNull()) + return; + + LLUUID old_item_id = getWearableItemID(type,index); + + if (wearable) + { + wearable->setItemID(item_id); + + if (old_item_id.notNull()) + { + gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); + setWearable(type,index,wearable); + } + else + { + pushWearable(type,wearable); + } + } + + gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); + + LLViewerInventoryItem* item = gInventory.getItem(item_id); + if (item && wearable) + { + // We're changing the asset id, so we both need to set it + // locally via setAssetUUID() and via setTransactionID() which + // will be decoded on the server. JC + item->setAssetUUID(wearable->getAssetID()); + item->setTransactionID(wearable->getTransactionID()); + gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id); + item->updateServer(FALSE); + } + gInventory.notifyObservers(); } void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, - const std::string new_name) -{ - LLViewerWearable* old_wearable = getViewerWearable(type, index); - if(!old_wearable) return; - bool name_changed = !new_name.empty() && (new_name != old_wearable->getName()); - if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion()) - { - LLUUID old_item_id = old_wearable->getItemID(); - LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); - new_wearable->setItemID(old_item_id); // should this be in LLViewerWearable::copyDataFrom()? - setWearable(type,index,new_wearable); - - // old_wearable may still be referred to by other inventory items. Revert - // unsaved changes so other inventory items aren't affected by the changes - // that were just saved. - old_wearable->revertValues(); - - LLInventoryItem* item = gInventory.getItem(old_item_id); - if (item) - { - std::string item_name = item->getName(); - if (name_changed) - { - LL_INFOS() << "saveWearable changing name from " << item->getName() << " to " << new_name << LL_ENDL; - item_name = new_name; - } - // Update existing inventory item - LLPointer<LLViewerInventoryItem> template_item = - new LLViewerInventoryItem(item->getUUID(), - item->getParentUUID(), - item->getPermissions(), - new_wearable->getAssetID(), - new_wearable->getAssetType(), - item->getInventoryType(), - item_name, - item->getDescription(), - item->getSaleInfo(), - item->getFlags(), - item->getCreationDate()); - template_item->setTransactionID(new_wearable->getTransactionID()); - update_inventory_item(template_item, gAgentAvatarp->mEndCustomizeCallback); - } - else - { - // Add a new inventory item (shouldn't ever happen here) - U32 todo = AddWearableToAgentInventoryCallback::CALL_NONE; - LLPointer<LLInventoryCallback> cb = - new AddWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - type, - index, - new_wearable, - todo); - addWearableToAgentInventory(cb, new_wearable); - return; - } - - gAgentAvatarp->wearableUpdated(type); - } + const std::string new_name) +{ + LLViewerWearable* old_wearable = getViewerWearable(type, index); + if(!old_wearable) return; + bool name_changed = !new_name.empty() && (new_name != old_wearable->getName()); + if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion()) + { + LLUUID old_item_id = old_wearable->getItemID(); + LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); + new_wearable->setItemID(old_item_id); // should this be in LLViewerWearable::copyDataFrom()? + setWearable(type,index,new_wearable); + + // old_wearable may still be referred to by other inventory items. Revert + // unsaved changes so other inventory items aren't affected by the changes + // that were just saved. + old_wearable->revertValues(); + + LLInventoryItem* item = gInventory.getItem(old_item_id); + if (item) + { + std::string item_name = item->getName(); + if (name_changed) + { + LL_INFOS() << "saveWearable changing name from " << item->getName() << " to " << new_name << LL_ENDL; + item_name = new_name; + } + // Update existing inventory item + LLPointer<LLViewerInventoryItem> template_item = + new LLViewerInventoryItem(item->getUUID(), + item->getParentUUID(), + item->getPermissions(), + new_wearable->getAssetID(), + new_wearable->getAssetType(), + item->getInventoryType(), + item_name, + item->getDescription(), + item->getSaleInfo(), + item->getFlags(), + item->getCreationDate()); + template_item->setTransactionID(new_wearable->getTransactionID()); + update_inventory_item(template_item, gAgentAvatarp->mEndCustomizeCallback); + } + else + { + // Add a new inventory item (shouldn't ever happen here) + U32 todo = AddWearableToAgentInventoryCallback::CALL_NONE; + LLPointer<LLInventoryCallback> cb = + new AddWearableToAgentInventoryCallback( + LLPointer<LLRefCount>(NULL), + type, + index, + new_wearable, + todo); + addWearableToAgentInventory(cb, new_wearable); + return; + } + + gAgentAvatarp->wearableUpdated(type); + } } void LLAgentWearables::saveWearableAs(const LLWearableType::EType type, - const U32 index, - const std::string& new_name, - const std::string& description, - BOOL save_in_lost_and_found) -{ - if (!isWearableCopyable(type, index)) - { - LL_WARNS() << "LLAgent::saveWearableAs() not copyable." << LL_ENDL; - return; - } - LLViewerWearable* old_wearable = getViewerWearable(type, index); - if (!old_wearable) - { - LL_WARNS() << "LLAgent::saveWearableAs() no old wearable." << LL_ENDL; - return; - } - - LLInventoryItem* item = gInventory.getItem(getWearableItemID(type,index)); - if (!item) - { - LL_WARNS() << "LLAgent::saveWearableAs() no inventory item." << LL_ENDL; - return; - } - std::string trunc_name(new_name); - LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); - LLViewerWearable* new_wearable = LLWearableList::instance().createCopy( - old_wearable, - trunc_name); - - LLPointer<LLInventoryCallback> cb = - new AddWearableToAgentInventoryCallback( - LLPointer<LLRefCount>(NULL), - type, - index, - new_wearable, - AddWearableToAgentInventoryCallback::CALL_WEARITEM, - description - ); - LLUUID category_id; - if (save_in_lost_and_found) - { - category_id = gInventory.findCategoryUUIDForType( - LLFolderType::FT_LOST_AND_FOUND); - } - else - { - // put in same folder as original - category_id = item->getParentUUID(); - } - - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - category_id, - new_name, - cb); - - // old_wearable may still be referred to by other inventory items. Revert - // unsaved changes so other inventory items aren't affected by the changes - // that were just saved. - old_wearable->revertValuesWithoutUpdate(); + const U32 index, + const std::string& new_name, + const std::string& description, + BOOL save_in_lost_and_found) +{ + if (!isWearableCopyable(type, index)) + { + LL_WARNS() << "LLAgent::saveWearableAs() not copyable." << LL_ENDL; + return; + } + LLViewerWearable* old_wearable = getViewerWearable(type, index); + if (!old_wearable) + { + LL_WARNS() << "LLAgent::saveWearableAs() no old wearable." << LL_ENDL; + return; + } + + LLInventoryItem* item = gInventory.getItem(getWearableItemID(type,index)); + if (!item) + { + LL_WARNS() << "LLAgent::saveWearableAs() no inventory item." << LL_ENDL; + return; + } + std::string trunc_name(new_name); + LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN); + LLViewerWearable* new_wearable = LLWearableList::instance().createCopy( + old_wearable, + trunc_name); + + LLPointer<LLInventoryCallback> cb = + new AddWearableToAgentInventoryCallback( + LLPointer<LLRefCount>(NULL), + type, + index, + new_wearable, + AddWearableToAgentInventoryCallback::CALL_WEARITEM, + description + ); + LLUUID category_id; + if (save_in_lost_and_found) + { + category_id = gInventory.findCategoryUUIDForType( + LLFolderType::FT_LOST_AND_FOUND); + } + else + { + // put in same folder as original + category_id = item->getParentUUID(); + } + + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + category_id, + new_name, + cb); + + // old_wearable may still be referred to by other inventory items. Revert + // unsaved changes so other inventory items aren't affected by the changes + // that were just saved. + old_wearable->revertValuesWithoutUpdate(); } void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index) { - LLViewerWearable* wearable = getViewerWearable(type, index); - llassert(wearable); - if (wearable) - { - wearable->revertValues(); - } + LLViewerWearable* wearable = getViewerWearable(type, index); + llassert(wearable); + if (wearable) + { + wearable->revertValues(); + } } void LLAgentWearables::saveAllWearables() { - //if (!gInventory.isLoaded()) - //{ - // return; - //} + //if (!gInventory.isLoaded()) + //{ + // return; + //} - for (S32 i=0; i < LLWearableType::WT_COUNT; i++) - { - for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) - saveWearable((LLWearableType::EType)i, j); - } + for (S32 i=0; i < LLWearableType::WT_COUNT; i++) + { + for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) + saveWearable((LLWearableType::EType)i, j); + } } // 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 (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) - { - LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j); - if (curr_item_id == item_id) - { - LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j); - llassert(old_wearable); - if (!old_wearable) continue; - - std::string old_name = old_wearable->getName(); - old_wearable->setName(new_name); - LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); - new_wearable->setItemID(item_id); - LLInventoryItem* item = gInventory.getItem(item_id); - if (item) - { - new_wearable->setPermissions(item->getPermissions()); - } - old_wearable->setName(old_name); - - setWearable((LLWearableType::EType)i,j,new_wearable); - break; - } - } - } + for (S32 i=0; i < LLWearableType::WT_COUNT; i++) + { + for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) + { + LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j); + if (curr_item_id == item_id) + { + LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j); + llassert(old_wearable); + if (!old_wearable) continue; + + std::string old_name = old_wearable->getName(); + old_wearable->setName(new_name); + LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable); + new_wearable->setItemID(item_id); + LLInventoryItem* item = gInventory.getItem(item_id); + if (item) + { + new_wearable->setPermissions(item->getPermissions()); + } + old_wearable->setName(old_name); + + setWearable((LLWearableType::EType)i,j,new_wearable); + break; + } + } + } } BOOL LLAgentWearables::isWearableModifiable(LLWearableType::EType type, U32 index) const { - LLUUID item_id = getWearableItemID(type, index); - return item_id.notNull() ? isWearableModifiable(item_id) : FALSE; + 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()) - { - LLInventoryItem* item = gInventory.getItem(linked_id); - if (item && item->getPermissions().allowModifyBy(gAgent.getID(), - gAgent.getGroupID())) - { - return TRUE; - } - } - return FALSE; + const LLUUID& linked_id = gInventory.getLinkedItemID(item_id); + if (linked_id.notNull()) + { + LLInventoryItem* item = gInventory.getItem(linked_id); + if (item && item->getPermissions().allowModifyBy(gAgent.getID(), + gAgent.getGroupID())) + { + return TRUE; + } + } + return FALSE; } BOOL LLAgentWearables::isWearableCopyable(LLWearableType::EType type, U32 index) const { - LLUUID item_id = getWearableItemID(type, index); - if (!item_id.isNull()) - { - LLInventoryItem* item = gInventory.getItem(item_id); - if (item && item->getPermissions().allowCopyBy(gAgent.getID(), - gAgent.getGroupID())) - { - return TRUE; - } - } - return FALSE; + LLUUID item_id = getWearableItemID(type, index); + if (!item_id.isNull()) + { + LLInventoryItem* item = gInventory.getItem(item_id); + if (item && item->getPermissions().allowCopyBy(gAgent.getID(), + gAgent.getGroupID())) + { + return TRUE; + } + } + return FALSE; } /* @@ -547,270 +547,270 @@ BOOL LLAgentWearables::isWearableCopyable(LLWearableType::EType type, U32 index) LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::EType type, U32 index) { - LLUUID item_id = getWearableItemID(type,index); - LLInventoryItem* item = NULL; - if (item_id.notNull()) - { - item = gInventory.getItem(item_id); - } - return item; + LLUUID item_id = getWearableItemID(type,index); + LLInventoryItem* item = NULL; + if (item_id.notNull()) + { + item = gInventory.getItem(item_id); + } + return item; } const LLViewerWearable* 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 (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) - { - const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); - if (curr_wearable && (curr_wearable->getItemID() == base_item_id)) - { - return curr_wearable; - } - } - } - return NULL; + 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++) + { + const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); + if (curr_wearable && (curr_wearable->getItemID() == base_item_id)) + { + return curr_wearable; + } + } + } + return NULL; } LLViewerWearable* 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++) - { - LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); - if (curr_wearable && (curr_wearable->getItemID() == base_item_id)) - { - return curr_wearable; - } - } - } - return NULL; -} - -LLViewerWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) -{ - for (S32 i=0; i < LLWearableType::WT_COUNT; i++) - { - for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) - { - LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); - if (curr_wearable && (curr_wearable->getAssetID() == asset_id)) - { - return curr_wearable; - } - } - } - return NULL; + 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++) + { + LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); + if (curr_wearable && (curr_wearable->getItemID() == base_item_id)) + { + return curr_wearable; + } + } + } + return NULL; +} + +LLViewerWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) +{ + for (S32 i=0; i < LLWearableType::WT_COUNT; i++) + { + for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++) + { + LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j); + if (curr_wearable && (curr_wearable->getAssetID() == asset_id)) + { + return curr_wearable; + } + } + } + return NULL; } LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) { - return dynamic_cast<LLViewerWearable*> (getWearable(type, index)); + return dynamic_cast<LLViewerWearable*> (getWearable(type, index)); } const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const { - return dynamic_cast<const LLViewerWearable*> (getWearable(type, index)); + return dynamic_cast<const LLViewerWearable*> (getWearable(type, index)); } // static BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type) { - return (gAgentWearables.getWearableCount(type) > 0); + return (gAgentWearables.getWearableCount(type) > 0); } // virtual void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed) { - if (isAgentAvatarValid()) - { - gAgentAvatarp->wearableUpdated(wearable->getType()); - } - - LLWearableData::wearableUpdated(wearable, removed); - - if (!removed) - { - LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable); - viewer_wearable->refreshName(); - - // 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 ) - { - U32 index; - if (getWearableIndex(wearable,index)) - { - LL_INFOS() << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << LL_ENDL; - wearable->setDefinitionVersion(22); - saveWearable(wearable->getType(),index); - } - } - - checkWearableAgainstInventory(viewer_wearable); - } + if (isAgentAvatarValid()) + { + gAgentAvatarp->wearableUpdated(wearable->getType()); + } + + LLWearableData::wearableUpdated(wearable, removed); + + if (!removed) + { + LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable); + viewer_wearable->refreshName(); + + // 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 ) + { + U32 index; + if (getWearableIndex(wearable,index)) + { + LL_INFOS() << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << LL_ENDL; + wearable->setDefinitionVersion(22); + saveWearable(wearable->getType(),index); + } + } + + checkWearableAgainstInventory(viewer_wearable); + } } const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const { - const LLViewerWearable *wearable = getViewerWearable(type,index); - if (wearable) - return wearable->getItemID(); - else - return LLUUID(); + const LLViewerWearable *wearable = getViewerWearable(type,index); + if (wearable) + return wearable->getItemID(); + else + return LLUUID(); } const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const { - const LLViewerWearable *wearable = getViewerWearable(type,index); - if (wearable) - return wearable->getAssetID(); - else - return LLUUID(); + const LLViewerWearable *wearable = getViewerWearable(type,index); + if (wearable) + return wearable->getAssetID(); + else + return LLUUID(); } BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id) const { - return getWearableFromItemID(item_id) != NULL; + return getWearableFromItemID(item_id) != NULL; } void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index) { - LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index); - if (!wearable) - { - LL_ERRS() << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << LL_ENDL; - return; - } - LLLocalTextureObject lto; - wearable->setLocalTextureObject(texture_type, lto); + LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index); + if (!wearable) + { + LL_ERRS() << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << LL_ENDL; + return; + } + LLLocalTextureObject lto; + wearable->setLocalTextureObject(texture_type, lto); } class OnWearableItemCreatedCB: public LLInventoryCallback { public: - OnWearableItemCreatedCB(): - mWearablesAwaitingItems(LLWearableType::WT_COUNT,NULL) - { - LL_INFOS() << "created callback" << LL_ENDL; - } - /* virtual */ void fire(const LLUUID& inv_item) - { - LL_INFOS() << "One item created " << inv_item.asString() << LL_ENDL; - LLConstPointer<LLInventoryObject> item = gInventory.getItem(inv_item); - mItemsToLink.push_back(item); - updatePendingWearable(inv_item); - } - ~OnWearableItemCreatedCB() - { - LL_INFOS() << "All items created" << LL_ENDL; - LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; - link_inventory_array(LLAppearanceMgr::instance().getCOF(), - mItemsToLink, - link_waiter); - } - void addPendingWearable(LLViewerWearable *wearable) - { - if (!wearable) - { - LL_WARNS() << "no wearable" << LL_ENDL; - return; - } - LLWearableType::EType type = wearable->getType(); - if (type<LLWearableType::WT_COUNT) - { - mWearablesAwaitingItems[type] = wearable; - } - else - { - LL_WARNS() << "invalid type " << type << LL_ENDL; - } - } - void updatePendingWearable(const LLUUID& inv_item) - { - LLViewerInventoryItem *item = gInventory.getItem(inv_item); - if (!item) - { - LL_WARNS() << "no item found" << LL_ENDL; - return; - } - if (!item->isWearableType()) - { - LL_WARNS() << "non-wearable item found" << LL_ENDL; - return; - } - if (item && item->isWearableType()) - { - LLWearableType::EType type = item->getWearableType(); - if (type < LLWearableType::WT_COUNT) - { - LLViewerWearable *wearable = mWearablesAwaitingItems[type]; - if (wearable) - wearable->setItemID(inv_item); - } - else - { - LL_WARNS() << "invalid wearable type " << type << LL_ENDL; - } - } - } - + OnWearableItemCreatedCB(): + mWearablesAwaitingItems(LLWearableType::WT_COUNT,NULL) + { + LL_INFOS() << "created callback" << LL_ENDL; + } + /* virtual */ void fire(const LLUUID& inv_item) + { + LL_INFOS() << "One item created " << inv_item.asString() << LL_ENDL; + LLConstPointer<LLInventoryObject> item = gInventory.getItem(inv_item); + mItemsToLink.push_back(item); + updatePendingWearable(inv_item); + } + ~OnWearableItemCreatedCB() + { + LL_INFOS() << "All items created" << LL_ENDL; + LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; + link_inventory_array(LLAppearanceMgr::instance().getCOF(), + mItemsToLink, + link_waiter); + } + void addPendingWearable(LLViewerWearable *wearable) + { + if (!wearable) + { + LL_WARNS() << "no wearable" << LL_ENDL; + return; + } + LLWearableType::EType type = wearable->getType(); + if (type<LLWearableType::WT_COUNT) + { + mWearablesAwaitingItems[type] = wearable; + } + else + { + LL_WARNS() << "invalid type " << type << LL_ENDL; + } + } + void updatePendingWearable(const LLUUID& inv_item) + { + LLViewerInventoryItem *item = gInventory.getItem(inv_item); + if (!item) + { + LL_WARNS() << "no item found" << LL_ENDL; + return; + } + if (!item->isWearableType()) + { + LL_WARNS() << "non-wearable item found" << LL_ENDL; + return; + } + if (item && item->isWearableType()) + { + LLWearableType::EType type = item->getWearableType(); + if (type < LLWearableType::WT_COUNT) + { + LLViewerWearable *wearable = mWearablesAwaitingItems[type]; + if (wearable) + wearable->setItemID(inv_item); + } + else + { + LL_WARNS() << "invalid wearable type " << type << LL_ENDL; + } + } + } + private: - LLInventoryObject::const_object_list_t mItemsToLink; - std::vector<LLViewerWearable*> mWearablesAwaitingItems; + LLInventoryObject::const_object_list_t mItemsToLink; + std::vector<LLViewerWearable*> mWearablesAwaitingItems; }; void LLAgentWearables::createStandardWearables() { - LL_WARNS() << "Creating standard wearables" << LL_ENDL; - - if (!isAgentAvatarValid()) return; - - const BOOL create[LLWearableType::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 - }; - - LLPointer<LLInventoryCallback> cb = new OnWearableItemCreatedCB; - for (S32 i=0; i < LLWearableType::WT_COUNT; i++) - { - if (create[i]) - { - llassert(getWearableCount((LLWearableType::EType)i) == 0); - LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp); - ((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable); - // no need to update here... - LLUUID category_id = LLUUID::null; + LL_WARNS() << "Creating standard wearables" << LL_ENDL; + + if (!isAgentAvatarValid()) return; + + const BOOL create[LLWearableType::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 + }; + + LLPointer<LLInventoryCallback> cb = new OnWearableItemCreatedCB; + for (S32 i=0; i < LLWearableType::WT_COUNT; i++) + { + if (create[i]) + { + llassert(getWearableCount((LLWearableType::EType)i) == 0); + LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp); + ((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable); + // no need to update here... + LLUUID category_id = LLUUID::null; create_inventory_wearable(gAgent.getID(), - gAgent.getSessionID(), - category_id, - wearable->getTransactionID(), - wearable->getName(), - wearable->getDescription(), - wearable->getAssetType(), - wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), - cb); - } - } + gAgent.getSessionID(), + category_id, + wearable->getTransactionID(), + wearable->getName(), + wearable->getDescription(), + wearable->getAssetType(), + wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + cb); + } + } } // We no longer need this message in the current viewer, but send @@ -818,622 +818,622 @@ void LLAgentWearables::createStandardWearables() // remove this function once the SH-3455 changesets are universally deployed. void LLAgentWearables::sendDummyAgentWearablesUpdate() { - LL_DEBUGS("Avatar") << "sendAgentWearablesUpdate()" << LL_ENDL; + LL_DEBUGS("Avatar") << "sendAgentWearablesUpdate()" << LL_ENDL; + + // Send the AgentIsNowWearing + gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing); - // Send the AgentIsNowWearing - gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing); - - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - // Send 4 standardized nonsense item ids (same as returned by the modified sim, not that it especially matters). - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(1)); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("db5a4e5f-9da3-44c8-992d-1181c5795498")); + // Send 4 standardized nonsense item ids (same as returned by the modified sim, not that it especially matters). + gMessageSystem->nextBlockFast(_PREHASH_WearableData); + gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(1)); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("db5a4e5f-9da3-44c8-992d-1181c5795498")); - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(2)); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("6969c7cc-f72f-4a76-a19b-c293cce8ce4f")); + gMessageSystem->nextBlockFast(_PREHASH_WearableData); + gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(2)); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("6969c7cc-f72f-4a76-a19b-c293cce8ce4f")); - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(3)); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("7999702b-b291-48f9-8903-c91dfb828408")); + gMessageSystem->nextBlockFast(_PREHASH_WearableData); + gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(3)); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("7999702b-b291-48f9-8903-c91dfb828408")); - gMessageSystem->nextBlockFast(_PREHASH_WearableData); - gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(4)); - gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("566cb59e-ef60-41d7-bfa6-e0f293fbea40")); + gMessageSystem->nextBlockFast(_PREHASH_WearableData); + gMessageSystem->addU8Fast(_PREHASH_WearableType, U8(4)); + gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID("566cb59e-ef60-41d7-bfa6-e0f293fbea40")); - gAgent.sendReliableMessage(); + gAgent.sendReliableMessage(); } void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index) { - LLUUID first_item_id = getWearableItemID((LLWearableType::EType)type, index); - // Open the inventory and select the first item we added. - if (first_item_id.notNull()) - { - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); - if (active_panel) - { - active_panel->setSelection(first_item_id, TAKE_FOCUS_NO); - } - } + LLUUID first_item_id = getWearableItemID((LLWearableType::EType)type, index); + // Open the inventory and select the first item we added. + if (first_item_id.notNull()) + { + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(); + if (active_panel) + { + active_panel->setSelection(first_item_id, TAKE_FOCUS_NO); + } + } } void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb, - LLViewerWearable* wearable, - const LLUUID& category_id, - BOOL notify) + LLViewerWearable* wearable, + const LLUUID& category_id, + BOOL notify) { create_inventory_wearable(gAgent.getID(), - gAgent.getSessionID(), - category_id, - wearable->getTransactionID(), - wearable->getName(), - wearable->getDescription(), - wearable->getAssetType(), - wearable->getType(), - wearable->getPermissions().getMaskNextOwner(), - cb); + gAgent.getSessionID(), + category_id, + wearable->getTransactionID(), + wearable->getName(), + wearable->getDescription(), + wearable->getAssetType(), + wearable->getType(), + wearable->getPermissions().getMaskNextOwner(), + cb); } void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_remove_all, U32 index) { - if (getWearableCount(type) == 0) - { - // no wearables to remove - return; - } - - if (do_remove_all) - { - removeWearableFinal(type, do_remove_all, index); - } - else - { - LLViewerWearable* old_wearable = getViewerWearable(type,index); - - if (old_wearable) - { - if (old_wearable->isDirty()) - { - LLSD payload; - payload["wearable_type"] = (S32)type; - payload["wearable_index"] = (S32)index; - // Bring up view-modal dialog: Save changes? Yes, No, Cancel - LLNotificationsUtil::add("WearableSave", LLSD(), payload, &LLAgentWearables::onRemoveWearableDialog); - return; - } - else - { - removeWearableFinal(type, do_remove_all, index); - } - } - } -} - - -// static + if (getWearableCount(type) == 0) + { + // no wearables to remove + return; + } + + if (do_remove_all) + { + removeWearableFinal(type, do_remove_all, index); + } + else + { + LLViewerWearable* old_wearable = getViewerWearable(type,index); + + if (old_wearable) + { + if (old_wearable->isDirty()) + { + LLSD payload; + payload["wearable_type"] = (S32)type; + payload["wearable_index"] = (S32)index; + // Bring up view-modal dialog: Save changes? Yes, No, Cancel + LLNotificationsUtil::add("WearableSave", LLSD(), payload, &LLAgentWearables::onRemoveWearableDialog); + return; + } + else + { + removeWearableFinal(type, do_remove_all, index); + } + } + } +} + + +// static 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(); - S32 index = (S32)notification["payload"]["wearable_index"].asInteger(); - switch(option) - { - case 0: // "Save" - gAgentWearables.saveWearable(type, index); - gAgentWearables.removeWearableFinal(type, false, index); - break; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLWearableType::EType type = (LLWearableType::EType)notification["payload"]["wearable_type"].asInteger(); + S32 index = (S32)notification["payload"]["wearable_index"].asInteger(); + switch(option) + { + case 0: // "Save" + gAgentWearables.saveWearable(type, index); + gAgentWearables.removeWearableFinal(type, false, index); + break; - case 1: // "Don't Save" - gAgentWearables.removeWearableFinal(type, false, index); - break; + case 1: // "Don't Save" + gAgentWearables.removeWearableFinal(type, false, index); + break; - case 2: // "Cancel" - break; + case 2: // "Cancel" + break; - default: - llassert(0); - break; - } - return false; + default: + llassert(0); + break; + } + return false; } // Called by removeWearable() and onRemoveWearableDialog() to actually do the removal. void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, bool do_remove_all, U32 index) { - //LLAgentDumper dumper("removeWearable"); - if (do_remove_all) - { - S32 max_entry = getWearableCount(type)-1; - for (S32 i=max_entry; i>=0; i--) - { - LLViewerWearable* old_wearable = getViewerWearable(type,i); - if (old_wearable) - { - eraseWearable(old_wearable); - old_wearable->removeFromAvatar(); - } - } - clearWearableType(type); - } - else - { - LLViewerWearable* old_wearable = getViewerWearable(type, index); - - if (old_wearable) - { - eraseWearable(old_wearable); - old_wearable->removeFromAvatar(); - } - } - - gInventory.notifyObservers(); + //LLAgentDumper dumper("removeWearable"); + if (do_remove_all) + { + S32 max_entry = getWearableCount(type)-1; + for (S32 i=max_entry; i>=0; i--) + { + LLViewerWearable* old_wearable = getViewerWearable(type,i); + if (old_wearable) + { + eraseWearable(old_wearable); + old_wearable->removeFromAvatar(); + } + } + clearWearableType(type); + } + else + { + LLViewerWearable* old_wearable = getViewerWearable(type, index); + + if (old_wearable) + { + eraseWearable(old_wearable); + old_wearable->removeFromAvatar(); + } + } + + gInventory.notifyObservers(); } // Assumes existing wearables are not dirty. void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items, - const std::vector< LLViewerWearable* >& wearables) -{ - LL_INFOS() << "setWearableOutfit() start" << LL_ENDL; - - S32 count = wearables.size(); - llassert(items.size() == count); - - // Check for whether outfit already matches the one requested - S32 matched = 0, mismatched = 0; - const S32 arr_size = LLWearableType::WT_COUNT; - S32 type_counts[arr_size]; - BOOL update_inventory = FALSE; - std::fill(type_counts,type_counts+arr_size,0); - for (S32 i = 0; i < count; i++) - { - LLViewerWearable* new_wearable = wearables[i]; - LLPointer<LLInventoryItem> new_item = items[i]; - - const LLWearableType::EType type = new_wearable->getType(); - if (type < 0 || type>=LLWearableType::WT_COUNT) - { - LL_WARNS() << "invalid type " << type << LL_ENDL; - mismatched++; - continue; - } - S32 index = type_counts[type]; - type_counts[type]++; - - LLViewerWearable *curr_wearable = dynamic_cast<LLViewerWearable*>(getWearable(type,index)); - if (!new_wearable || !curr_wearable || - new_wearable->getAssetID() != curr_wearable->getAssetID()) - { - LL_DEBUGS("Avatar") << "mismatch, type " << type << " index " << index - << " names " << (curr_wearable ? curr_wearable->getName() : "NONE") << "," - << " names " << (new_wearable ? new_wearable->getName() : "NONE") << LL_ENDL; - mismatched++; - continue; - } - - // Update only inventory in this case - ordering of wearables with the same asset id has no effect. - // Updating wearables in this case causes the two-alphas error in MAINT-4158. - // We should actually disallow wearing two wearables with the same asset id. - if (curr_wearable->getName() != new_item->getName() || - curr_wearable->getItemID() != new_item->getUUID()) - { - LL_DEBUGS("Avatar") << "mismatch on name or inventory id, names " - << curr_wearable->getName() << " vs " << new_item->getName() - << " item ids " << curr_wearable->getItemID() << " vs " << new_item->getUUID() - << LL_ENDL; - update_inventory = TRUE; - continue; - } - // If we got here, everything matches. - matched++; - } - LL_DEBUGS("Avatar") << "matched " << matched << " mismatched " << mismatched << LL_ENDL; - for (S32 j=0; j<LLWearableType::WT_COUNT; j++) - { - LLWearableType::EType type = (LLWearableType::EType) j; - if (getWearableCount(type) != type_counts[j]) - { - LL_DEBUGS("Avatar") << "count mismatch for type " << j << " current " << getWearableCount(j) << " requested " << type_counts[j] << LL_ENDL; - mismatched++; - } - } - if (mismatched == 0 && !update_inventory) - { - LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL; - notifyLoadingFinished(); - return; - } - - // updating inventory + const std::vector< LLViewerWearable* >& wearables) +{ + LL_INFOS() << "setWearableOutfit() start" << LL_ENDL; + + S32 count = wearables.size(); + llassert(items.size() == count); + + // Check for whether outfit already matches the one requested + S32 matched = 0, mismatched = 0; + const S32 arr_size = LLWearableType::WT_COUNT; + S32 type_counts[arr_size]; + BOOL update_inventory = FALSE; + std::fill(type_counts,type_counts+arr_size,0); + for (S32 i = 0; i < count; i++) + { + LLViewerWearable* new_wearable = wearables[i]; + LLPointer<LLInventoryItem> new_item = items[i]; + + const LLWearableType::EType type = new_wearable->getType(); + if (type < 0 || type>=LLWearableType::WT_COUNT) + { + LL_WARNS() << "invalid type " << type << LL_ENDL; + mismatched++; + continue; + } + S32 index = type_counts[type]; + type_counts[type]++; + + LLViewerWearable *curr_wearable = dynamic_cast<LLViewerWearable*>(getWearable(type,index)); + if (!new_wearable || !curr_wearable || + new_wearable->getAssetID() != curr_wearable->getAssetID()) + { + LL_DEBUGS("Avatar") << "mismatch, type " << type << " index " << index + << " names " << (curr_wearable ? curr_wearable->getName() : "NONE") << "," + << " names " << (new_wearable ? new_wearable->getName() : "NONE") << LL_ENDL; + mismatched++; + continue; + } + + // Update only inventory in this case - ordering of wearables with the same asset id has no effect. + // Updating wearables in this case causes the two-alphas error in MAINT-4158. + // We should actually disallow wearing two wearables with the same asset id. + if (curr_wearable->getName() != new_item->getName() || + curr_wearable->getItemID() != new_item->getUUID()) + { + LL_DEBUGS("Avatar") << "mismatch on name or inventory id, names " + << curr_wearable->getName() << " vs " << new_item->getName() + << " item ids " << curr_wearable->getItemID() << " vs " << new_item->getUUID() + << LL_ENDL; + update_inventory = TRUE; + continue; + } + // If we got here, everything matches. + matched++; + } + LL_DEBUGS("Avatar") << "matched " << matched << " mismatched " << mismatched << LL_ENDL; + for (S32 j=0; j<LLWearableType::WT_COUNT; j++) + { + LLWearableType::EType type = (LLWearableType::EType) j; + if (getWearableCount(type) != type_counts[j]) + { + LL_DEBUGS("Avatar") << "count mismatch for type " << j << " current " << getWearableCount(j) << " requested " << type_counts[j] << LL_ENDL; + mismatched++; + } + } + if (mismatched == 0 && !update_inventory) + { + LL_DEBUGS("Avatar") << "no changes, bailing out" << LL_ENDL; + notifyLoadingFinished(); + return; + } + + // updating inventory LLWearableType* wearable_type_inst = LLWearableType::getInstance(); - // TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later - // 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 j = 0; j < (S32)LLWearableType::WT_COUNT; j++) - { - if (wearable_type_inst->getAssetType((LLWearableType::EType)j) == LLAssetType::AT_CLOTHING) - { - removeWearable((LLWearableType::EType)j, true, 0); - } - } - - for (S32 i = 0; i < count; i++) - { - LLViewerWearable* new_wearable = wearables[i]; - LLPointer<LLInventoryItem> new_item = items[i]; - - llassert(new_wearable); - if (new_wearable) - { - const LLWearableType::EType type = new_wearable->getType(); - - LLUUID old_wearable_id = new_wearable->getItemID(); - new_wearable->setName(new_item->getName()); - new_wearable->setItemID(new_item->getUUID()); - - if (wearable_type_inst->getAssetType(type) == LLAssetType::AT_BODYPART) - { - // exactly one wearable per body part - setWearable(type,0,new_wearable); - if (old_wearable_id.notNull()) - { - // we changed id before setting wearable, update old item manually - // to complete the swap. - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_wearable_id); - } - } - else - { - pushWearable(type,new_wearable); - } - - const BOOL removed = FALSE; - wearableUpdated(new_wearable, removed); - } - } - - gInventory.notifyObservers(); - - if (mismatched == 0) - { - LL_DEBUGS("Avatar") << "inventory updated, wearable assets not changed, bailing out" << LL_ENDL; - notifyLoadingFinished(); - return; - } - - // updating agent avatar - - if (isAgentAvatarValid()) - { - gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); - - // If we have not yet declouded, we may want to use - // baked texture UUIDs sent from the first objectUpdate message - // don't overwrite these. If we have already declouded, we've saved - // these ids as the last known good textures and can invalidate without - // re-clouding. - if (!gAgentAvatarp->getIsCloud()) - { - gAgentAvatarp->invalidateAll(); - } - } - - // Start rendering & update the server - mWearablesLoaded = TRUE; - - notifyLoadingFinished(); - - // Copy wearable params to avatar. - gAgentAvatarp->writeWearablesToAvatar(); - - // Then update the avatar based on the copied params. - gAgentAvatarp->updateVisualParams(); - - gAgentAvatarp->dumpAvatarTEs("setWearableOutfit"); - - LL_DEBUGS("Avatar") << "setWearableOutfit() end" << LL_ENDL; + // TODO: Removed check for ensuring that teens don't remove undershirt and underwear. Handle later + // 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 j = 0; j < (S32)LLWearableType::WT_COUNT; j++) + { + if (wearable_type_inst->getAssetType((LLWearableType::EType)j) == LLAssetType::AT_CLOTHING) + { + removeWearable((LLWearableType::EType)j, true, 0); + } + } + + for (S32 i = 0; i < count; i++) + { + LLViewerWearable* new_wearable = wearables[i]; + LLPointer<LLInventoryItem> new_item = items[i]; + + llassert(new_wearable); + if (new_wearable) + { + const LLWearableType::EType type = new_wearable->getType(); + + LLUUID old_wearable_id = new_wearable->getItemID(); + new_wearable->setName(new_item->getName()); + new_wearable->setItemID(new_item->getUUID()); + + if (wearable_type_inst->getAssetType(type) == LLAssetType::AT_BODYPART) + { + // exactly one wearable per body part + setWearable(type,0,new_wearable); + if (old_wearable_id.notNull()) + { + // we changed id before setting wearable, update old item manually + // to complete the swap. + gInventory.addChangedMask(LLInventoryObserver::LABEL, old_wearable_id); + } + } + else + { + pushWearable(type,new_wearable); + } + + const BOOL removed = FALSE; + wearableUpdated(new_wearable, removed); + } + } + + gInventory.notifyObservers(); + + if (mismatched == 0) + { + LL_DEBUGS("Avatar") << "inventory updated, wearable assets not changed, bailing out" << LL_ENDL; + notifyLoadingFinished(); + return; + } + + // updating agent avatar + + if (isAgentAvatarValid()) + { + gAgentAvatarp->setCompositeUpdatesEnabled(TRUE); + + // If we have not yet declouded, we may want to use + // baked texture UUIDs sent from the first objectUpdate message + // don't overwrite these. If we have already declouded, we've saved + // these ids as the last known good textures and can invalidate without + // re-clouding. + if (!gAgentAvatarp->getIsCloud()) + { + gAgentAvatarp->invalidateAll(); + } + } + + // Start rendering & update the server + mWearablesLoaded = TRUE; + + notifyLoadingFinished(); + + // Copy wearable params to avatar. + gAgentAvatarp->writeWearablesToAvatar(); + + // Then update the avatar based on the copied params. + gAgentAvatarp->updateVisualParams(); + + gAgentAvatarp->dumpAvatarTEs("setWearableOutfit"); + + LL_DEBUGS("Avatar") << "setWearableOutfit() end" << LL_ENDL; } // User has picked "wear on avatar" from a menu. void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) { - //LLAgentDumper dumper("setWearableItem"); - if (isWearingItem(new_item->getUUID())) - { - LL_WARNS() << "wearable " << new_item->getUUID() << " is already worn" << LL_ENDL; - return; - } - - const LLWearableType::EType type = new_wearable->getType(); - - if (!do_append) - { - // Remove old wearable, if any - // MULTI_WEARABLE: hardwired to 0 - LLViewerWearable* old_wearable = getViewerWearable(type,0); - if (old_wearable) - { - const LLUUID& old_item_id = old_wearable->getItemID(); - if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && - (old_item_id == new_item->getUUID())) - { - LL_DEBUGS() << "No change to wearable asset and item: " << LLWearableType::getInstance()->getTypeName(type) << LL_ENDL; - return; - } - - if (old_wearable->isDirty()) - { - // Bring up modal dialog: Save changes? Yes, No, Cancel - LLSD payload; - payload["item_id"] = new_item->getUUID(); - LLNotificationsUtil::add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable)); - return; - } - } - } - - setWearableFinal(new_item, new_wearable, do_append); -} - -// static + //LLAgentDumper dumper("setWearableItem"); + if (isWearingItem(new_item->getUUID())) + { + LL_WARNS() << "wearable " << new_item->getUUID() << " is already worn" << LL_ENDL; + return; + } + + const LLWearableType::EType type = new_wearable->getType(); + + if (!do_append) + { + // Remove old wearable, if any + // MULTI_WEARABLE: hardwired to 0 + LLViewerWearable* old_wearable = getViewerWearable(type,0); + if (old_wearable) + { + const LLUUID& old_item_id = old_wearable->getItemID(); + if ((old_wearable->getAssetID() == new_wearable->getAssetID()) && + (old_item_id == new_item->getUUID())) + { + LL_DEBUGS() << "No change to wearable asset and item: " << LLWearableType::getInstance()->getTypeName(type) << LL_ENDL; + return; + } + + if (old_wearable->isDirty()) + { + // Bring up modal dialog: Save changes? Yes, No, Cancel + LLSD payload; + payload["item_id"] = new_item->getUUID(); + LLNotificationsUtil::add("WearableSave", LLSD(), payload, boost::bind(onSetWearableDialog, _1, _2, new_wearable)); + return; + } + } + } + + setWearableFinal(new_item, new_wearable, do_append); +} + +// static bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable) { - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); - U32 index; - if (!gAgentWearables.getWearableIndex(wearable,index)) - { - LL_WARNS() << "Wearable not found" << LL_ENDL; - delete wearable; - return false; - } - if (!new_item) - { - delete wearable; - return false; - } - - switch(option) - { - case 0: // "Save" - gAgentWearables.saveWearable(wearable->getType(),index); - gAgentWearables.setWearableFinal(new_item, wearable); - break; - - case 1: // "Don't Save" - gAgentWearables.setWearableFinal(new_item, wearable); - break; - - case 2: // "Cancel" - break; - - default: - llassert(0); - break; - } - - delete wearable; - return false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID()); + U32 index; + if (!gAgentWearables.getWearableIndex(wearable,index)) + { + LL_WARNS() << "Wearable not found" << LL_ENDL; + delete wearable; + return false; + } + if (!new_item) + { + delete wearable; + return false; + } + + switch(option) + { + case 0: // "Save" + gAgentWearables.saveWearable(wearable->getType(),index); + gAgentWearables.setWearableFinal(new_item, wearable); + break; + + case 1: // "Don't Save" + gAgentWearables.setWearableFinal(new_item, wearable); + break; + + case 2: // "Cancel" + break; + + default: + llassert(0); + break; + } + + delete wearable; + return false; } // Called from setWearableItem() and onSetWearableDialog() to actually set the wearable. // MULTI_WEARABLE: unify code after null objects are gone. void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append) { - const LLWearableType::EType type = new_wearable->getType(); - - if (do_append && getWearableItemID(type,0).notNull()) - { - new_wearable->setItemID(new_item->getUUID()); - const bool trigger_updated = false; - pushWearable(type, new_wearable, trigger_updated); - LL_INFOS() << "Added additional wearable for type " << type - << " size is now " << getWearableCount(type) << LL_ENDL; - checkWearableAgainstInventory(new_wearable); - } - else - { - // Replace the old wearable with a new one. - llassert(new_item->getAssetUUID() == new_wearable->getAssetID()); - - LLViewerWearable *old_wearable = getViewerWearable(type,0); - LLUUID old_item_id; - if (old_wearable) - { - old_item_id = old_wearable->getItemID(); - } - new_wearable->setItemID(new_item->getUUID()); - setWearable(type,0,new_wearable); - - if (old_item_id.notNull()) - { - gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); - gInventory.notifyObservers(); - } - LL_INFOS() << "Replaced current element 0 for type " << type - << " size is now " << getWearableCount(type) << LL_ENDL; - } + const LLWearableType::EType type = new_wearable->getType(); + + if (do_append && getWearableItemID(type,0).notNull()) + { + new_wearable->setItemID(new_item->getUUID()); + const bool trigger_updated = false; + pushWearable(type, new_wearable, trigger_updated); + LL_INFOS() << "Added additional wearable for type " << type + << " size is now " << getWearableCount(type) << LL_ENDL; + checkWearableAgainstInventory(new_wearable); + } + else + { + // Replace the old wearable with a new one. + llassert(new_item->getAssetUUID() == new_wearable->getAssetID()); + + LLViewerWearable *old_wearable = getViewerWearable(type,0); + LLUUID old_item_id; + if (old_wearable) + { + old_item_id = old_wearable->getItemID(); + } + new_wearable->setItemID(new_item->getUUID()); + setWearable(type,0,new_wearable); + + if (old_item_id.notNull()) + { + gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id); + gInventory.notifyObservers(); + } + LL_INFOS() << "Replaced current element 0 for type " << type + << " size is now " << getWearableCount(type) << LL_ENDL; + } } // User has picked "remove from avatar" from a menu. // static void LLAgentWearables::userRemoveWearable(const LLWearableType::EType &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))) - { - gAgentWearables.removeWearable(type,false,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))) + { + gAgentWearables.removeWearable(type,false,index); + } } -//static +//static void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &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))) - { - gAgentWearables.removeWearable(type,true,0); - } + 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))) + { + gAgentWearables.removeWearable(type,true,0); + } } // Given a desired set of attachments, find what objects need to be // removed, and what additional inventory items need to be added. void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array_t& obj_item_array, - llvo_vec_t& objects_to_remove, - llvo_vec_t& objects_to_retain, - LLInventoryModel::item_array_t& items_to_add) -{ - // Possible cases: - // already wearing but not in request set -> take off. - // already wearing and in request set -> leave alone. - // not wearing and in request set -> put on. - - if (!isAgentAvatarValid()) return; - - std::set<LLUUID> requested_item_ids; - std::set<LLUUID> current_item_ids; - for (S32 i=0; i<obj_item_array.size(); i++) - { - const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID(); - //LL_INFOS() << "Requested attachment id " << requested_id << LL_ENDL; - requested_item_ids.insert(requested_id); - } - - // Build up list of objects to be removed and items currently attached. + llvo_vec_t& objects_to_remove, + llvo_vec_t& objects_to_retain, + LLInventoryModel::item_array_t& items_to_add) +{ + // Possible cases: + // already wearing but not in request set -> take off. + // already wearing and in request set -> leave alone. + // not wearing and in request set -> put on. + + if (!isAgentAvatarValid()) return; + + std::set<LLUUID> requested_item_ids; + std::set<LLUUID> current_item_ids; + for (S32 i=0; i<obj_item_array.size(); i++) + { + const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID(); + //LL_INFOS() << "Requested attachment id " << requested_id << LL_ENDL; + requested_item_ids.insert(requested_id); + } + + // Build up list of objects to be removed and items currently attached. LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); LLVOAvatar::attachment_map_t::iterator end = gAgentAvatarp->mAttachmentPoints.end(); - while (iter != end) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject *objectp = attachment_iter->get(); - if (objectp) - { - LLUUID object_item_id = objectp->getAttachmentItemID(); - - bool remove_attachment = true; - if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) - { // Object currently worn, was requested to keep it - // Flag as currently worn so we won't have to add it again. - remove_attachment = false; - } - else if (objectp->isTempAttachment()) - { // Check if we should keep this temp attachment - remove_attachment = LLAppearanceMgr::instance().shouldRemoveTempAttachment(objectp->getID()); - } - - if (remove_attachment) - { - // LL_INFOS() << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL; - objects_to_remove.push_back(objectp); - } - else - { - // LL_INFOS() << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL; - current_item_ids.insert(object_item_id); - objects_to_retain.push_back(objectp); - } - } - } - } - - for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin(); - it != obj_item_array.end(); - ++it) - { - LLUUID linked_id = (*it).get()->getLinkedUUID(); - if (current_item_ids.find(linked_id) != current_item_ids.end()) - { - // Requested attachment is already worn. - } - else - { - // Requested attachment is not worn yet. - items_to_add.push_back(*it); - } - } - // S32 remove_count = objects_to_remove.size(); - // S32 add_count = items_to_add.size(); - // LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL; + while (iter != end) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *objectp = attachment_iter->get(); + if (objectp) + { + LLUUID object_item_id = objectp->getAttachmentItemID(); + + bool remove_attachment = true; + if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) + { // Object currently worn, was requested to keep it + // Flag as currently worn so we won't have to add it again. + remove_attachment = false; + } + else if (objectp->isTempAttachment()) + { // Check if we should keep this temp attachment + remove_attachment = LLAppearanceMgr::instance().shouldRemoveTempAttachment(objectp->getID()); + } + + if (remove_attachment) + { + // LL_INFOS() << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL; + objects_to_remove.push_back(objectp); + } + else + { + // LL_INFOS() << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << LL_ENDL; + current_item_ids.insert(object_item_id); + objects_to_retain.push_back(objectp); + } + } + } + } + + for (LLInventoryModel::item_array_t::iterator it = obj_item_array.begin(); + it != obj_item_array.end(); + ++it) + { + LLUUID linked_id = (*it).get()->getLinkedUUID(); + if (current_item_ids.find(linked_id) != current_item_ids.end()) + { + // Requested attachment is already worn. + } + else + { + // Requested attachment is not worn yet. + items_to_add.push_back(*it); + } + } + // S32 remove_count = objects_to_remove.size(); + // S32 add_count = items_to_add.size(); + // LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL; } std::vector<LLViewerObject*> LLAgentWearables::getTempAttachments() { - llvo_vec_t temp_attachs; - if (isAgentAvatarValid()) - { - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end();) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - LLViewerObject *objectp = attachment_iter->get(); - if (objectp && objectp->isTempAttachment()) - { - temp_attachs.push_back(objectp); - } - } - } - } - return temp_attachs; + llvo_vec_t temp_attachs; + if (isAgentAvatarValid()) + { + for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end();) + { + LLVOAvatar::attachment_map_t::iterator curiter = iter++; + LLViewerJointAttachment* attachment = curiter->second; + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *objectp = attachment_iter->get(); + if (objectp && objectp->isTempAttachment()) + { + temp_attachs.push_back(objectp); + } + } + } + } + return temp_attachs; } void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove) { - if (!isAgentAvatarValid()) return; - - if (objects_to_remove.empty()) - return; - - LL_DEBUGS("Avatar") << "ATT [ObjectDetach] removing " << objects_to_remove.size() << " objects" << LL_ENDL; - gMessageSystem->newMessage("ObjectDetach"); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - for (llvo_vec_t::iterator it = objects_to_remove.begin(); - it != objects_to_remove.end(); - ++it) - { - LLViewerObject *objectp = *it; - //gAgentAvatarp->resetJointPositionsOnDetach(objectp); - gMessageSystem->nextBlockFast(_PREHASH_ObjectData); - gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); - const LLUUID& item_id = objectp->getAttachmentItemID(); - LLViewerInventoryItem *item = gInventory.getItem(item_id); - LL_DEBUGS("Avatar") << "ATT removing object, item is " << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; + if (!isAgentAvatarValid()) return; + + if (objects_to_remove.empty()) + return; + + LL_DEBUGS("Avatar") << "ATT [ObjectDetach] removing " << objects_to_remove.size() << " objects" << LL_ENDL; + gMessageSystem->newMessage("ObjectDetach"); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + for (llvo_vec_t::iterator it = objects_to_remove.begin(); + it != objects_to_remove.end(); + ++it) + { + LLViewerObject *objectp = *it; + //gAgentAvatarp->resetJointPositionsOnDetach(objectp); + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); + const LLUUID& item_id = objectp->getAttachmentItemID(); + LLViewerInventoryItem *item = gInventory.getItem(item_id); + LL_DEBUGS("Avatar") << "ATT removing object, item is " << (item ? item->getName() : "UNKNOWN") << " " << item_id << LL_ENDL; LLAttachmentsMgr::instance().onDetachRequested(item_id); - } - gMessageSystem->sendReliable(gAgent.getRegionHost()); + } + gMessageSystem->sendReliable(gAgent.getRegionHost()); } void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array) { - // Build a compound message to send all the objects that need to be rezzed. - S32 obj_count = obj_item_array.size(); - if (obj_count > 0) - { - LL_DEBUGS("Avatar") << "ATT attaching multiple, total obj_count " << obj_count << LL_ENDL; - } + // Build a compound message to send all the objects that need to be rezzed. + S32 obj_count = obj_item_array.size(); + if (obj_count > 0) + { + LL_DEBUGS("Avatar") << "ATT attaching multiple, total obj_count " << obj_count << LL_ENDL; + } for(LLInventoryModel::item_array_t::const_iterator it = obj_item_array.begin(); it != obj_item_array.end(); ++it) { - const LLInventoryItem* item = *it; + const LLInventoryItem* item = *it; LLAttachmentsMgr::instance().addAttachmentRequest(item->getLinkedUUID(), 0, TRUE); } } @@ -1442,150 +1442,150 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra // (depending on closer_to_body parameter). bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) const { - const LLWearable* wearable = getWearableFromItemID(item_id); - if (!wearable) return false; + 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; + 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; + return wearable != marginal_wearable; } BOOL LLAgentWearables::areWearablesLoaded() const { - return mWearablesLoaded; + return mWearablesLoaded; } bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const { - if (!wearable) return false; - - LLWearableType::EType 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)) - && (getWearableCount(type) <= 1) ); + if (!wearable) return false; + + LLWearableType::EType 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)) + && (getWearableCount(type) <= 1) ); } void LLAgentWearables::animateAllWearableParams(F32 delta) { - for( S32 type = 0; type < LLWearableType::WT_COUNT; ++type ) - { - for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count) - { - LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count); - llassert(wearable); - if (wearable) - { - wearable->animateParams(delta); - } - } - } + for( S32 type = 0; type < LLWearableType::WT_COUNT; ++type ) + { + for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count) + { + LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count); + llassert(wearable); + if (wearable) + { + wearable->animateParams(delta); + } + } + } } bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool closer_to_body) { - if (!item) return false; - if (!item->isWearableType()) return false; - - LLWearableType::EType type = item->getWearableType(); - U32 wearable_count = getWearableCount(type); - if (0 == wearable_count) 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) - { - LLViewerWearable* bottom_wearable = dynamic_cast<LLViewerWearable*>( getBottomWearable(type) ); - if (bottom_wearable->getAssetID() == asset_id) - { - return false; - } - } - else // !closer_to_body - { - LLViewerWearable* top_wearable = dynamic_cast<LLViewerWearable*>( getTopWearable(type) ); - if (top_wearable->getAssetID() == asset_id) - { - return false; - } - } - - for (U32 i = 0; i < wearable_count; ++i) - { - LLViewerWearable* wearable = getViewerWearable(type, i); - if (!wearable) continue; - if (wearable->getAssetID() != asset_id) continue; - - //swapping wearables - U32 swap_i = closer_to_body ? i-1 : i+1; - swapWearables(type, i, swap_i); - return true; - } - - return false; + if (!item) return false; + if (!item->isWearableType()) return false; + + LLWearableType::EType type = item->getWearableType(); + U32 wearable_count = getWearableCount(type); + if (0 == wearable_count) 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) + { + LLViewerWearable* bottom_wearable = dynamic_cast<LLViewerWearable*>( getBottomWearable(type) ); + if (bottom_wearable->getAssetID() == asset_id) + { + return false; + } + } + else // !closer_to_body + { + LLViewerWearable* top_wearable = dynamic_cast<LLViewerWearable*>( getTopWearable(type) ); + if (top_wearable->getAssetID() == asset_id) + { + return false; + } + } + + for (U32 i = 0; i < wearable_count; ++i) + { + LLViewerWearable* wearable = getViewerWearable(type, i); + if (!wearable) continue; + if (wearable->getAssetID() != asset_id) continue; + + //swapping wearables + U32 swap_i = closer_to_body ? i-1 : i+1; + swapWearables(type, i, swap_i); + return true; + } + + return false; } // static void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id, std::function<void(const LLUUID&)> created_cb) { - if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; - - if (type == LLWearableType::WT_UNIVERSAL && !gAgent.getRegion()->bakesOnMeshEnabled()) - { - LL_WARNS("Inventory") << "Can't create WT_UNIVERSAL type " << LL_ENDL; - return; - } - - LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); - LLAssetType::EType asset_type = wearable->getAssetType(); - LLPointer<LLBoostFuncInventoryCallback> cb; - if(wear) - { - cb = new LLBoostFuncInventoryCallback(wear_and_edit_cb); - } - else - { - cb = new LLBoostFuncInventoryCallback(wear_cb); - } + if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; + + if (type == LLWearableType::WT_UNIVERSAL && !gAgent.getRegion()->bakesOnMeshEnabled()) + { + LL_WARNS("Inventory") << "Can't create WT_UNIVERSAL type " << LL_ENDL; + return; + } + + LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); + LLAssetType::EType asset_type = wearable->getAssetType(); + LLPointer<LLBoostFuncInventoryCallback> cb; + if(wear) + { + cb = new LLBoostFuncInventoryCallback(wear_and_edit_cb); + } + else + { + cb = new LLBoostFuncInventoryCallback(wear_cb); + } if (created_cb != NULL) { cb->addOnFireFunc(created_cb); } - LLUUID folder_id; + 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); - } + 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_wearable(gAgent.getID(), - gAgent.getSessionID(), - folder_id, - wearable->getTransactionID(), - wearable->getName(), - wearable->getDescription(), - asset_type, - wearable->getType(), - LLFloaterPerms::getNextOwnerPerms("Wearables"), - cb); + gAgent.getSessionID(), + folder_id, + wearable->getTransactionID(), + wearable->getName(), + wearable->getDescription(), + asset_type, + wearable->getType(), + LLFloaterPerms::getNextOwnerPerms("Wearables"), + cb); } // static void LLAgentWearables::editWearable(const LLUUID& item_id) { - LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); - if (!item) - { - LL_WARNS() << "Failed to get linked item" << LL_ENDL; - return; - } + LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); + if (!item) + { + LL_WARNS() << "Failed to get linked item" << LL_ENDL; + return; + } if (!item->isFinished()) { @@ -1595,18 +1595,18 @@ void LLAgentWearables::editWearable(const LLUUID& item_id) return; } - LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); - if (!wearable) - { - LL_WARNS() << "Cannot get wearable" << LL_ENDL; - return; - } + LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); + if (!wearable) + { + LL_WARNS() << "Cannot get wearable" << LL_ENDL; + return; + } - if (!gAgentWearables.isWearableModifiable(item->getUUID())) - { - LL_WARNS() << "Cannot modify wearable" << LL_ENDL; - return; - } + if (!gAgentWearables.isWearableModifiable(item->getUUID())) + { + LL_WARNS() << "Cannot modify wearable" << LL_ENDL; + return; + } S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE); S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR); @@ -1620,53 +1620,53 @@ void LLAgentWearables::editWearable(const LLUUID& item_id) return; } - const BOOL disable_camera_switch = LLWearableType::getInstance()->getDisableCameraSwitch(wearable->getType()); - LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance"); - LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch); + const BOOL disable_camera_switch = LLWearableType::getInstance()->getDisableCameraSwitch(wearable->getType()); + LLPanel* panel = LLFloaterSidePanelContainer::getPanel("appearance"); + LLSidepanelAppearance::editWearable(wearable, panel, disable_camera_switch); } // Request editing the item after it gets worn. void LLAgentWearables::requestEditingWearable(const LLUUID& item_id) { - mItemToEdit = gInventory.getLinkedItemID(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(); - } + if (mItemToEdit.notNull() && + mItemToEdit == gInventory.getLinkedItemID(item_id)) + { + LLAgentWearables::editWearable(item_id); + mItemToEdit.setNull(); + } } boost::signals2::connection LLAgentWearables::addLoadingStartedCallback(loading_started_callback_t cb) { - return mLoadingStartedSignal.connect(cb); + return mLoadingStartedSignal.connect(cb); } boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_t cb) { - return mLoadedSignal.connect(cb); + return mLoadedSignal.connect(cb); } bool LLAgentWearables::changeInProgress() const { - return mCOFChangeInProgress; + return mCOFChangeInProgress; } void LLAgentWearables::notifyLoadingStarted() { - mCOFChangeInProgress = true; - mCOFChangeTimer.reset(); - mLoadingStartedSignal(); + mCOFChangeInProgress = true; + mCOFChangeTimer.reset(); + mLoadingStartedSignal(); } void LLAgentWearables::notifyLoadingFinished() { - mCOFChangeInProgress = false; - mLoadedSignal(); + mCOFChangeInProgress = false; + mLoadedSignal(); } // EOF |