// Generated by MeshMaker (c) 2001 by Mychaeel <mychaeel@planetunreal.com>

class DoubleSpeed extends TournamentPickup;

#exec obj load file=..\Textures\Liquids.utx package=Liquids

//Model Import
#exec mesh import mesh=DoubleSpeed anivfile=Models\DoubleSpeed_a.3d datafile=Models\DoubleSpeed_d.3d x=0 y=0 z=0 mlod=0
#exec mesh origin mesh=DoubleSpeed x=0 y=0 z=0
#exec mesh sequence mesh=DoubleSpeed seq=All startframe=0 numframes=1

#exec meshmap new meshmap=DoubleSpeed mesh=DoubleSpeed
#exec meshmap scale meshmap=DoubleSpeed x=0.10184 y=0.10184 z=0.20367

//Skins
#exec MESHMAP SETTEXTURE MESHMAP=DoubleSpeed NUM=0 TEXTURE=InvSkin01
#exec MESHMAP SETTEXTURE MESHMAP=DoubleSpeed NUM=1 TEXTURE=UBersSkin00
#exec MESHMAP SETTEXTURE MESHMAP=DoubleSpeed NUM=2 TEXTURE=InvSkin00
#exec MESHMAP SETTEXTURE MESHMAP=DoubleSpeed NUM=3 TEXTURE=InvSkin04
#exec MESHMAP SETTEXTURE MESHMAP=DoubleSpeed NUM=4 TEXTURE=Liquids.liquid4


//-----------------------------------------------------------------------

var int FinalCount;
var() sound WarnSound, EndSound;

var() name WearedOffEvent;
var() name DroppedEvent;
var() name ReActivateEvent;

var bool bDroppedNWaiting;

var() sound GroundSound, UseSound;
var AmbientSTrail ast;

var DoubleSOverA Effect1A, Effect1B;
var DoubleElecFX Effect2;
var DoubleSCoronaV Effect3;

var float EffectTimeCount, RndElecCount;

var name WOEvent[32];
var name DEvent[32];
var name RAEvent[32];

var() byte UseSoundRadius, UseSoundVol;

var bool bHaveSpeedRelic;

var float SpeedFXCount;

replication
{
    reliable if( Role==ROLE_Authority)
	bDroppedNWaiting;
}

simulated function Tick(float DeltaTime)
{
	if (!bHidden && Pawn(Owner) == None && AmbientSound != GroundSound)
		AmbientSound = GroundSound;
	else if (bHidden && AmbientSound == GroundSound)
		AmbientSound = None;

	if (!bHidden)
	{
		if (EffectTimeCount == 0)
		{
			RndElecCount = (6 + Rand(20)) / 10;
			EffectTimeCount += DeltaTime;
			Effect2 = Spawn(Class'DoubleElecFX', Self);
		}
		else if (EffectTimeCount >= RndElecCount)
			EffectTimeCount = 0;
		else
			EffectTimeCount += DeltaTime;
	}

	if ((Region.Zone.bDestructive || Region.Zone.bKillZone || Region.Zone.DamagePerSec > 0) && Pawn(Owner) == None)
	{
		Charge = 0;
		Destroy();
	}
}


simulated function PostBeginPlay()
{
	Effect1A = Spawn(Class'DoubleSOverA', Self);
	Effect1B = Spawn(Class'DoubleSOverB', Self);
	Effect3 = Spawn(Class'DoubleSCoronaV', Self);

	Super.PostBeginPlay();
}


simulated function Destroyed()
{
local Actor A;
local byte bj;

	if (WearedOffEvent != '' && (Charge <= 0 || bDroppedNWaiting))
	{
	ForEach AllActors( class 'Actor', A, WearedOffEvent)
                		A.Trigger( Self, Instigator );

		For (bj=0; bj<32; bj++)
		{
			if (WOEvent[bj] != '')
			{
				ForEach AllActors( class 'Actor', A, WOEvent[bj])
                			A.Trigger( Self, Instigator );
			}
		}
	}

	if (DroppedEvent != '' && Charge > 0 && Pawn(Owner)!=None)
	{
	ForEach AllActors( class 'Actor', A, DroppedEvent)
                		A.Trigger( Self, Instigator );

		For (bj=0; bj<32; bj++)
		{
			if (DEvent[bj] != '')
			{
				ForEach AllActors( class 'Actor', A, DEvent[bj])
                			A.Trigger( Self, Instigator );
			}
		}
	}

	if (Effect1A != None)
		Effect1A.Destroy();
	if (Effect1B != None)
		Effect1B.Destroy();
	if (Effect2 != None)
		Effect2.Destroy();
	if (Effect3 != None)
		Effect3.Destroy();

	if (ast != None)
		ast.Destroy();

	if (Charge > 0 && !bDroppedNWaiting)
		DropACopy();

	if (Pawn(Owner) == None && !bHidden)
		Level.Game.PlaySpawnEffect(Self);

	Super.Destroyed();
}

function DropACopy()
{
local DoubleSpeed BS;
local vector PossibleLoc, HitLocation, HitNormal;
local actor AT;
local byte bj;

	PossibleLoc = Pawn(Owner).Location + (Rand(128) - 64)*vect(1,0,0) + (Rand(128) - 64)*vect(0,1,0);
	AT = Trace (HitLocation, HitNormal, PossibleLoc, Pawn(Owner).Location, False);

	if (AT == None)
		BS = Spawn(Class'DoubleSpeed', None,, PossibleLoc, Rand(32768) * rot(0,1,0));
	else
		BS = Spawn(Class'DoubleSpeed', None,, Pawn(Owner).Location, Rand(32768) * rot(0,1,0));

	BS.bDroppedNWaiting = True;
	BS.Charge = Charge;
	BS.Event = Event;
	BS.WearedOffEvent = WearedOffEvent;
	BS.SetPhysics(PHYS_Falling);
	BS.bRotatingPickup = False;
	BS.RotationRate = rot(0,0,0);
	BS.Tag = Tag;
	BS.bFixedRotationDir = False;
	BS.ReActivateEvent = ReActivateEvent;
	BS.DroppedEvent = DroppedEvent;
	BS.LifeSpan = 20.0;

	For (bj=0; bj<32; bj++)
	{
		BS.WOEvent[bj] = WOEvent[bj];
		BS.DEvent[bj] = DEvent[bj];
		BS.RAEvent[bj] = RAEvent[bj];
	}
}

function inventory SpawnCopy( pawn Other )
{
    local inventory Copy;

    if( Level.Game.ShouldRespawn(self) && !bDroppedNWaiting)
    {
        Copy = spawn(Class,Other,,,rot(0,0,0));
        Copy.Tag           = Tag;
        Copy.Event         = Event;
        GotoState('Sleeping');
    }
    else
        Copy = self;

    Copy.RespawnTime = 0.0;
    Copy.bHeldItem = true;
	DoubleSpeed(Copy).WearedOffEvent = WearedOffEvent;
	DoubleSpeed(Copy).DroppedEvent = DroppedEvent;
	DoubleSpeed(Copy).ReActivateEvent = ReActivateEvent;
    Copy.Charge = Charge;
    Copy.GiveTo( Other );
    return Copy;
}


function bool HandlePickupQuery( inventory Item )
{
local byte bj, bi;
local bool bHaveThisEventReg;
local Inventory Inv;

    if (item.class == class) 
    {
        if ( Charge < 999 )  
	{
                Charge += Item.Charge;
		if (Charge > 999)
			Charge = 999;

		//Events management
		///////////////////////////////////////////////////////////

		if (WearedOffEvent == '')
			WearedOffEvent = DoubleSpeed(Item).WearedOffEvent;
		if (DroppedEvent == '')
			DroppedEvent = DoubleSpeed(Item).DroppedEvent;

		if (WearedOffEvent != DoubleSpeed(Item).WearedOffEvent)
		{
			bHaveThisEventReg = False;
			For (bj=0; bj<32; bj++)
			{
				if (WOEvent[bj] == DoubleSpeed(Item).WearedOffEvent)
				{
					bHaveThisEventReg = True;
					break;
				}
			}

			if (!bHaveThisEventReg)
			{
				For (bj=0; bj<32; bj++)
				{
					if (WOEvent[bj] == '')
					{
						WOEvent[bj] = DoubleSpeed(Item).WearedOffEvent;
						break;
					}
				}
			}
		}

		if (DroppedEvent != DoubleSpeed(Item).DroppedEvent)
		{
			bHaveThisEventReg = False;
			For (bj=0; bj<32; bj++)
			{
				if (DEvent[bj] == DoubleSpeed(Item).DroppedEvent)
				{
					bHaveThisEventReg = True;
					break;
				}
			}

			if (!bHaveThisEventReg)
			{
				For (bj=0; bj<32; bj++)
				{
					if (DEvent[bj] == '')
					{
						DEvent[bj] = DoubleSpeed(Item).DroppedEvent;
						break;
					}
				}
			}
		}

		if (ReActivateEvent != DoubleSpeed(Item).ReActivateEvent)
		{
			bHaveThisEventReg = False;
			For (bj=0; bj<32; bj++)
			{
				if (RAEvent[bj] == DoubleSpeed(Item).ReActivateEvent)
				{
					bHaveThisEventReg = True;
					break;
				}
			}

			if (!bHaveThisEventReg)
			{
				For (bj=0; bj<32; bj++)
				{
					if (RAEvent[bj] == '')
					{
						RAEvent[bj] = DoubleSpeed(Item).ReActivateEvent;
						break;
					}
				}
			}
		}

		For (bj=0; bj<32; bj++)
		{
			if (DoubleSpeed(Item).WOEvent[bj] != '')
			{
				bHaveThisEventReg = False;
				For (bi=0; bi<32; bi++)
				{
					if (DoubleSpeed(Item).WOEvent[bj] == WOEvent[bi])
					{
						bHaveThisEventReg = True;
						break;
					}
				}

				
				if (!bHaveThisEventReg)
				{
					For (bi=0; bi<32; bi++)
					{
						if (WOEvent[bi] == '')
						{
							WOEvent[bi] = DoubleSpeed(Item).WOEvent[bj];
							break;
						}
					}
				}
				
			}
			else
				break;
		}


		For (bj=0; bj<32; bj++)
		{
			if (DoubleSpeed(Item).DEvent[bj] != '')
			{
				bHaveThisEventReg = False;
				For (bi=0; bi<32; bi++)
				{
					if (DoubleSpeed(Item).DEvent[bj] == DEvent[bi])
					{
						bHaveThisEventReg = True;
						break;
					}
				}

				
				if (!bHaveThisEventReg)
				{
					For (bi=0; bi<32; bi++)
					{
						if (DEvent[bi] == '')
						{
							DEvent[bi] = DoubleSpeed(Item).DEvent[bj];
							break;
						}
					}
				}
				
			}
			else
				break;
		}

		For (bj=0; bj<32; bj++)
		{
			if (DoubleSpeed(Item).RAEvent[bj] != '')
			{
				bHaveThisEventReg = False;
				For (bi=0; bi<32; bi++)
				{
					if (DoubleSpeed(Item).RAEvent[bj] == RAEvent[bi])
					{
						bHaveThisEventReg = True;
						break;
					}
				}

				
				if (!bHaveThisEventReg)
				{
					For (bi=0; bi<32; bi++)
					{
						if (RAEvent[bi] == '')
						{
							RAEvent[bi] = DoubleSpeed(Item).RAEvent[bj];
							break;
						}
					}
				}
				
			}
			else
				break;
		}
			

		if (Event == '')
			Event = DoubleSpeed(Item).Event;
		////////////////////////////////////////////////////////////////////////////////////
	}
            if (Level.Game.LocalLog != None)
                Level.Game.LocalLog.LogPickup(Item, Pawn(Owner));
            if (Level.Game.WorldLog != None)
                Level.Game.WorldLog.LogPickup(Item, Pawn(Owner));
            if ( Item.PickupMessageClass == None )
                Pawn(Owner).ClientMessage(item.PickupMessage, 'Pickup');
            else
                Pawn(Owner).ReceiveLocalizedMessage( item.PickupMessageClass, 0, None, None, item.Class );
            Item.PlaySound (item.PickupSound,,2.0);
            Item.SetReSpawn();

        return true;        
    }

    if ( Inventory == None )
        return false;

    return Inventory.HandlePickupQuery(Item);
}


singular function UsedUp()
{
local float SpeedScale;

	bActive = False;

 	if ( Level.Game.IsA('DeathMatchPlus') && DeathMatchPlus(Level.Game).bMegaSpeed )
            SpeedScale = 1.3;
        else
            SpeedScale = 1.0;


	// Restore player's stats.
        Pawn(Owner).AirControl = DeathMatchPlus(Level.Game).AirControl;
        Pawn(Owner).JumpZ = Pawn(Owner).Default.JumpZ * Level.Game.PlayerJumpZScaling();
        Pawn(Owner).GroundSpeed = Pawn(Owner).Default.GroundSpeed * SpeedScale;
        Pawn(Owner).WaterSpeed = Pawn(Owner).Default.WaterSpeed * SpeedScale;
        Pawn(Owner).AirSpeed = Pawn(Owner).Default.AirSpeed * SpeedScale;
        Pawn(Owner).Acceleration = Pawn(Owner).Default.Acceleration * SpeedScale;

	if (bHaveSpeedRelic && !Pawn(Owner).bHidden && Pawn(Owner).Health > 0)
	{
		Pawn(Owner).AirControl = 0.65;
        	Pawn(Owner).JumpZ *= 1.1;
        	Pawn(Owner).GroundSpeed *= 1.3;
        	Pawn(Owner).WaterSpeed *= 1.3;
        	Pawn(Owner).AirSpeed *= 1.3;
        	Pawn(Owner).Acceleration *= 1.3;
	}

	if (Pawn(Owner).FindInventoryType(Class'UBersJumpBoots') != None)
	{
		Pawn(Owner).AirControl = 1.0;
    		Pawn(Owner).JumpZ = Pawn(Owner).Default.JumpZ * 3;
	}
	


	if ( Owner != None )
	{
		if (Level.Game.LocalLog != None)
			Level.Game.LocalLog.LogItemDeactivate(Self, Pawn(Owner));
		if (Level.Game.WorldLog != None)
			Level.Game.WorldLog.LogItemDeactivate(Self, Pawn(Owner));
	}

	Destroy();
}

simulated function SpawnAS()
{
	ast = Spawn(Class'AmbientSTrail', Pawn(Owner));
	ast.AmbientSound = UseSound;
	ast.SoundRadius = UseSoundRadius;
	ast.SoundVolume = UseSoundVol;
}


//
// Player has activated the item, duplicate fire rate.
//
state Activated
{

	function Timer()
	{
	local float SpeedScale;

		Charge--;

		if (Pawn(Owner).AirControl == 0.65 && DeathMatchPlus(Level.Game).AirControl != 0.65)
		{
			if ( Level.Game.IsA('DeathMatchPlus') && DeathMatchPlus(Level.Game).bMegaSpeed )
            			SpeedScale = 1.3;
       			else
            			SpeedScale = 1.0;

			// Restore player's stats.
        		Pawn(Owner).AirControl = DeathMatchPlus(Level.Game).AirControl;
        		Pawn(Owner).JumpZ = Pawn(Owner).Default.JumpZ * Level.Game.PlayerJumpZScaling();
        		Pawn(Owner).GroundSpeed = Pawn(Owner).Default.GroundSpeed * SpeedScale;
        		Pawn(Owner).WaterSpeed = Pawn(Owner).Default.WaterSpeed * SpeedScale;
        		Pawn(Owner).AirSpeed = Pawn(Owner).Default.AirSpeed * SpeedScale;
        		Pawn(Owner).Acceleration = Pawn(Owner).Default.Acceleration * SpeedScale;

			// Alter player's stats.
			Pawn(Owner).AirControl = 0.8;
			Pawn(Owner).JumpZ *= 1.3;
			Pawn(Owner).GroundSpeed *= 2.0;
			Pawn(Owner).WaterSpeed *= 2.0;
			Pawn(Owner).AirSpeed *= 2.0;
			Pawn(Owner).Acceleration *= 2.0;

			if (Pawn(Owner).FindInventoryType(Class'UBersJumpBoots') != None)
			{
				Pawn(Owner).AirControl = 1.0;
    				Pawn(Owner).JumpZ = Pawn(Owner).Default.JumpZ * 3 * 1.3;
			}

			bHaveSpeedRelic = True;
		}

		if (Pawn(Owner).FindInventoryType(Class'UBersJumpBoots') != None && Pawn(Owner).AirControl != 1.0)
		{
			Pawn(Owner).AirControl = 1.0;
    			Pawn(Owner).JumpZ = Pawn(Owner).Default.JumpZ * 3 * 1.3;
		}

		if (Charge <= FinalCount && Charge>0)
		{
			SetTimer(0.7, False);
			Owner.PlaySound(WarnSound,, 8);
		}
		else if (Charge <= 0)
		{
			Owner.PlaySound(EndSound,, 8);
			UsedUp();
		}
		else
			SetTimer(1.0, False);
	}

	function EndState()
	{
		UsedUp();
	}

	simulated function Tick( float DeltaTime)
	{
	local vector X, Y, Z, FXLoc1, FXLoc2;

		if ((Pawn(Owner).FindInventoryType(Class'UBerseker') != None || Pawn(Owner).FindInventoryType(Class'UbersUDamage') != None || Pawn(Owner).FindInventoryType(Class'UbersInvisibility') != None) && ast!=None)
		{
			ast.Destroy();
			ast = None;
		}
		else if (ast==None && (Pawn(Owner).FindInventoryType(Class'UBerseker') == None && Pawn(Owner).FindInventoryType(Class'UbersUDamage') == None && Pawn(Owner).FindInventoryType(Class'UbersInvisibility') == None))
		{
			ast = Spawn(Class'AmbientSTrail', Pawn(Owner));
			ast.AmbientSound = UseSound;
			ast.SoundRadius = UseSoundRadius;
			ast.SoundVolume = UseSoundVol;
		}

		if (Role == ROLE_Authority)
		{
			if ((SpeedFXCount >= 0.025 && Pawn(Owner).FindInventoryType(Class'UBersInvisibility')==None) || 
			(SpeedFXCount >= 0.5 && Pawn(Owner).FindInventoryType(Class'UBersInvisibility')!=None))
			{
				SpeedFXCount = 0;

			if (Level.Game.IsA('TeamGamePlus'))
			{
				GetAxes(Pawn(Owner).Rotation, X, Y, Z);
				FXLoc1 = Pawn(Owner).Location - (Pawn(Owner).CollisionHeight-8)*Z + (Pawn(Owner).CollisionRadius-9)*Y;
				FXLoc2 = Pawn(Owner).Location - (Pawn(Owner).CollisionHeight-8)*Z - (Pawn(Owner).CollisionRadius-9)*Y;

				if (Pawn(Owner).PlayerReplicationInfo.Team == 0)
				{
					Spawn(Class'SpeedFXRed',,, FXLoc1);
					Spawn(Class'SpeedFXRed',,, FXLoc2);
				}
				else if (Pawn(Owner).PlayerReplicationInfo.Team == 1)
				{
					Spawn(Class'SpeedFXBlue',,, FXLoc1);
					Spawn(Class'SpeedFXBlue',,, FXLoc2);
				}
				else if (Pawn(Owner).PlayerReplicationInfo.Team == 2)
				{
					Spawn(Class'SpeedFXGreen',,, FXLoc1);
					Spawn(Class'SpeedFXGreen',,, FXLoc2);
				}
				else
				{
					Spawn(Class'SpeedFX',,, FXLoc1);
					Spawn(Class'SpeedFX',,, FXLoc2);
				}
				
			}
			else
			{
				GetAxes(Pawn(Owner).Rotation, X, Y, Z);
				FXLoc1 = Pawn(Owner).Location - (Pawn(Owner).CollisionHeight-8)*Z + (Pawn(Owner).CollisionRadius-9)*Y;
				FXLoc2 = Pawn(Owner).Location - (Pawn(Owner).CollisionHeight-8)*Z - (Pawn(Owner).CollisionRadius-9)*Y;

				Spawn(Class'SpeedFX',,, FXLoc1);
				Spawn(Class'SpeedFX',,, FXLoc2);
			}

			}
			else
				SpeedFXCount += DeltaTime;
				
		}
	}

	function BeginState()
	{
	local Inventory Inv;
	local Actor A;
	local byte bj;
	local float SpeedScale;

		SpawnAS();
		LifeSpan = 0.0;

		bActive = true;
		FinalCount = Min(FinalCount, Charge - 1);
		SetTimer(1.0,false);
		Owner.PlaySound(ActivateSound);	
		AmbientSound = None;


		if (Pawn(Owner).JumpZ == Pawn(Owner).Default.JumpZ * Level.Game.PlayerJumpZScaling() * 1.3)
		{ 
			if ( Level.Game.IsA('DeathMatchPlus') && DeathMatchPlus(Level.Game).bMegaSpeed )
            			SpeedScale = 1.3;
       			else
            			SpeedScale = 1.0;

			// Restore player's stats.
        		Pawn(Owner).AirControl = DeathMatchPlus(Level.Game).AirControl;
        		Pawn(Owner).JumpZ = Pawn(Owner).Default.JumpZ * Level.Game.PlayerJumpZScaling();
        		Pawn(Owner).GroundSpeed = Pawn(Owner).Default.GroundSpeed * SpeedScale;
        		Pawn(Owner).WaterSpeed = Pawn(Owner).Default.WaterSpeed * SpeedScale;
        		Pawn(Owner).AirSpeed = Pawn(Owner).Default.AirSpeed * SpeedScale;
        		Pawn(Owner).Acceleration = Pawn(Owner).Default.Acceleration * SpeedScale;

			bHaveSpeedRelic = True;
		}

		// Alter player's stats.
		Pawn(Owner).AirControl = 0.8;
		Pawn(Owner).JumpZ *= 1.3;
		Pawn(Owner).GroundSpeed *= 2.0;
		Pawn(Owner).WaterSpeed *= 2.0;
		Pawn(Owner).AirSpeed *= 2.0;
		Pawn(Owner).Acceleration *= 2.0;

		if (Pawn(Owner).FindInventoryType(Class'UBersJumpBoots') != None)
		{
			Pawn(Owner).AirControl = 1.0;
    			Pawn(Owner).JumpZ = Pawn(Owner).Default.JumpZ * 3 * 1.3;
		}


		if (ReActivateEvent != '' && bDroppedNWaiting)
		{
			ForEach AllActors( class 'Actor', A, ReActivateEvent)
                		A.Trigger( Self, Instigator );

		For (bj=0; bj<32; bj++)
		{
			if (RAEvent[bj] != '')
			{
				ForEach AllActors( class 'Actor', A, RAEvent[bj])
                			A.Trigger( Self, Instigator );
			}
		}

		}

		bDroppedNWaiting = False;
	}
}


State Sleeping
{
    ignores Touch;

    function BeginState()
    {
        BecomePickup();
        bHidden = true;
    }
    function EndState()
    {
        local int i;

        bSleepTouch = false;
        for ( i=0; i<4; i++ )
            if ( (Touching[i] != None) && Touching[i].IsA('Pawn') )
                bSleepTouch = true;
    }           
Begin:
    Sleep( ReSpawnTime ); 
    Sleep( XPlaySpawnEffect(self) );
    GoToState( 'Pickup' );
}


function float XPlaySpawnEffect(inventory Inv)
{
    spawn(class 'EnhancedReSpawnX',Inv,, Inv.Location );
    return 0.3;
}

defaultproperties
{
	DrawType=DT_Mesh
	Mesh=DoubleSpeed
	PickupViewMesh=DoubleSpeed
	CollisionRadius=15.000000
	CollisionHeight=26.000000
	RespawnSound=InvisibiltyRespawn
	FinalCount=4
	bMeshEnviroMap=False
	WarnSound=InvulnerableWarn
	EndSound=InvulnerableEnd
	PickupMessage="DOUBLE SPEED"
	PickupSound=InvisibilityPickup
	RespawnTime=82.000000
	bRotatingPickup=True
	RotationRate=(Yaw=30000)
	bAutoActivate=True
	Charge=30
	bActivatable=True
	bDisplayableInv=True
	MaxDesireability=4.000000
	SoundVolume=125
	SoundRadius=45
	GroundSound=Invis_GroundLoop
	UseSound=Invul_PowerLoop
	UseSoundRadius=20
	UseSoundVol=255
}
