bool CMFXParticleEffect::AttachToTarget( const SMFXParticleEntry& particleParams, const SMFXRunTimeEffectParams& params, IParticleEffect* pParticleEffect, const Vec3& dir, float scale )
{
	bool shouldTryToAttach = particleParams.attachToTarget && (params.trg != 0);
	if (!shouldTryToAttach)
	{
		return false;
	}

	IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(params.trg);
	if (pTargetEntity)
	{
		//Try to figure out if it's a character using physics type
		IPhysicalEntity* pTargetPhysics = pTargetEntity->GetPhysics();
		int physicsType = pTargetPhysics ? pTargetPhysics->GetType() : PE_NONE;

		bool isCharacter = (physicsType == PE_LIVING) || (physicsType == PE_ARTICULATED);

		if (isCharacter)
		{
			return AttachToCharacter(*pTargetEntity, particleParams, params, dir, scale);
		}
		//else
		//{
			//return AttachToEntity(*pTargetEntity, particleParams, params, pParticleEffect, dir, scale);
		//}
	}

	return false;
}
void CStickyProjectile::NetSetStuck(CProjectile* pProjectile, bool stuck)
{
	if(stuck && ((m_flags&eSF_IsStuck)==0))
	{
		IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(m_parentId);
		if(pTargetEntity)
		{
			if(ICharacterInstance* pTargetCharacter = pTargetEntity->GetCharacter(0))
			{
				const char* boneName = pTargetCharacter->GetICharacterModel()->GetICharacterModelSkeleton()->GetJointNameByID(m_stuckJoint);
				if(AttachToCharacter(pProjectile, *pTargetEntity, *pTargetCharacter, boneName))
				{
					IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId());
					m_flags |= eSF_IsStuck;
					m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0;
					m_childId = pProjectile->GetEntityId();
				}
			}
		}
		if((m_flags&eSF_IsStuck)==0)
		{
			IEntity* pProjectileEntity = pProjectile->GetEntity();
			AttachTo(pProjectile, pTargetEntity);
			m_childId = pProjectileEntity->GetId();
			if(pTargetEntity) //If we have a parent then the stuck position/rotation are local to the parent
			{
				pProjectileEntity->SetPos(m_stuckPos);
				pProjectileEntity->SetRotation(m_stuckRot);
			}
			else if(m_flags&eSF_OrientateToCollNormal)
			{
				Matrix34 mat;
				mat.SetTranslation(m_stuckPos);
				mat.SetRotation33(Matrix33(m_stuckRot));
				pProjectileEntity->SetWorldTM(mat);
			}
			else
			{
				pProjectileEntity->SetPos(m_stuckPos);
			}
			m_flags |= eSF_IsStuck;
		}
	}
}
bool CStickyProjectile::StickToEntity( const SStickParams& stickParams, IEntity* pTargetEntity )
{
	IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity();
	ICharacterInstance* pCharInstance = pTargetEntity->GetCharacter(0);
	if( pCharInstance)	
	{
		IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId());
		if (!pActor || (stickParams.m_bStickToFriendlies || !pActor->IsFriendlyEntity(stickParams.m_ownerId)) && (gEnv->bMultiplayer || !pActor->IsDead()))
		{
			m_stuckJoint = GetJointIdFromPartId(*pTargetEntity, stickParams.m_targetPartId);
			m_stuckNormal = stickParams.m_stickNormal;
			m_stuckPartId = stickParams.m_targetPartId;

			ICharacterModelSkeleton* pICharacterModelSkeleton = pCharInstance->GetICharacterModel()->GetICharacterModelSkeleton();
			ISkeletonPose* pSkeleton = pCharInstance->GetISkeletonPose();
			const char* boneName = pICharacterModelSkeleton->GetJointNameByID(m_stuckJoint);
			const QuatT jointWorld = QuatT(pTargetEntity->GetWorldTM()) * pSkeleton->GetAbsJointByID(m_stuckJoint);
			QuatT loc;
			CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc );
			pProjectileEntity->SetWorldTM(Matrix34(loc));

			// Get the local pos and rot.
			loc = jointWorld.GetInverted() * loc;
			m_stuckPos = loc.t;
			m_stuckRot = loc.q;

			// Attach.
			if(AttachToCharacter( stickParams.m_pProjectile, *pTargetEntity, *pCharInstance, boneName))
			{
				m_flags |= eSF_IsStuck;
				m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0;
				SetParentId(pTargetEntity->GetId());
				m_childId = pProjectileEntity->GetId();
				return true;
			}
		}
	}
	else
	{
		m_stuckNormal = stickParams.m_stickNormal;
		m_stuckPartId = stickParams.m_targetPartId;

		QuatT loc;
		CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc );

		AttachTo(stickParams.m_pProjectile, pTargetEntity);

		pProjectileEntity->SetWorldTM(Matrix34(loc));

		// Set as Stuck.
		SetParentId(pTargetEntity->GetId());
		m_childId = pProjectileEntity->GetId();
		m_flags |= eSF_IsStuck;

		//Store position and rotation relative to parent entity
		m_stuckPos = pProjectileEntity->GetPos();
		m_stuckRot = pProjectileEntity->GetRotation();
		return true;
	}

	return false;
}