SUN-69 MAINT-2258 : temp attachments getting removed improperly. Reviewed by Kelly.

meow-7.2.2
simon 2013-10-17 14:58:27 -07:00
parent 4621aedc37
commit 8eb56668fe
7 changed files with 95 additions and 9 deletions

View File

@ -1538,7 +1538,11 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
std::set<LLUUID> requested_item_ids;
std::set<LLUUID> current_item_ids;
for (S32 i=0; i<obj_item_array.count(); i++)
requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID());
{
const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID();
//llinfos << "Requested attachment id " << requested_id << llendl;
requested_item_ids.insert(requested_id);
}
// Build up list of objects to be removed and items currently attached.
llvo_vec_t objects_to_remove;
@ -1555,16 +1559,27 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
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.
{ // Object currently worn, was requested to keep it
// Flag as currently worn so we won't have to add it again.
current_item_ids.insert(object_item_id);
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)
{
// llinfos << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl;
objects_to_remove.push_back(objectp);
}
else
{
// object currently worn, not requested.
objects_to_remove.push_back(objectp);
// llinfos << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl;
current_item_ids.insert(object_item_id);
}
}
}

View File

@ -3415,21 +3415,50 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
llwarns << "called with empty list, nothing to do" << llendl;
}
for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
{
{
const LLUUID& id_to_remove = *it;
const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
removeCOFItemLinks(linked_item_id);
}
updateAppearanceFromCOF();
addDoomedTempAttachment(linked_item_id);
}
updateAppearanceFromCOF();
}
void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
{
LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
removeCOFItemLinks(linked_item_id);
addDoomedTempAttachment(linked_item_id);
updateAppearanceFromCOF();
}
// Adds the given item ID to mDoomedTempAttachmentIDs iff it's a temp attachment
void LLAppearanceMgr::addDoomedTempAttachment(const LLUUID& id_to_remove)
{
LLViewerObject * attachmentp = gAgentAvatarp->findAttachmentByID(id_to_remove);
if (attachmentp &&
attachmentp->isTempAttachment())
{ // If this is a temp attachment and we want to remove it, record the ID
// so it will be deleted when attachments are synced up with COF
mDoomedTempAttachmentIDs.insert(id_to_remove);
//llinfos << "Will remove temp attachment id " << id_to_remove << llendl;
}
}
// Find AND REMOVES the given UUID from mDoomedTempAttachmentIDs
bool LLAppearanceMgr::shouldRemoveTempAttachment(const LLUUID& item_id)
{
doomed_temp_attachments_t::iterator iter = mDoomedTempAttachmentIDs.find(item_id);
if (iter != mDoomedTempAttachmentIDs.end())
{
mDoomedTempAttachmentIDs.erase(iter);
return true;
}
return false;
}
bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
{
if (!item || !item->isWearableType()) return false;

View File

@ -142,6 +142,9 @@ public:
void removeAllClothesFromAvatar();
void removeAllAttachmentsFromAvatar();
// Special handling of temp attachments, which are not in the COF
bool shouldRemoveTempAttachment(const LLUUID& item_id);
//has the current outfit changed since it was loaded?
bool isOutfitDirty() { return mOutfitIsDirty; }
@ -239,6 +242,12 @@ private:
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
// Set of temp attachment UUIDs that should be removed
typedef std::set<LLUUID> doomed_temp_attachments_t;
doomed_temp_attachments_t mDoomedTempAttachmentIDs;
void addDoomedTempAttachment(const LLUUID& id_to_remove);
//////////////////////////////////////////////////////////////////////////////////
// Item-specific convenience functions
public:

View File

@ -5879,6 +5879,13 @@ void LLViewerObject::resetChildrenPosition(const LLVector3& offset, BOOL simplif
return ;
}
// virtual
BOOL LLViewerObject::isTempAttachment() const
{
return (mID.notNull() && (mID == mAttachmentItemID));
}
const LLUUID &LLViewerObject::getAttachmentItemID() const
{
return mAttachmentItemID;

View File

@ -171,6 +171,8 @@ public:
virtual BOOL isAttachment() const { return FALSE; }
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;
virtual void updateRadius() {};
virtual F32 getVObjRadius() const; // default implemenation is mDrawable->getRadius()

View File

@ -5975,6 +5975,28 @@ BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
LLViewerObject * LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) const
{
for(attachment_map_t::const_iterator attachment_points_iter = mAttachmentPoints.begin();
attachment_points_iter != gAgentAvatarp->mAttachmentPoints.end();
++attachment_points_iter)
{
LLViewerJointAttachment* attachment = attachment_points_iter->second;
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
attachment_iter != attachment->mAttachedObjects.end();
++attachment_iter)
{
LLViewerObject *attached_object = (*attachment_iter);
if (attached_object &&
attached_object->getID() == target_id)
{
return attached_object;
}
}
}
return NULL;
}
// virtual

View File

@ -731,6 +731,8 @@ public:
void cleanupAttachedMesh( LLViewerObject* pVO );
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
protected:
LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
void lazyAttach();