//=============================================================================
// KFProj_HealingDart
//=============================================================================
// Healing Dart projectile
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// John "Ramm-Jaeger" Gibson
//=============================================================================

class KFProj_HealingDart extends KFProj_Bullet
	hidedropdown;

var Actor SeekTarget;
var vector InitialDir;

/** Tracking strength multiplier */
var(Locking) float TrackingStrength;

/** Offset to apply to SeekTarget's location */
var vector SeekOffset;
/** Set on first tick with a valid SeekTarget */
var bool bSeekInitialized;

replication
{
    if( bNetInitial && (Role==ROLE_Authority) )
        SeekTarget, InitialDir;
}

/** Called from Tick the first time we have a valid target */
simulated function InitializeSeek()
{
	local KFPawn KFP;

	if ( IsZero(InitialDir) )
	{
		InitialDir = Normal(Velocity);
	}

	// Instead of aiming at the cylinder aim for a bone on the mesh that will collide with this
	// projectile. Fixes an issue where the dart can miss a stationary target (see MTO_IKFloorConform)
	KFP = KFPawn(SeekTarget);
	if ( KFP != None && KFP.TorsoBoneName != '' )
	{
		SeekOffset = KFP.Mesh.GetBoneLocation(KFP.TorsoBoneName) - KFP.Location;
	}
}

/** Handle flight FX fading */
simulated event Tick(float DeltaTime)
{
    local vector SeekingVector, ForceDir;
    local float VelMag;

    super.Tick(DeltaTime);

	if ( bShuttingDown || SeekTarget == none )
	{
		return;
	}

	if ( SeekTarget == Instigator )
	{
		SeekTarget = none;
		return;
	}

	// Initialize seek vars
    if ( !bSeekInitialized )
	{
		InitializeSeek();
		bSeekInitialized = true;
	}

	SeekingVector = SeekTarget.Location + SeekOffset;
	ForceDir = Normal(SeekingVector - Location);

	if( (ForceDir Dot InitialDir) > 0.f )
	{
		VelMag = VSize(Velocity);
		Acceleration = TrackingStrength * VelMag * ForceDir;
	}
	else
	{
		Acceleration = Vect(0,0,0);
	}
}

/** Skip projectile HitWall since the healing dart does no damage and just explode/shutdown */
simulated event HitWall(vector HitNormal, Actor Wall, PrimitiveComponent WallComp)
{
	Explode(Location, HitNormal);
}

defaultproperties
{
	MaxSpeed=10000.0
	Speed=10000.0

	TrackingStrength=75

	// @note: Use caution when bNoReplicationToInstigator != bUseClientSideHitDetection or if bSyncToOriginalLocation !=
	// bUpdateSimulatedPosition.  Using CSHD with server replicated projectiles can be error prone if not careful.

	bAmbientSoundZedTimeOnly=false
    bNoReplicationToInstigator=false
	bUseClientSideHitDetection=true
	bUpdateSimulatedPosition=false
	bRotationFollowsVelocity=true//false
	bNetTemporary=false

	bDamageDestructiblesOnTouch=false
}

