//=============================================================================
// KFEmit_DirectionalPath
//=============================================================================
// Directional emitter
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//============================================================================

class KFEmit_DirectionalPath extends Emitter;

/** The Template to use for this emitter */
var() ParticleSystem EmitterTemplate;

/** path points to travel to */
var vector DestinationFinal;
var vector DestinationMidPoint;
var vector DestinationCurrent;

/** limit to destroy the partcile */
var float LimitDistanceCurrent;
var float LimitDistanceCurrentPowed;
var float LimitDistanceDestinationFinal;
var float LimitDistanceDestinationMidPoint;

/** rate to changed dir on curves */
var float CurveTurnRateCurrent;
var float CurveTurnRateUntilDestinationFinal;
var float CurveTurnRateUntilDestinationMidPoint;

var float RateTickCheckHasReached;

var vector LastDir;
var vector NewDir;
var bool IsEnabled;

/*********************************************************************************************
* Acceleration physics
 ********************************************************************************************* */

/** Acceleration magnitude */
var() float ParticleSpeed;

var float HalfAngleSpawnCone;

var transient bool bInitialized;

var transient bool bReachDestinationFinal;
var transient bool bReachDestinationMidPoint;
var transient float TickCheckHasReachedTime;

simulated function PostBeginPlay()
{
	//LifeSpan = 3.0;
	TickCheckHasReachedTime = RateTickCheckHasReached;
	Super.PostBeginPlay();
}

/** Override the final waypoint (optional) */
simulated function SetDestination( 	vector NewDestinationFinal,
									vector NewDestinationMidPoint,
									float NewLimitDistanceDestinationFinal,
									float NewLimitDistanceDestinationMidPoint,
									float NewCurveTurnRateUntilDestinationFinal,
									float NewCurveTurnRateUntilDestinationMidPoint,
									float NewHalfAngleSpawnCone)
{
	DestinationFinal = NewDestinationFinal;
	DestinationMidPoint = NewDestinationMidPoint;

	LimitDistanceDestinationFinal = NewLimitDistanceDestinationFinal;
	LimitDistanceDestinationMidPoint = NewLimitDistanceDestinationMidPoint;

	CurveTurnRateUntilDestinationFinal = NewCurveTurnRateUntilDestinationFinal;
	CurveTurnRateUntilDestinationMidPoint = NewCurveTurnRateUntilDestinationMidPoint;

	bReachDestinationFinal = false;
	bReachDestinationMidPoint = false;
	HalfAngleSpawnCone = NewHalfAngleSpawnCone;

	DestinationCurrent = DestinationMidPoint;
	LimitDistanceCurrent = LimitDistanceDestinationMidPoint;
	LimitDistanceCurrentPowed = LimitDistanceCurrent * LimitDistanceCurrent;
	CurveTurnRateCurrent = CurveTurnRateUntilDestinationMidPoint;

	Velocity = VRandCone(Normal(DestinationCurrent - Location), HalfAngleSpawnCone) * ParticleSpeed;
	LastDir = Normal(Velocity);
	SetRotation(rotator(Normal(Velocity)));
	SetPhysics(PHYS_Projectile);

	//OriginalDistanceToDestination = VSize(Destination - Location);

	bInitialized = true;
}

simulated function UpdateDestination( vector NewDestinationFinal, optional vector NewDestinationMidPoint )
{
	DestinationFinal = NewDestinationFinal;
	DestinationMidPoint = NewDestinationMidPoint;

	DestinationCurrent = DestinationFinal;
	if (!bReachDestinationMidPoint)
	{
		DestinationCurrent = DestinationMidPoint;
	}
}

simulated event SetTemplate(ParticleSystem NewTemplate, optional bool bDestroyOnFinish)
{
	Super(Emitter).SetTemplate(NewTemplate, bDestroyOnFinish);
}

simulated function bool HasReachedDestinationFinal()
{
	Local bool bCloseEnough;
	bCloseEnough = VSizeSq(Location - DestinationFinal) <= LimitDistanceCurrentPowed ;
	return bCloseEnough;
}

simulated function bool HasReachedDestinationMidPoint()
{
	Local bool bCloseEnough;
	bCloseEnough = VSizeSq(Location - DestinationMidPoint) <= LimitDistanceCurrentPowed ;
	return bCloseEnough;
}

	
simulated function Tick(float DeltaTime)
{
	if ( !bInitialized || IsEnabled == false )
	{
		return;
	}

	TickCheckHasReachedTime -= DeltaTime;
	if (TickCheckHasReachedTime <= 0)
	{
		TickCheckHasReachedTime = RateTickCheckHasReached;
		
		if (bReachDestinationMidPoint)
		{
			if (bReachDestinationFinal)
			{
				SetLocation(DestinationFinal);
				return;
			}
			if( HasReachedDestinationFinal() )
			{
				bReachDestinationFinal = true;
				SetLocation(DestinationFinal);
				return;
			}
		}
		else
		{
			if( HasReachedDestinationMidPoint() )
			{
				bReachDestinationMidPoint = true;
				DestinationCurrent = DestinationFinal;
				LimitDistanceCurrent = LimitDistanceDestinationFinal;
				LimitDistanceCurrentPowed = LimitDistanceCurrent * LimitDistanceCurrent;
				CurveTurnRateCurrent = CurveTurnRateUntilDestinationFinal;
			}
		}
	}

	



	//Acceleration = CurveTurnRate * DeltaTime * ACCEL_RATE * Normal(Destination - Location);
	//Velocity = Velocity + Acceleration; // force double acceleration
	NewDir = Normal(DestinationCurrent - Location);
	SetRotation(rotator(LastDir + CurveTurnRateCurrent * NewDir));
	Velocity = vector(Rotation) * ParticleSpeed;
	//SetRotation(rotator(Normal(Velocity)));
	LastDir = vector(Rotation);
	//Velocity = vector(Rotation) * ParticleSpeed;

	//DrawDebugSphere(Location, 12, 12, 255, 0, 0, false);
}

simulated function DeactivateEmitter()
{
	ParticleSystemComponent.DeactivateSystem();
	IsEnabled = false;
	bReachDestinationFinal = false;
	bReachDestinationMidPoint = false;
	SetTickIsDisabled(true);
	SetHidden(true);
}

simulated function ActivateEmitter()
{
	ParticleSystemComponent.ActivateSystem();
	IsEnabled = true;
	bInitialized = true;
	SetTickIsDisabled(false);
	SetHidden(false);
}

simulated function OnParticleSystemFinished(ParticleSystemComponent FinishedComponent)
{
	return;
}

defaultproperties
{
	ParticleSpeed=600
	bNoDelete=false
	bStatic=false
	HalfAngleSpawnCone=60

	LimitDistanceDestinationFinal=5
	LimitDistanceDestinationMidPoint=16
	CurveTurnRateUntilDestinationFinal=0.4
	CurveTurnRateUntilDestinationMidPoint=4.0
	RateTickCheckHasReached=0.05
}