Script:Files:script/weapons/railgun.script

From Mod Wiki
Revision as of 18:08, 2 November 2007 by Wizz (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
/***********************************************************************

weapon_railgun.script

***********************************************************************/

object weapon_railgun : weapon_clip {
    void        preinit();
    void        init();
    void        destroy();

    void        DoFire();
    void        FireCommon();
    void        OnNetworkTracer( vector start, vector end, float strength );

    void        PlayFireSound();

    void        CreateUpdateEnergy();
    void        KillUpdateEnergy();
    void        UpdateEnergy();
    float        GetEnergy();
    void        ClearEnergy();

    float        GetSoundPitch();

    float        rechargeTime;
    float        energyTimerHandle;

    float        threadId;
};

void weapon_railgun::preinit() {
    hasScope        = true;
    hasScopeZoom    = true;
    hasIronSights    = false;
    usesStroyent    = true;

    fireRateSingle    = getFloatKeyWithDefault( "fire_rate", 0.2f );

    rechargeTime    = getFloatKeyWithDefault( "recharge_time", 2.0f );
    energyTimerHandle = sys.allocTargetTimer( getKeyWithDefault( "timer_energy", "railgun_energy" ) );

    CreateUpdateEnergy();

    threadId = -1;
    if ( sys.getLocalPlayer() == myPlayer ) {
        sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.distance", -2 );
        threadId = thread RangeUpdateThread( myPlayer, 16384 );
    }
}

void weapon_railgun::init() {
    weaponState( "Raise", 0 );
}

void weapon_railgun::destroy() {
    KillUpdateEnergy();

    if ( threadId != -1 ) {
        sys.terminate( threadId );
    }
}

void weapon_railgun::DoFire() {
    if ( !mainFireDown ) {
        FireSingle();
        ClearEnergy();
    }
}

void weapon_railgun::FireCommon() {
    PlayFireEffect();
    PlayFireSound();
    PlayBrassSound();

    if ( myPlayer.IsSniperScopeUp() ) {
        playAnim( ANIMCHANNEL_ALL, "fire_zoom" );
    } else {
        playAnim( ANIMCHANNEL_ALL, "fire" );
    }

    float strength = GetEnergy();
    launchProjectiles( numProjectiles, 0, getCurrentSpread(), 0, 1, strength );
    if ( !sys.isClient() || sys.getLocalPlayer() == myPlayer ) {
        handle effectHandle = getLastTracer();
        if ( effectHandle ) {
            vector color = g_vectorZero;
            // scale the red & green unevenly
            color_x = strength;
            color_y = ( strength - 0.5 ) * 2 + 0.1;
            setEffectColor( effectHandle, color, 1 );

            if ( !sys.isClient() ) {
                // send an unreliable event so clients can show it
                vector start = getEffectOrigin( effectHandle );
                vector end = getEffectEndOrigin( effectHandle );
                sendTracerMessage( start, end, strength );
            }
        }
    }
    increaseSpread();

    UseAmmo_Stroyent( 0 );
    AmmoCheck( 0 );
}

void weapon_railgun::OnNetworkTracer( vector start, vector end, float strength ) {
    if ( sys.getLocalPlayer() != myPlayer ) {
        doProjectileTracer( 0, start, end );
        handle effectHandle = getLastTracer();
        if ( effectHandle ) {
            vector color = g_vectorZero;
            // scale the red & green unevenly
            color_x = strength;
            color_y = ( strength - 0.5 ) * 2 + 0.1;
            setEffectColor( effectHandle, color, 1 );
        }
    }
}

void weapon_railgun::PlayFireSound() {
    startSound( "snd_fire_local", SND_WEAPON_FIRE_LOCAL );
    startSound( "snd_fire", SND_WEAPON_FIRE );
    startSound( "snd_fire_far", SND_WEAPON_FIRE_FAR );
    startSound( "snd_charge", SND_WEAPON_MECH );
}

float weapon_railgun::GetEnergy() {
    float value = sys.getTime() - sys.getTargetTimerValue( energyTimerHandle, myPlayer );
    value = value / rechargeTime;
    if ( value < 0 ) {
        value = 0;
    } else if ( value > 1 ) {
        value = 1;
    }

    return value;
}

void weapon_railgun::ClearEnergy() {
    sys.setTargetTimerValue( energyTimerHandle, myPlayer, sys.getTime() );
}

void weapon_railgun::CreateUpdateEnergy() {
    if ( myPlayer == sys.getLocalPlayer() ) {
        sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.showHeat", 1.f );
    }

    thread UpdateEnergy();
}

void weapon_railgun::KillUpdateEnergy() {
    if ( ShouldRunGuis() ) {
        sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.showHeat", 0.f );
    }

    setChannelPitchShift( SND_WEAPON_IDLE, 1.0f );

    sys.killThread( "UpdateEnergy_" + getName() );
}

void weapon_railgun::UpdateEnergy() {
    boolean isLocal = ShouldRunGuis();
    float soundPitchSpeed = getFloatKeyWithDefault( "recharge_pitch", 1.f );
    float newSoundPitch;

    while ( true ) {
        if ( isLocal ) {
            float energy = GetEnergy();
            sys.setGUIFloat( GUI_GLOBALS_HANDLE, "weapons.heat", energy );
            setChannelPitchShift( SND_WEAPON_IDLE, GetSoundPitch() );
        }

        sys.waitFrame();
    }
}

float weapon_railgun::GetSoundPitch() {
    float energy = GetEnergy();
    return energy;
}