SUN-69 MAINT-2258 : temp attachments getting removed improperly. Reviewed by Kelly.
parent
4621aedc37
commit
8eb56668fe
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue