class CBTTask3StateProjectileAttack extends CBTTask3StateAttack
{
	public var attackRange			: float;
	public var projEntity			: CEntityTemplate;
	public var projectileName	 	: name;
	public var dodgeable			: bool;
	public var useLookatTarget		: bool;
	
	public var projectiles 		: array<W3AdvancedProjectile>;
	
	latent function Main() : EBTNodeStatus
	{
		var res : EBTNodeStatus;
		if ( !projEntity )
		{
			projEntity = (CEntityTemplate)LoadResourceAsync( projectileName );
		}
		
		if ( !projEntity )
		{
			return BTNS_Failed;
		}
		
		res = super.Main();
		
		return res;
	}
	
	function OnAnimEvent( animEventName : name, animEventType : EAnimationEventType, animInfo : SAnimationEventAnimInfo ) : bool
	{
		var res : bool;
		
		res = super.OnAnimEvent(animEventName,animEventType, animInfo);
		
		if ( animEventName == 'ShootProjectile' )
		{
			ShootProjectile();
			return true;
		}
		else if ( animEventName == 'Shoot3Projectiles' )
		{
			ShootProjectile();
			ShootProjectile(GetActor().GetHeading()+5);
			ShootProjectile(GetActor().GetHeading()-5);
			return true;
		}
		else if ( animEventName == 'Shoot5Projectiles' )
		{
			ShootProjectile();
			ShootProjectile(GetActor().GetHeading()+5);
			ShootProjectile(GetActor().GetHeading()-5);
			ShootProjectile(GetActor().GetHeading()+10);
			ShootProjectile(GetActor().GetHeading()-10);
			return true;
		}
		
		return res;
	}
	
	function ShootProjectile(optional customHeading : float)
	{
		var npc : CNewNPC = GetNPC();
		var projRot : EulerAngles;
		var projPos, targetPos : Vector;
		var projectile : W3AdvancedProjectile;
		var distanceToTarget : float;
		var projectileFlightTime : float;
		var target : CActor = GetCombatTarget();
		
		var projOriginMat : Matrix;
		
		if ( npc.CalcEntitySlotMatrix( 'projectile_origin', projOriginMat ) )
		{
			projPos	= MatrixGetTranslation( projOriginMat );
		}
		else
		{
			projPos = npc.GetWorldPosition();
			projPos.Z += 1.5f;
		}
		
		projRot = npc.GetWorldRotation();
		projectile = (W3AdvancedProjectile)theGame.CreateEntity( projEntity, projPos, projRot );
		projectile.Init( npc );
		
		
		if ( useLookatTarget )
		{
			targetPos = npc.GetBehaviorVectorVariable('lookAtTarget');
		}
		else if ( customHeading )
			targetPos = projPos + VecFromHeading(customHeading)*attackRange;
		else
			targetPos = projPos +  npc.GetHeadingVector()*attackRange;
			
		projectile.ShootProjectileAtPosition( 0, projectile.projSpeed, targetPos, attackRange );
		
		if ( dodgeable )
		{
			distanceToTarget = VecDistance( npc.GetWorldPosition(), target.GetWorldPosition() );		
			
			// used to dodge projectile before it hits
			projectileFlightTime = distanceToTarget / projectile.projSpeed;
			target.SignalGameplayEventParamFloat('Time2DodgeProjectile', projectileFlightTime );
		}
		
		projectiles.PushBack( projectile );
	}
}

class CBTTask3StateProjectileAttackDef extends CBTTask3StateAttackDef
{
	default instanceClass = 'CBTTask3StateProjectileAttack';

	editable var attackRange 		: float;
	//editable var projEntity	 		: CEntityTemplate;
	editable var projectileName	 	: name;
	editable var dodgeable			: bool;
	editable var useLookatTarget	: bool;
	
	hint projEntity = "!!Obsolete!! - use projectileName instead";
	
	default dodgeable = true;
	default attackRange = 10.0;
}