//=============================================================================
// Jetpack.
// Revised by AnthraX & Scarface (Shiva)
//=============================================================================
class Jetpack extends TournamentPickup
    config;

#exec OBJ LOAD File=Extro.uax

/*--- Data. -----------------------------------------------------------------*/

var() float         MaxFuel,
                    RechargeRate,
                    Thrust,
                    MaxVel,
                    HorizThrust,
                    MaxHorizVel,
                    ThrustFrequency;
var float           Fuel;           // Fuel left, measured in seconds
var Effects         Trail;
var bool            SimFall,
                    ClientSim;
var float           ThrustTimer;
var float           OldLTS;	   // TR independent jetpack

var config bool     bNoAutoBind;

var JetpackActor JA;


replication
{
    reliable if ( Role < ROLE_Authority )
        SetJetpack, ToggleJetpack;

    reliable if ( Role == ROLE_Authority )
        ClientSetBind, ClientActivate, ClientDeactivate;

    unreliable if ( Role == ROLE_Authority )
        Trail, Fuel, SimFall, ClientSim, MaxFuel, RechargeRate, Thrust, MaxVel,
        HorizThrust, MaxHorizVel, ThrustFrequency;
}


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


function PostBeginPlay()
{
    Super.PostBeginPlay();
    bAutoActivate = false;
    Fuel = MaxFuel;
    
    
}

function GiveTo(Pawn other)
{
    Super.GiveTo(other);
    if ( Owner == other )
    {
        if ( PlayerPawn(Owner) != None )
        {
            ClientSetBind();
            ClientDeactivate();
        }
        
        JA=spawn(class'JetpackActor',Owner);
        GotoState('DeActivated');
    }
}

/*--- Client Functions. -----------------------------------------------------*/
function AnnounceAll(string sMessage)
{
    local Pawn p;

    for ( p = Level.PawnList; p != None; p = p.nextPawn )
	    if ( (p.bIsPlayer || p.IsA('MessagingSpectator')) &&
          p.PlayerReplicationInfo != None  )
		    p.ClientMessage(sMessage);
}

simulated function ClientSetBind()
{
    local int key;
    local string keyName, bind, bindCaps;
    local PlayerPawn playerOwner;

    playerOwner = PlayerPawn(Owner);
    if ( playerOwner == None || bNoAutoBind )
        return;

    for ( key = 0; key < 255; key++ )
    {
        keyName = playerOwner.ConsoleCommand("KEYNAME"@key);
        bind = playerOwner.ConsoleCommand("KEYBINDING"@keyName);
        bindCaps = Caps(bind);

        if ( Left(bindCaps, 4) == "JUMP" || InStr(bindCaps, " JUMP") != -1 ||
          InStr(bindCaps, "|JUMP") != -1 )
        {
            if ( Left(bindCaps, 10) != "SETJETPACK" &&
              InStr(bindCaps, " SETJETPACK") == -1 &&
              InStr(bindCaps, "|SETJETPACK") == -1 &&
              Left(bindCaps, 13) != "TOGGLEJETPACK" &&
              InStr(bindCaps, " TOGGLEJETPACK") == -1 &&
              InStr(bindCaps, "|TOGGLEJETPACK") == -1 )
            {
                bind = "SetJetpack 1|"$bind$"|OnRelease SetJetpack 0";
                playerOwner.ConsoleCommand("SET INPUT"@keyName@bind);
            }
        }
    }

    SaveConfig();
}




simulated function ClientActivate()
{
    if ( Role == ROLE_Authority )
        return;

    GotoState('Activated');
}

simulated function ClientDeactivate()
{
    if ( Role == ROLE_Authority )
        return;

    GotoState('DeActivated');
}

/*--- Console Functions. ----------------------------------------------------*/

exec function ToggleJetpack()
{
    GotoState('Activated');
}

exec function SetJetpack(bool enabled)
{
    if ( enabled )
        GotoState('Activated');
    else
        GotoState('DeActivated');
}

/*-----------------------------------------------------------------------------
 * STATE Activated.
 * --------------------------------------------------------------------------*/

state Activated
{
    simulated function BeginState()
    {
        local UT_Invisibility inv;
        if ( Role == ROLE_Authority )
        {
            if ( Owner.Physics != PHYS_Falling || Fuel <= 0 )
            {
                GotoState('DeActivated');
                return;
            }

            bActive = true;
            ClientActivate();

            // Effects
	    inv = UT_Invisibility(Pawn(Owner).FindInventoryType(class'UT_Invisibility'));
            if ( Trail == None )
		if ( inv == None || inv.charge < 160)
                	Trail = Spawn(class'JetTrail', Owner);
            if( JA == None )
            {
             JA=spawn(class'JetpackActor',Owner);
            }
            
            if( JA != None )
            {
             JA.FlameOn();
            }
        }
        else
            ThrustTimer = 0;


        // Physics
        if ( PlayerPawn(Owner) != None && SimFall )
            Pawn(Owner).bSimFall = true;
        
        // Timing
        OldLTS = Level.TimeSeconds; // 
        SetTimer(1 / ThrustFrequency, false);
    }


    simulated function EndState()
    {
        local sgSpeed sp;
	sp = sgSpeed(Pawn(Owner).FindInventoryType(class'sgSpeed'));
	if (sp != None)
	{
		sp.GotoState('Activated');
	}
        if ( Role == ROLE_Authority )
        {
            bActive = false;

            ClientDeactivate();

            // Effects
            if ( Trail != None )
            {
                Trail.Destroy();
                Trail = None;
            }

            if( JA == None )
            {
             JA=spawn(class'JetpackActor',Owner);
            }
            
            if( JA != None )
            {
             JA.FlameOff();
            }
        }

        // Physics
        if ( PlayerPawn(Owner) != None )
            Pawn(Owner).bSimFall = false;
    }
    
    simulated function Timer()
    {
        local vector horizVel;
        local rotator rot;
        local sgSpeed sp;
        local float deltatime;
        
        // TR independent jetpack
        deltatime = Level.TimeSeconds - OldLTS;
        OldLTS = Level.TimeSeconds;
        Fuel = FMax(Fuel - deltatime, 0);        

        if ( Role == ROLE_Authority &&
          (Owner.Physics != PHYS_Falling || Fuel <= 0) )
        {
            GotoState('DeActivated');
            return;
        }

	sp = sgSpeed(Pawn(Owner).FindInventoryType(class'sgSpeed'));
	if (sp != None)
	{
		sp.GotoState('DeActivated');
	}

        horizVel = Owner.Velocity;
        horizVel.Z = 0;
        rot.Yaw = Owner.Rotation.Yaw;
        if ( cos((rotator(horizVel).Yaw - rot.Yaw)/32768*pi) *
          VSize(horizVel) < MaxHorizVel )
            Owner.Velocity += vector(rot) * HorizThrust * 1 / ThrustFrequency;

        if ( Owner.Velocity.Z < MaxVel )
            Owner.Velocity.Z = FMin(Owner.Velocity.Z + Thrust *
              1 / ThrustFrequency, MaxVel);

        SetTimer(1 / ThrustFrequency, false);
    }

    exec function ToggleJetpack()
    {
        GotoState('DeActivated');
    }



}

/*-----------------------------------------------------------------------------
 * STATE DeActivated.
 * --------------------------------------------------------------------------*/

state DeActivated
{
    //  TR independent jetpack
    simulated function BeginState()
    {
        OldLTS = Level.TimeSeconds;
        SetTimer(1 / 20.0, true); // 'Emulates' 20 TR
    }
    
    simulated function Timer()
    {
        local float deltatime;
	        
	// TR independent jetpack
	deltatime = Level.TimeSeconds - OldLTS;
	OldLTS = Level.TimeSeconds;
        Fuel = FMin(Fuel + RechargeRate * deltaTime, MaxFuel);
    }      
}

defaultproperties
{
    MaxFuel=3.00
    RechargeRate=0.80
    Thrust=1500.00
    MaxVel=350.00
    HorizThrust=250.00
    MaxHorizVel=400.00
    ThrustFrequency=20.00
    ClientSim=True
    bActivatable=True
    bDisplayableInv=True
    PickupMessage="You got the Jetpack."
    ItemName="Jetpack"
    RespawnTime=60.00
    PickupViewMesh=LodMesh'UnrealI.AsbSuit'
    ProtectionType1=ProtectNone
    ProtectionType2=ProtectNone
    Charge=150
    MaxDesireability=3.00
    PickupSound=Sound'UnrealI.Pickups.FieldSnd'
    Icon=Texture'SiegeUltimateRC7UB01Media.U.realShare.Icons.I_ShieldBelt'
    bOwnerNoSee=True
    bTrailerSameRotation=True
    Mesh=LodMesh'Botpack.ShieldBeltMeshM'
    bGameRelevant=True
    CollisionRadius=25.00
    CollisionHeight=10.00
}
