//=============================================================================
// KFExplosion_ReplicatedMedicGrenade
//=============================================================================
// Used by projectiles and kismet to spawn an explosion
// Extends KFExplosion_MedicGrenade and uses functionality from KFExplosionActorReplicated
//=============================================================================
// Killing Floor 2
// Copyright (C) 2018 Tripwire Interactive LLC
//=============================================================================

class KFExplosion_ReplicatedMedicGrenade extends KFExplosion_MedicGrenade;

/** Should be a serializable object, like in the level or something (as is the case for kismet actions). */
var transient private repnotify GameExplosion		ExploTemplateRef;

/** Does a trace to find hitactor, hitlocation, hitnormal for directional explosions */
var bool bTraceForHitActorWhenDirectionalExplosion;

/** If true, spawn particle system at the weapon muzzle even actor location is not */
var bool bSyncParticlesToMuzzle;

/** The pawn the explosion should attach to */
var transient repnotify Pawn BlastAttachee;

/** Where the explosion will attach if there's a BlastAttachee */
var name AttachPointName;

replication
{
	if (bNetDirty)
		ExploTemplateRef, bTraceForHitActorWhenDirectionalExplosion, bSyncParticlesToMuzzle, BlastAttachee;
}

simulated event ReplicatedEvent(Name VarName)
{
	if (VarName == 'ExploTemplateRef')
	{
		Explode(ExploTemplateRef, ExplosionDirection);
	}
	else
	{
		super.ReplicatedEvent(VarName);
	}
}

simulated function Explode(GameExplosion NewExplosionTemplate, optional vector ExploDirection)
{
	local vector MyHitLocation, MyHitNormal;
	local vector TraceStart, TraceDest;
	Local Actor MyHitActor;

	// Trace to find where the directional blast would hit for applying effects
	if (NewExplosionTemplate.bDirectionalExplosion && bTraceForHitActorWhenDirectionalExplosion)
	{
		TraceStart = Location;
		TraceDest = Location + (ExploDirection * NewExplosionTemplate.DamageRadius);

		MyHitActor = Trace(MyHitLocation, MyHitNormal, TraceDest, TraceStart, TRUE, , , TRACEFLAG_Bullet);

		if (MyHitActor != none)
		{
			NewExplosionTemplate.HitLocation = MyHitLocation;
			NewExplosionTemplate.HitNormal = MyHitNormal;
		}
	}

	if (Role == ROLE_Authority)
	{
		BlastAttachee = Pawn(Attachee);
		ExploTemplateRef = NewExplosionTemplate;
	}

	super.Explode(NewExplosionTemplate, ExploDirection);

	LifeSpan = FMax(LifeSpan, 1.0);
}

/** Use actor rotation instead of HitNormal! */
simulated function SpawnExplosionParticleSystem(ParticleSystem Template)
{
	if (BlastAttachee != none)
	{
		WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(Template, BlastAttachee.Mesh, AttachPointName);
	}
	else if (bSyncParticlesToMuzzle)
	{
		WorldInfo.MyEmitterPool.SpawnEmitter(Template, GetMuzzleEffectLocation(), Rotation, None);
	}
	else
	{
		WorldInfo.MyEmitterPool.SpawnEmitter(Template, Location, Rotation, None);
	}
}

simulated function SetSyncToMuzzleLocation(bool bSync)
{
	bSyncParticlesToMuzzle = bSync;
}

/**
 * Get muzzle location for currently equipped weapon
 * This is visual only! Damage is done from ExplosionActor location
 */
simulated function vector GetMuzzleEffectLocation()
{
	local KFPawn KFP;

	if (WorldInfo.NetMode != NM_DedicatedServer && Instigator != None)
	{
		// Try third person attachment
		if (!Instigator.IsFirstPerson())
		{
			KFP = KFPawn(Instigator);
			if (KFP != None && KFP.WeaponAttachment != None)
			{
				return KFP.WeaponAttachment.GetMuzzleLocation(0);
			}
		}
		// Otherwise use first person muzzle
		else if (Instigator.Weapon != None)
		{
			return Instigator.Weapon.GetMuzzleLoc();
		}
	}

	return Location;
}

defaultproperties
{
	bNetTemporary = true
	bAlwaysRelevant = TRUE
	RemoteRole = ROLE_SimulatedProxy
	bNetInitialRotation = TRUE

	HealingAmount=5
	Interval=1
	MaxTime=8

	AttachPointName=Hips
}
