class TriOrb expands Projectile;

#exec MESH IMPORT MESH=TriOrb ANIVFILE=MODELS\TriOrb_a.3d DATAFILE=MODELS\TriOrb_d.3d X=0 Y=0 Z=0
#exec MESH ORIGIN MESH=TriOrb X=0 Y=0 Z=0

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

#exec MESHMAP NEW MESHMAP=TriOrb MESH=TriOrb
#exec MESHMAP SCALE MESHMAP=TriOrb X=0.05 Y=0.05 Z=0.1

#exec TEXTURE IMPORT NAME=OrbitalCorona FILE=CORONAS\OrbitalCorona.bmp GROUP=Coronas FLAGS=2

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


var float Splasher, MoreDamage;
var bool HealthGiver;
var() int GravBoulderOffset;

var GravTrail gravBall;


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

simulated function Destroyed()
{
	if (gravBall != None)
		gravBall.Destroy();

	Super.Destroyed();
}

simulated function PostBeginPlay()
{
	gravBall = Spawn(Class'GravTrail',Self);
	SetTimer(0.1, True);
}

simulated function Timer()
{
local Actor A;
local vector X, Y, Z;

	if (Role == ROLE_Authority)
	{
	ForEach VisibleCollidingActors(Class'Actor', A, 250 * FMax(1.0, Splasher))
	{
		if (A.Tag != 'NoLift' && A != Instigator)
		{
			if (A.IsA('GravBoulder'))
				A.TakeDamage(0, Instigator, A.Location, Normal(Location - A.Location) * 1500, 'Gravity');
			else if (!Level.Game.IsA('MonsterHunt') || (Level.Game.IsA('MonsterHunt') && !A.IsA('Bot') && !A.IsA('PlayerPawn')))
				A.TakeDamage(0, Instigator, A.Location, Normal(Location - A.Location) * (A.Mass/25) * 10000, 'Gravity');

		}
	}

	GetAxes(RotRand(), X, Y, Z);
	Spawn(Class'GravBoulder',,, Location + GravBoulderOffset*FMax(1.0, Splasher)*X + 
	GravBoulderOffset*FMax(1.0, Splasher)*Y + GravBoulderOffset*FMax(1.0, Splasher)*Z, RotRand());
	}
}


auto state Flying
{

    simulated function ProcessTouch (Actor Other, Vector HitLocation)
    {
	If (Other.IsA('Pawn') && HealthGiver)
	{
		If (((Pawn(Other).PlayerReplicationInfo.Team == Instigator.PlayerReplicationInfo.Team && Level.Game.IsA('TeamGamePlus') && !Level.Game.IsA('MonsterHunt')) ||
		(Level.Game.IsA('MonsterHunt') && !Pawn(Other).IsA('ScriptedPawn')) || Pawn(Other) == Instigator) && Pawn(Other).Health < Class'NWMutator'.default.MaxHealth)
		{
			Pawn(Other).Health += Damage * FMax(1.0,MoreDamage);
				if (Pawn(Other).Health > Class'NWMutator'.default.MaxHealth)
					Pawn(Other).Health = Class'NWMutator'.default.MaxHealth;
		}
	}

	If (Other != Instigator)
           Other.TakeDamage(Damage, Instigator, Other.Location, vect(0,0,0), 'Gravity');
    }

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

    simulated function Explode(vector HitLocation, vector HitNormal)
    {
        BlowUp(HitLocation);
	Spawn(Class'GravityExpl');

        Destroy();
    }


    function BeginState()
    {
        local vector Dir;

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


//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;
}
//******************************************************************************************************************


defaultproperties
{
	DrawType=DT_Mesh
	Mesh=TriOrb
	bParticles=True
	Texture=OrbitalCorona
	DrawScale=0.500000
	bFixedRotationDir=True
	RotationRate=(Pitch=25000,Yaw=25000)
	Style=STY_Translucent
	bBounce=False
	RemoteRole=ROLE_SimulatedProxy
	Damage=2000
	MaxSpeed=400.000000
	MomentumTransfer=-500000
	MyDamageType="Gravity"
	speed=220.000000
	bUnlit=True
	SoundVolume=128
	SoundRadius=80
	AmbientSound=GravityProj_Loop
	ScaleGlow=3.000000
	LightBrightness=100
	LightHue=193
	LightSaturation=87
	LightEffect=LE_FireWaver
	LightRadius=6
	LightType=LT_Steady
	ExplosionDecal=Class'GravDecal'
	bNetTemporary=True
	CollisionHeight=10.000000
	CollisionRadius=10.000000
	GravBoulderOffset=120
}
