class GravBeam expands Projectile;

#exec MESH IMPORT MESH=GravBeam ANIVFILE=MODELS\GravBeam_a.3d DATAFILE=MODELS\GravBeam_d.3d X=0 Y=0 Z=0
#exec MESH LODPARAMS MESH=GravBeam STRENGTH=0
#exec MESH ORIGIN MESH=GravBeam X=-400 Y=0 Z=0

#exec MESH SEQUENCE MESH=GravBeam SEQ=All STARTFRAME=0 NUMFRAMES=25
#exec MESH SEQUENCE MESH=GravBeam SEQ=Still STARTFRAME=0 NUMFRAMES=1
#exec MESH SEQUENCE MESH=GravBeam SEQ=Rotating STARTFRAME=0 NUMFRAMES=25 RATE=50.0

#exec MESHMAP NEW MESHMAP=GravBeam MESH=GravBeam
#exec MESHMAP SCALE MESHMAP=GravBeam X=0.15 Y=0.04 Z=0.08

#exec TEXTURE IMPORT NAME=GravBeam FILE=EFFECTS\GravBeam.bmp GROUP=Effects FLAGS=2
#exec MESHMAP SETTEXTURE MESHMAP=GravBeam NUM=1 TEXTURE=GravBeam

#exec AUDIO IMPORT NAME="Grav_Fire" FILE=SOUNDS\Grav_Fire.wav GROUP="Graviton"



var GravBeam GravityBeam;
var GravityLight WallEffect;
var int Position;
var() vector FireOffset;
var() float BeamSize;
var bool bRight, bCenter;
var Actor DamagedActor, GrabbedGuy;
var bool Grabbed;
var float AccumulatedDamage, LastHitTime, PreviousBeamSize;
var vector VeryOldLocation[2];
var GravityRound GR;


replication
{
	// Things the server should send to the client.
	unreliable if( Role==ROLE_Authority )
		bRight, bCenter;
}


function PostBeginPlay()
{
	Super.PostBeginPlay();
	LoopAnim('Rotating', 0.8);
	SetTimer(0.1, True);
}

simulated function Destroyed()
{
	if ( GravityBeam != None )
		GravityBeam.Destroy();
	if ( WallEffect != None )
		WallEffect.Destroy();
	if ( GR != None)
		GR.Destroy();
	

	if (GrabbedGuy != None)
	{

	Grabbed = False;

	GrabbedGuy.SetBase(None);
			
	if (!GrabbedGuy.IsA('Projectile'))
	{
		if (!GrabbedGuy.Region.Zone.bWaterZone || !GrabbedGuy.IsA('Pawn'))
			GrabbedGuy.SetPhysics(PHYS_Falling);
		else
			GrabbedGuy.SetPhysics(PHYS_Swimming);
	}

	GrabbedGuy.TakeDamage(0, Instigator, GrabbedGuy.Location, 100 * (VeryOldLocation[1] - VeryOldLocation[0]) * (GrabbedGuy.Mass / 50), 'Smashed');

	GrabbedGuy = None;
	}

	Super.Destroyed();

}

simulated function Timer()
{
	if (Grabbed)
	{
		VeryOldLocation[0] = VeryOldLocation[1];
		VeryOldLocation[1] = GrabbedGuy.Location;
	}
}

simulated function CheckBeam(vector X, float DeltaTime)
{
	local actor HitActor;
	local vector HitLocation, HitNormal, LocationOffSet;
	local GravBeam kJi;

	// check to see if hits something, else spawn or orient child

	if (!Grabbed)
	{
		HitActor = Trace(HitLocation, HitNormal, Location + BeamSize * X, Location, true);
		if (HitActor == None)
			HitLocation = Location + BeamSize * X;
	}
	else
	{
		HitActor = GrabbedGuy;
		HitLocation = Location + (BeamSize + WallEffect.DrawScale * 80) * X;
	}


		////////////////////////////////////////////////////////////////////

		if (WallEffect != None)
		{
			if (WallEffect.bDeleteMe || !WallEffect.IsA('GravityBall') )
			{
				WallEffect.Destroy();
				WallEffect = None;
			}
		}

		if (WallEffect == None)
			WallEffect = Spawn(class'GravityLight',,, HitLocation);
		if (WallEffect != None)
			WallEffect.SetLocation(HitLocation);

		if (HitActor == Level)
		{
			
		if ( GravityBeam != None )
		{
			GravityBeam.Destroy();
			GravityBeam = None;
		}
			return;
		}


		/////////////////////////////////////////////////////////////////////

		//Grabbing code
		if (HitActor != None && HitActor != Level)
		{
		if ((HitActor.IsA('Pawn') || HitActor.IsA('Projectile') || HitActor.IsA('Decoration') || HitActor.IsA('Vehicle')) 
	&& !Grabbed && HitActor.Tag != 'NoLift' && !HitActor.bStatic && (HitActor != Instigator || (HitActor == Instigator && 
		Class'NWMutator'.default.bGravitonFlyHack)) && !HitActor.IsA('MegaTonOMFG')){

			Grabbed = True;
			GrabbedGuy = HitActor;
			PreviousBeamSize = BeamSize;

			if (GR == None)
				GR = Spawn(Class'GravityRound', GrabbedGuy,, GrabbedGuy.Location);

		}
		else if (Grabbed == True && Instigator.bAltFire == 1 && !HitActor.bHidden)
		{
			if (!GrabbedGuy.IsA('Projectile'))
				GrabbedGuy.SetPhysics(PHYS_None);

			if (GrabbedGuy != None)	
				GrabbedGuy.SetLocation(HitLocation);
		}
		else if (Grabbed == True && (Instigator.bAltFire == 0 || HitActor.bHidden))
		{
			Grabbed = False;
			
			if ( GR != None)
			{
				GR.Destroy();
				GR = None;
			}

			if (GrabbedGuy != None)
				GrabbedGuy.SetBase(None);
			
			if (!GrabbedGuy.IsA('Projectile'))
			{
			if (!GrabbedGuy.Region.Zone.bWaterZone || !GrabbedGuy.IsA('Pawn'))
				GrabbedGuy.SetPhysics(PHYS_Falling);
			else
				GrabbedGuy.SetPhysics(PHYS_Swimming);
			}

			GrabbedGuy.TakeDamage(0, Instigator, GrabbedGuy.Location, 100 * (VeryOldLocation[1] - VeryOldLocation[0]) * (GrabbedGuy.Mass / 50), 'Smashed');
			
			GrabbedGuy = None;
			
		}

		if (GrabbedGuy != None)
			WallEffect.DrawScale = FMax(GrabbedGuy.CollisionRadius, GrabbedGuy.CollisionHeight) / 128;
		

		/////////////////////////////////////////////////////////////////////
		

		if ( GravityBeam != None )
		{
			GravityBeam.Destroy();
			GravityBeam = None;
		}

		return;

		}
		

	if ( !(Position >= 9) )
	{
		if (WallEffect != None)
		{
			WallEffect.Destroy();
			WallEffect = None;
		}
		if ( GravityBeam == None )
		{
			GravityBeam = Spawn(class'GravBeam',,, Location + BeamSize * X); 
			GravityBeam.Position = Position + 1;
		}
		else
			GravityBeam.UpdateBeam(self, X, DeltaTime);
	}

}

simulated function UpdateBeam(GravBeam ParentBolt, vector Dir, float DeltaTime)
{
	local actor HitActor;
	local vector HitLocation, HitNormal;

	SetLocation(ParentBolt.Location + BeamSize * Dir);
	SetRotation(ParentBolt.Rotation);
	CheckBeam(Dir, DeltaTime);
}




defaultproperties
{
	DrawType=DT_Mesh
	Mesh=GravBeam
	bUnlit=True
	Style=STY_Translucent
	MyDamageType=Smashed
	BeamSize=120.000000
	bUnlit=true
	RemoteRole=ROLE_None
	MaxSpeed=0.000000
	CollisionRadius=00000.000000
	CollisionHeight=00000.000000
	bCollideActors=False
	bCollideWorld=False
	bNetTemporary=False
	bGameRelevant=true
	Physics=PHYS_None
	LifeSpan=60.000000
	Damage=0.000000
	MomentumTransfer=0
	bRight=True
	AmbientSound=Grav_Fire
	SoundRadius=12
	SoundVolume=255
	LightBrightness=100
	LightHue=193
	LightSaturation=87
	LightEffect=LE_FireWaver
	LightRadius=4
	LightType=LT_Steady
	FireOffset=(X=0.000000,Y=8.000000,Z=7.000000)
}
