class IsFacingTowardsSource extends EffectObjectSingleFilter_Scripted
{
	editable var m_applyForPlayer : Bool;
	editable var m_applyForNPCs : Bool;
	editable var m_invert : Bool;
	editable var m_maxAllowedAngleYaw : Float;
	default m_maxAllowedAngleYaw = 90.f;
	editable var m_maxAllowedAnglePitch : Float;
	default m_maxAllowedAnglePitch = 45.f;

	public function Process( ctx : EffectScriptContext, filterCtx : EffectSingleFilterScriptContext ) : Bool
	{
		var targetEntity : Entity;
		var targetPuppet : ScriptedPuppet;
		var targetTransform : Transform;
		var sourceEntity : Entity;
		var sourceTransform : Transform;
		var isFacingSource : Bool;
		isFacingSource = true;
		targetEntity = EffectSingleFilterScriptContext.GetEntity( filterCtx );
		sourceEntity = EffectScriptContext.GetSource( ctx );
		if( !( targetEntity ) || !( sourceEntity ) )
		{
			return true;
		}
		sourceTransform = Transform.Create( sourceEntity.GetWorldPosition(), sourceEntity.GetWorldOrientation() );
		targetPuppet = ( ( ScriptedPuppet )( targetEntity ) );
		if( m_applyForPlayer && ( targetEntity == GameInstance.GetPlayerSystem( EffectScriptContext.GetGameInstance( ctx ) ).GetLocalPlayerControlledGameObject() ) )
		{
			GameInstance.GetCameraSystem( EffectScriptContext.GetGameInstance( ctx ) ).GetActiveCameraWorldTransform( targetTransform );
			isFacingSource = IsWithinAngleLimits( sourceTransform, targetTransform, m_maxAllowedAngleYaw, m_maxAllowedAnglePitch );
		}
		if( m_applyForNPCs && targetPuppet )
		{
			targetTransform = Transform.Create( targetEntity.GetWorldPosition(), targetEntity.GetWorldOrientation() );
			isFacingSource = IsWithinAngleLimits( sourceTransform, targetTransform, m_maxAllowedAngleYaw, -1.0 );
		}
		return ( ( m_invert ) ? ( !( isFacingSource ) ) : ( isFacingSource ) );
	}

	public function IsWithinAngleLimits( sourceTransform : Transform, targetTransform : Transform, maxAllowedAngleYaw : Float, maxAllowedAnglePitch : Float ) : Bool
	{
		var distanceVector : Vector4;
		var targetAngles : EulerAngles;
		var distanceVectorAngles : EulerAngles;
		var angleDelta : Float;
		var isWithinLimits : Bool;
		isWithinLimits = true;
		distanceVector = Transform.GetPosition( sourceTransform ) - Transform.GetPosition( targetTransform );
		targetAngles = Vector4.ToRotation( Quaternion.GetForward( Transform.GetOrientation( targetTransform ) ) );
		distanceVectorAngles = Vector4.ToRotation( distanceVector );
		if( maxAllowedAngleYaw > 0.0 )
		{
			angleDelta = AbsF( targetAngles.Yaw - distanceVectorAngles.Yaw );
			isWithinLimits = isWithinLimits && ( angleDelta <= maxAllowedAngleYaw );
		}
		if( maxAllowedAnglePitch > 0.0 )
		{
			angleDelta = AbsF( targetAngles.Pitch - distanceVectorAngles.Pitch );
			isWithinLimits = isWithinLimits && ( angleDelta <= maxAllowedAnglePitch );
		}
		return isWithinLimits;
	}

}

