void CDAViewModel::FireObsoleteEvent( const Vector& origin, const QAngle& angles, int event, const char *options )
{
	CSDKPlayer* pOwner = ToSDKPlayer(GetOwner());
	if (!pOwner)
		return;

	Vector attachOrigin;
	QAngle attachAngles; 

	switch( event )
	{
	// Obsolete. Use the AE_CL_CREATE_PARTICLE_EFFECT event instead, which uses the artist driven particle system & editor.
	case AE_CLIENT_EFFECT_ATTACH:
		{
			int iAttachment = -1;
			int iParam = 0;
			char token[128];
			char effectFunc[128];

			const char *p = options;

			p = nexttoken(token, p, ' ');

			if( token ) 
				Q_strncpy( effectFunc, token, sizeof(effectFunc) );

			p = nexttoken(token, p, ' ');

			bool bResult = false;

			if( token )
			{
				if (pOwner->IsInThirdPerson() && pOwner->GetActiveSDKWeapon())
				{
					iAttachment = pOwner->GetActiveSDKWeapon()->LookupAttachment(token);
					bResult = pOwner->GetActiveSDKWeapon()->GetAttachment( iAttachment, attachOrigin, attachAngles );
				}
				else
				{
					iAttachment = LookupAttachment(token);
					bResult = GetAttachment( iAttachment, attachOrigin, attachAngles );
				}
			}

			p = nexttoken(token, p, ' ');

			if( token )
				iParam = atoi(token);

			if (bResult)
			{
				// Fill out the generic data
				CEffectData data;
				data.m_vOrigin = attachOrigin;
				data.m_vAngles = attachAngles;
				AngleVectors( attachAngles, &data.m_vNormal );
				data.m_hEntity = GetRefEHandle();
				data.m_nAttachmentIndex = iAttachment + 1;
				data.m_fFlags = iParam;

				DispatchEffect( effectFunc, data );
			}
		}
		break;
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CSDKPlayerAnimState::Update( float eyeYaw, float eyePitch, float flCharacterYaw, float flCharacterPitch )
{
	// Profile the animation update.
	VPROF( "CMultiPlayerAnimState::Update" );

	// Get the SDK player.
	CSDKPlayer *pSDKPlayer = GetSDKPlayer();
	if ( !pSDKPlayer )
		return;

	// Get the studio header for the player.
	CStudioHdr *pStudioHdr = pSDKPlayer->GetModelPtr();
	if ( !pStudioHdr )
		return;

	// Check to see if we should be updating the animation state - dead, ragdolled?
	if ( !ShouldUpdateAnimState() )
	{
		ClearAnimationState();
		return;
	}

	// Store the eye angles.
	m_flEyeYaw = AngleNormalize( eyeYaw );
	m_flEyePitch = AngleNormalize( eyePitch );

	float flRampSpeed = 20;
	if (pSDKPlayer->GetActiveSDKWeapon() && pSDKPlayer->GetActiveSDKWeapon()->HasAimInSpeedPenalty())
		flRampSpeed = 50;

	float flApproachSpeed = gpGlobals->frametime * pSDKPlayer->GetSlowMoMultiplier() * RemapVal(m_pSDKPlayer->m_Shared.GetAimIn(), 0, 1, 10, flRampSpeed);

	float flYawDifference = AngleNormalize( flCharacterYaw - m_flCharacterEyeYaw );
	float flYawApproachSpeed = flYawDifference * flApproachSpeed;
	if (fabs(flYawApproachSpeed) < fabs(flYawDifference))
		m_flCharacterEyeYaw += flYawApproachSpeed;
	else
		m_flCharacterEyeYaw = flCharacterYaw;

	float flPitchDifference = AngleNormalize( flCharacterPitch - m_flCharacterEyePitch );
	float flPitchApproachSpeed = flPitchDifference * flApproachSpeed;
	if (fabs(flPitchApproachSpeed) < fabs(flPitchDifference))
		m_flCharacterEyePitch += flPitchApproachSpeed;
	else
		m_flCharacterEyePitch = flCharacterPitch;

	// Compute the player sequences.
	ComputeSequences( pStudioHdr );

	if ( SetupPoseParameters( pStudioHdr ) )
	{
		// Pose parameter - what direction are the player's legs running in.
		ComputePoseParam_MoveYaw( pStudioHdr );

		ComputePoseParam_StuntYaw( pStudioHdr );

		// Pose parameter - Torso aiming (up/down).
		ComputePoseParam_AimPitch( pStudioHdr );

		// Pose parameter - Torso aiming (rotation).
		ComputePoseParam_AimYaw( pStudioHdr );
	}

#ifdef CLIENT_DLL 
	if ( C_BasePlayer::ShouldDrawLocalPlayer() )
	{
		m_pSDKPlayer->SetPlaybackRate( 1.0f );
	}
#endif
}