class NPCTrackingPlayerPrereqState extends PrereqState
{
	var m_listener : PuppetListener;
}

class NPCTrackingPlayerPrereq extends IScriptablePrereq
{
	var m_invert : Bool;

	protected export override function Initialize( recordID : TweakDBID )
	{
		m_invert = TweakDBInterface.GetBool( recordID + T".invert", false );
	}

	protected export const override function OnRegister( state : PrereqState, game : GameInstance, context : IScriptable ) : Bool
	{
		var npcOwner : NPCPuppet;
		var castedState : NPCTrackingPlayerPrereqState;
		npcOwner = ( ( NPCPuppet )( context ) );
		if( npcOwner )
		{
			castedState = ( ( NPCTrackingPlayerPrereqState )( state ) );
			castedState.m_listener = new PuppetListener;
			castedState.m_listener.RegisterOwner( castedState );
			ScriptedPuppet.AddListener( npcOwner, castedState.m_listener );
			return false;
		}
		return false;
	}

	protected export const override function OnUnregister( state : PrereqState, game : GameInstance, context : IScriptable )
	{
		var npcOwner : NPCPuppet;
		var castedState : NPCTrackingPlayerPrereqState;
		npcOwner = ( ( NPCPuppet )( context ) );
		castedState = ( ( NPCTrackingPlayerPrereqState )( state ) );
		if( npcOwner && castedState.m_listener )
		{
			ScriptedPuppet.RemoveListener( npcOwner, castedState.m_listener );
		}
		castedState.m_listener = NULL;
	}

	public export const override function IsFulfilled( game : GameInstance, context : IScriptable ) : Bool
	{
		var owner : GameObject;
		var targetNPC : weak< NPCPuppet >;
		owner = ( ( GameObject )( context ) );
		targetNPC = ( ( NPCPuppet )( owner ) );
		return EvaluateCondition( targetNPC.IsPuppetTargetingPlayer() );
	}

	public const function EvaluateCondition( isTrackingPlayer : Bool ) : Bool
	{
		if( !( isTrackingPlayer ) )
		{
			return ( ( m_invert ) ? ( true ) : ( false ) );
		}
		return ( ( m_invert ) ? ( false ) : ( true ) );
	}

}

class NPCDetectingPlayerPrereqState extends PrereqState
{
	var m_owner : weak< GameObject >;
	var m_listenerID : CallbackHandle;

	protected event OnStateUpdate( value : Float )
	{
		var checkPassed : Bool;
		const var prereq : NPCDetectingPlayerPrereq;
		prereq = ( ( NPCDetectingPlayerPrereq )( GetPrereq() ) );
		checkPassed = prereq.Evaluate( m_owner, value );
		OnChanged( checkPassed );
	}

}

class NPCDetectingPlayerPrereq extends IScriptablePrereq
{
	var m_threshold : Float;

	protected override function Initialize( recordID : TweakDBID )
	{
		m_threshold = TweakDBInterface.GetFloat( recordID + T".percentage", 0.0 );
	}

	protected const override function OnRegister( state : PrereqState, game : GameInstance, context : IScriptable ) : Bool
	{
		var bb : IBlackboard;
		var castedState : NPCDetectingPlayerPrereqState;
		bb = ( ( ScriptedPuppet )( context ) ).GetPuppetStateBlackboard();
		castedState = ( ( NPCDetectingPlayerPrereqState )( state ) );
		castedState.m_owner = ( ( GameObject )( context ) );
		castedState.m_listenerID = bb.RegisterListenerFloat( GetAllBlackboardDefs().PuppetState.DetectionPercentage, castedState, 'OnStateUpdate' );
		return false;
	}

	protected const override function OnUnregister( state : PrereqState, game : GameInstance, context : IScriptable )
	{
		var castedState : NPCDetectingPlayerPrereqState;
		castedState = ( ( NPCDetectingPlayerPrereqState )( state ) );
		if( castedState.m_listenerID )
		{
			( ( ScriptedPuppet )( context ) ).GetPuppetStateBlackboard().UnregisterListenerFloat( GetAllBlackboardDefs().PuppetState.DetectionPercentage, castedState.m_listenerID );
		}
	}

	public const override function IsFulfilled( game : GameInstance, context : IScriptable ) : Bool
	{
		var owner : GameObject;
		var targetNPC : weak< NPCPuppet >;
		owner = ( ( GameObject )( context ) );
		targetNPC = ( ( NPCPuppet )( owner ) );
		if( targetNPC.GetDetectionPercentage() > m_threshold )
		{
			return true;
		}
		return false;
	}

	public const function Evaluate( owner : GameObject, percentage : Float ) : Bool
	{
		if( m_threshold == 0.0 )
		{
			if( percentage > 0.0 )
			{
				return true;
			}
		}
		else
		{
			if( percentage >= m_threshold )
			{
				return true;
			}
		}
		return false;
	}

}

