class BoltEMPProj expands Projectile;

#exec MESH IMPORT MESH=BoltEMPProj ANIVFILE=MODELS\BoltEMPProj_a.3d DATAFILE=MODELS\BoltEMPProj_d.3d X=0 Y=0 Z=0
#exec MESH LODPARAMS MESH=BoltEMPProj STRENGTH=0
#exec MESH ORIGIN MESH=BoltEMPProj X=0 Y=0 Z=0

#exec MESH SEQUENCE MESH=BoltEMPProj SEQ=All STARTFRAME=0 NUMFRAMES=1
#exec MESH SEQUENCE MESH=BoltEMPProj SEQ=Still STARTFRAME=0 NUMFRAMES=1

#exec MESHMAP NEW MESHMAP=BoltEMPProj MESH=BoltEMPProj
#exec MESHMAP SCALE MESHMAP=BoltEMPProj X=0.1 Y=0.1 Z=0.2

#exec OBJ LOAD FILE=Textures\NaliEffects.utx PACKAGE=NaliWeaponsII.GFX
#exec MESHMAP SETTEXTURE MESHMAP=BoltEMPProj NUM=1 TEXTURE=Electric02

#exec AUDIO IMPORT NAME="BoltEMPLoop" FILE=SOUNDS\BoltEMPLoop.wav GROUP="BoltR"


var int Kickback;
var float Splasher, MoreDamage;
var bool HealthGiver;

var int LastBoltTime;
var BoltEMPCorona BoltTrail;

var bool bCanHitOwner;


replication
{
	// Things the server should send to the client.
	reliable if(Role==ROLE_Authority)
		Kickback, MoreDamage, HealthGiver, Splasher;
}

simulated function Timer()
{
	if (!bCanHitOwner)
		bCanHitOwner = True;
}


simulated function Destroyed()
{
    if ( BoltTrail != None )
        BoltTrail.Destroy();
    Super.Destroyed();
}


simulated function PostBeginPlay()
{
	Super.PostBeginPlay();
	BoltTrail = Spawn(Class'BoltEMPCorona', Self);
	SetTimer(0.8, False);
}


function Combo()
{
local ComboShockwave cs;
local int i;

	cs = Spawn(Class'ComboShockwave');
	cs.Kickback = Kickback;
	cs.MoreDamage = MoreDamage;
	cs.HealthGiver = HealthGiver;
	cs.Splasher = Splasher;

	Spawn(Class'EMPCombo');

	Spawn(class'X_ParticleExplosionB');

	For (i=0; i<7; i++)
		Spawn(Class'TraceCombo',,,, RotRand());

	Destroy();
}


simulated function ClientFlashes()
{
	local Vector EndFlashFog;
	local float f;
	local PlayerPawn p;

	//EndFlashFog.X=0;	EndFlashFog.Y=0;	EndFlashFog.Z=3;
	EndFlashFog.X=0;	EndFlashFog.Y=3;	EndFlashFog.Z=3;

	ForEach VisibleCollidingActors( class'PlayerPawn', p, 600)
	{
		p.ClientFlash( 2, 1000*EndFlashFog );
	}
}

//Special HurtRadius - With Health giving implementation
//******************************************************************************************************************
function HurtRadiusX( float DamageAmount, float DamageRadius, name DamageName, float Momentum, vector HitLocation )
{
    local actor Victims;
    local float damageScale, dist;
    local vector dir;
    local Pawn P;
    
    if( bHurtEntry )
        return;

    bHurtEntry = true;
    foreach VisibleCollidingActors( class 'Actor', Victims, DamageRadius, HitLocation )
    {
	if (HealthGiver && Victims.IsA('Pawn'))
	{
		dir = Victims.Location - HitLocation;
		dist = FMax(1,VSize(dir));
		dir = dir/dist; 
		damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);

		P = Pawn(Victims);
		If (((P.PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team && Level.Game.IsA('TeamGamePlus') && !Level.Game.IsA('MonsterHunt')) ||
		(Level.Game.IsA('MonsterHunt') && !P.IsA('ScriptedPawn')) || P==Instigator) && 
		P.Health < Class'NWMutator'.default.MaxHealth)
		{
			P.Health += damageScale * DamageAmount * FMax(1.0,MoreDamage);
			if (P.Health > Class'NWMutator'.default.MaxHealth)
				P.Health = Class'NWMutator'.default.MaxHealth;
		}
		else
		{
        	if( Victims != self )
        	{
         	   Victims.TakeDamage(
                	damageScale * DamageAmount,
                	Instigator, 
			Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,
			(damageScale * Momentum * dir),
			DamageName
			);
        	}
	}
		
	}
	else
	{
        if( Victims != self )
        {
            dir = Victims.Location - HitLocation;
            dist = FMax(1,VSize(dir));
            dir = dir/dist; 
            damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);
            Victims.TakeDamage
            (
                damageScale * DamageAmount,
                Instigator, 
                Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,
                (damageScale * Momentum * dir),
                DamageName
            );
        }
	}
    }

    bHurtEntry = false;
}
//******************************************************************************************************************


auto state Flying
{

    simulated function ZoneChange( Zoneinfo NewZone )
    {
	local Pawn P;
	local int ElecDamage;

        if (NewZone.bWaterZone)
	{
		if (Role == ROLE_Authority)
		{
		ForEach RadiusActors( Class'Pawn', P, 500)
		{
			ElecDamage = (VSize(P.Location - Location) - 500) / -1;

			if (P.Region.Zone == NewZone)
			{
				if (HealthGiver)
				{
				If (((P.PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team && Level.Game.IsA('TeamGamePlus') && !Level.Game.IsA('MonsterHunt')) ||
				(Level.Game.IsA('MonsterHunt') && !P.IsA('ScriptedPawn')) || P == Instigator)  && P.Health < Class'NWMutator'.default.MaxHealth)
				{
					P.Health += ElecDamage * FMax(1.0,MoreDamage);
					if (P.Health > Class'NWMutator'.default.MaxHealth)
						P.Health = Class'NWMutator'.default.MaxHealth;
				}
				}

				if ((HealthGiver && P != Instigator) || !HealthGiver)
					P.TakeDamage( ElecDamage * FMax(1.0,MoreDamage), Instigator, P.Location, vect(0,0,0), 'Electrified');
			}
		}
		}

		PlaySound (Sound'AmbOutside.OneShot.lightn12', SLOT_Interface, 255.0, True, 50000.0);
		PlaySound (Sound'AmbOutside.OneShot.lightn12', SLOT_None, 255.0, True, 50000.0);
		PlaySound (Sound'AmbOutside.OneShot.lightn12', SLOT_Misc, 255.0, True, 50000.0);
		PlaySound (Sound'AmbOutside.OneShot.lightn12', SLOT_Talk, 255.0, True, 50000.0);

		Spawn(Class'X_ElectricZoned',,, Location);

		ClientFlashes();

		Destroy();
	}
    }


    simulated function ProcessTouch (Actor Other, Vector HitLocation)
    {
	if ((bCanHitOwner || Other != Instigator) && (!Other.IsA('Projectile') || Other.bProjTarget) && Other!=Level)
		Explode(HitLocation, vect(0,0,1));
    }

    function BlowUp(vector HitLocation)
    {
        HurtRadiusX(Damage * FMax(1.0,MoreDamage), 150 * FMax(1.0, Splasher), MyDamageType, MomentumTransfer * (KickBack + 1), HitLocation);
        MakeNoise(1.0);
    }

	simulated function Explode(vector HitLocation, vector HitNormal)
    {
	local X_Electric_CorpseOv XOver;
	local EMPNormalExpl ene;
	local X_ParticleExplosion xpe;

	Xover = Spawn(class'X_Electric_CorpseOv',,, Location);
	Xover.EffectRadius = 150 * FMax(1.0, Splasher);

	ene = spawn(class'EMPNormalExpl',,,HitLocation);
	ene.RemoteRole = ROLE_None;

	xpe = spawn(class'X_ParticleExplosionC',,,HitLocation);
	xpe.RemoteRole = ROLE_None;
	
        BlowUp(HitLocation);

        Destroy();
    }

    function BeginState()
    {
        local vector Dir;

        Dir = vector(Rotation);
        Velocity = speed * Dir;
        Acceleration = Dir * 50;


        if (Region.Zone.bWaterZone)
		ZoneChange(Region.Zone);
    }
}



defaultproperties
{
	DrawType=DT_Mesh
	Mesh=BoltEMPProj
	Style=STY_Translucent
	bBounce=False
	RemoteRole=ROLE_SimulatedProxy
	Damage=50
	MaxSpeed=1000.000000
	MomentumTransfer=30000
	MyDamageType="Electrified"
	speed=500.000000
	DrawScale=1.000000
	bUnlit=True
	CollisionHeight=10.000000
	CollisionRadius=10.000000
	SoundVolume=128
	SoundRadius=80
	AmbientSound=BoltEMPLoop
	ScaleGlow=3.000000
	bFixedRotationDir=True
	RotationRate=(Pitch=160000,Yaw=160000)
	LightBrightness=100
	LightHue=168
	LightSaturation=68
	LightEffect=LE_FireWaver
	LightRadius=4
	LightType=LT_Steady
	bProjTarget=True
	ExplosionDecal=Class'EMPImpact'
	bNetTemporary=False
}
