Esempio n. 1
0
// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b
void RlvAttachmentManager::onAttach(LLViewerJointAttachment* pAttachPt)
{
	S32 idxAttachPt = gRlvHandler.getAttachPointIndex(pAttachPt->getObject());
	if (!idxAttachPt)
		return;

	// If the attachment point has a pending "reattach" then we don't want to do anything
	rlv_attach_map_t::iterator itAttach = m_PendingAttach.find(idxAttachPt);
	if (itAttach != m_PendingAttach.end())
	{
		if (pAttachPt->getItemID() == itAttach->second.idItem)
			m_PendingAttach.erase(itAttach);
		return;
	}

	// Check if the attach is the result of a user action (="Wear")
	rlv_wear_map_t::iterator itWear = m_PendingWear.find(pAttachPt->getItemID());
	if (itWear != m_PendingWear.end())
	{
		// We need to return the attachment point to its previous state if it's non-attachable
		if (gRlvHandler.isLockedAttachment(idxAttachPt, RLV_LOCK_ADD))
		{
			// Get the state of the attachment point at the time the user picked "Wear" (if we don't have one it wasn't "add locked" then)
			std::map<S32, LLUUID>::iterator itAttachPrev = itWear->second.attachPts.find(idxAttachPt);
			if ( (itAttachPrev != itWear->second.attachPts.end()) && (pAttachPt->getItemID() != itAttachPrev->second) )
			{
				// If it was empty we need to force detach the new attachment; if it wasn't we need to reattach the old one
				if (itAttachPrev->second.isNull())
				{
					forceDetach(pAttachPt);
					m_PendingDetach.insert(std::pair<S32, LLUUID>(idxAttachPt, pAttachPt->getItemID()));
				}
				else if (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) // (only if we're not reattaching something else there)
				{
					m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(itAttachPrev->second)));
				}
			}
		}
		m_PendingWear.erase(itWear); // No need to start the timer since it should be running already if '!m_PendingWear.empty()'
	}
}
Esempio n. 2
0
// Checked: 2009-10-12 (RLVa-1.0.5b) | Modified: RLVa-1.0.5b
void RlvAttachmentManager::onDetach(LLViewerJointAttachment* pAttachPt)
{
	S32 idxAttachPt = gRlvHandler.getAttachPointIndex(pAttachPt->getObject());
	if (!idxAttachPt)
		return;

	// If this is an attachment that we force-detached then we don't want to do anything (even if it is "remove locked")
	rlv_detach_map_t::iterator itDetach = m_PendingDetach.find(idxAttachPt);
	if ( (itDetach != m_PendingDetach.end()) && (itDetach->second == pAttachPt->getItemID()) )
	{
		m_PendingDetach.erase(itDetach);
		return;
	}

	// If the attachment is currently "remove locked" and we're not already trying to reattach something there we should reattach it
	if ( (m_PendingAttach.find(idxAttachPt) == m_PendingAttach.end()) && (gRlvHandler.isLockedAttachment(idxAttachPt, RLV_LOCK_REMOVE)) )
	{
		m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(pAttachPt->getItemID())));
		startTimer();
	}
}
Esempio n. 3
0
// Checked: 2010-07-28 (RLVa-1.1.3a) | Modified: RLVa-1.2.0i
void RlvAttachmentLockWatchdog::onDetach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt)
{
	S32 idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachPt);
	const LLUUID& idAttachItem = (pAttachObj) ? pAttachObj->getAttachmentItemID() : LLUUID::null;
	RLV_ASSERT( (!gAgent.getAvatarObject()) || ((idxAttachPt) && (idAttachItem.notNull())) );
	if ( (!idxAttachPt) || (idAttachItem.isNull()) )
		return;

	// If it's an attachment that's pending force-detach then we don't want to do anything (even if it's currently "remove locked")
	rlv_detach_map_t::iterator itDetach = std::find(m_PendingDetach.begin(), m_PendingDetach.end(), idAttachItem);
	if (itDetach != m_PendingDetach.end())
	{
		m_PendingDetach.erase(itDetach);
		return;
	}

	// If the attachment is currently "remove locked" then we should reattach it (unless it's already pending reattach)
	if (gRlvAttachmentLocks.isLockedAttachment(pAttachObj))
	{
		bool fPendingAttach = false;
		for (rlv_attach_map_t::const_iterator itReattach = m_PendingAttach.lower_bound(idxAttachPt), 
				itReattachEnd = m_PendingAttach.upper_bound(idxAttachPt); itReattach != itReattachEnd; ++itReattach)
		{
			if (itReattach->second.idItem == idAttachItem)
			{
				fPendingAttach = true;
				break;
			}
		}

		// TODO-RLVa: [RLVa-1.2.1] we should re-add the item to COF as well to make sure it'll reattach when the user relogs
		//		-> check the call order in LLVOAvatarSelf::detachObject() since COF removal happens *after* we're called
		if (!fPendingAttach)
		{
			m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(idAttachItem)));
			startTimer();
		}
	}
}
Esempio n. 4
0
// Checked: 2010-09-23 (RLVa-1.1.3a) | Modified: RLVa-1.2.1d
void RlvAttachmentLockWatchdog::onAttach(const LLViewerObject* pAttachObj, const LLViewerJointAttachment* pAttachPt)
{
	S32 idxAttachPt = RlvAttachPtLookup::getAttachPointIndex(pAttachObj);
	const LLUUID& idAttachItem = (pAttachObj) ? pAttachObj->getAttachmentItemID() : LLUUID::null;
	RLV_ASSERT( (!gAgent.getAvatarObject()) || ((idxAttachPt) && (idAttachItem.notNull())) );
	if ( (!idxAttachPt) || (idAttachItem.isNull()) )
		return;

	// Check if the attachment point has a pending "reattach"
	rlv_attach_map_t::iterator itAttach = m_PendingAttach.lower_bound(idxAttachPt), itAttachEnd = m_PendingAttach.upper_bound(idxAttachPt);
	if (itAttach != itAttachEnd)
	{
		bool fPendingReattach = false;
		for (; itAttach != itAttachEnd; ++itAttach)
		{
			if (idAttachItem == itAttach->second.idItem)
			{
				fPendingReattach = true;
				m_PendingAttach.erase(itAttach);
				break;
			}
		}
		if (!fPendingReattach)
			detach(pAttachObj);
		return;
	}

	// Check if the attach was allowed at the time it was requested
	rlv_wear_map_t::iterator itWear = m_PendingWear.find(idAttachItem);
	if (itWear != m_PendingWear.end())
	{
		// We'll need to return the attachment point to its previous state if it was non-attachable
		if (itWear->second.isAddLockedAttachPt(idxAttachPt))
		{
			// Get the saved state of the attachment point (but do nothing if the item itself was already worn then)
			std::map<S32, uuid_vec_t>::iterator itAttachPrev = itWear->second.attachPts.find(idxAttachPt);
			RLV_ASSERT(itAttachPrev != itWear->second.attachPts.end());
			if (std::find(itAttachPrev->second.begin(), itAttachPrev->second.end(), idAttachItem) == itAttachPrev->second.end())
			{
				// If it was empty we need to detach everything on the attachment point; if it wasn't we need to restore it to what it was
				if (itAttachPrev->second.empty())
				{
					detach(idxAttachPt);
				}
				else
				{
					// Iterate over all the current attachments and force detach any that shouldn't be there
					c_llvo_vec_t attachObjs;
					for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
							itAttachObj != pAttachPt->mAttachedObjects.end(); ++itAttachObj)
					{
						const LLViewerObject* pAttachObj = *itAttachObj;

						uuid_vec_t::iterator itAttach = 
							std::find(itAttachPrev->second.begin(), itAttachPrev->second.end(), pAttachObj->getAttachmentItemID());
						if (itAttach == itAttachPrev->second.end())
							detach(pAttachObj);
						else
							itAttachPrev->second.erase(itAttach);
					}

					// Whatever is left is something that needs to be reattached
					for (uuid_vec_t::const_iterator itAttach = itAttachPrev->second.begin(); 
							itAttach != itAttachPrev->second.end(); ++itAttach)
					{
						m_PendingAttach.insert(std::pair<S32, RlvReattachInfo>(idxAttachPt, RlvReattachInfo(*itAttach)));
					}
				}
			}
		}
		else if (RLV_WEAR_REPLACE == itWear->second.eWearAction)
		{
			// Now that we know where this attaches to check if we can actually perform a "replace"
			bool fCanReplace = true;
			for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachObj = pAttachPt->mAttachedObjects.begin();
					((itAttachObj != pAttachPt->mAttachedObjects.end()) && (fCanReplace)); ++itAttachObj)
			{
				if (pAttachObj != *itAttachObj)
					fCanReplace &= !gRlvAttachmentLocks.isLockedAttachment(*itAttachObj);
			}

			if (fCanReplace)
				detach(idxAttachPt, pAttachObj);	// Replace == allowed: detach everything except the new attachment
			else
				detach(pAttachObj);					// Replace != allowed: detach the new attachment
		}
		m_PendingWear.erase(itWear); // No need to start the timer since it should be running already if '!m_PendingWear.empty()'
	}
}