Script:Files:script/items/supplypack.script

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

item_supplypack.script

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

#define SUPPLYPACK_LOWAMMO            4
#define SUPPLYPACK_NUMPROJECTILES    1
#define    SUPPLYPACK_SPREAD            0

// blend times
#define SUPPLYPACK_IDLE_TO_LOWER        2
#define SUPPLYPACK_IDLE_TO_FIRE        1
#define    SUPPLYPACK_IDLE_TO_RELOAD    3
#define SUPPLYPACK_RAISE_TO_IDLE        3
#define SUPPLYPACK_FIRE_TO_IDLE        4
#define SUPPLYPACK_RELOAD_TO_IDLE    4

object item_supplypack : weapon_base {

    float        nextAttack;

    float        baseChargePerUse;

    void        preinit();
    void        init();
    void        destroy();

    void        Raise();
    void        Idle();
    void        Fire();
    void        Reload();

    boolean        AllowSprint();

    void        ToolTipThread_Raise();

    boolean        tipThreadActive;
}

void item_supplypack::preinit() {
    baseChargePerUse = chargePerUse;
}

void item_supplypack::init() {
    if ( myPlayer.isLocalPlayer() ) {
        thread ToolTipThread_Raise();
    }

    nextAttack = 0;

    weaponState( "Raise", 0 );
}

void item_supplypack::destroy() {
}

void item_supplypack::ToolTipThread_Raise() {
    myPlayer.cancelToolTips();
    sys.wait( myPlayer.CalcTooltipWait() );

    WAIT_FOR_TOOLTIP;
    myPlayer.sendToolTip( GetToolTip( getKey( "tt_intro_1" ) ) );

    WAIT_FOR_TOOLTIP;
    myPlayer.sendToolTip( GetToolTip( getKey( "tt_intro_2" ) ) );
}

void item_supplypack::Raise() {
    UpdateCharge();

    Base_Raise();
}

void item_supplypack::Idle() {
    weaponReady();
    playCycle( ANIMCHANNEL_ALL, "idle" );

    StartIdleEffect();

    float weaponReadyTime;

    while( 1 ) {
        if ( WEAPON_LOWERWEAPON ) {
            StopIdleEffect();
            weaponState( "Lower", SUPPLYPACK_IDLE_TO_LOWER );
        }

        if ( WEAPON_ATTACK ) {
            if ( !mainFireDown ) {
                myPlayer.disableSprint( 1.f );
                mainFireDown = true;

                if ( sys.getTime() >= nextAttack ) {
                    if ( CanRemove( chargePerUse ) ) {
                        StopIdleEffect();
                        weaponState( "Fire", SUPPLYPACK_IDLE_TO_FIRE );
                    } else {
                        if ( myPlayer.isLocalPlayer() ) {
                            myPlayer.sendToolTip( GetToolTip( getKey( "tt_need_charge" ) ) );
                            sys.startSoundDirect( getKey( "snd_need_charge" ), SND_ANY );
                            G_NotifyNoCharge( myPlayer );
                        }

                        weaponReloading();
                        weaponReadyTime = sys.getTime() + 2.f;
                    }
                }
            }
        } else {
            mainFireDown = false;
            if ( AllowSprint() ) {
                myPlayer.disableSprint( 0.f );
                if ( myPlayer.AI_SPRINT ) {
                    StopIdleEffect();
                    weaponState( "Sprint", 4 );
                }
            } else {
                myPlayer.disableSprint( 1.f );
            }
        }

        UpdateCharge();

        if ( weaponReadyTime != 0.f ) {
            if ( sys.getTime() > weaponReadyTime ) {
                weaponReady();
                weaponReadyTime = 0.f;
            }
        }

        sys.waitFrame();
    }
}

void item_supplypack::Reload() {
    weaponReloading();
    sys.wait( 0.1f );
    weaponState( "Idle", SUPPLYPACK_RAISE_TO_IDLE );
}

void item_supplypack::Fire() {
    boolean launched;

    Remove( chargePerUse );

    UpdateCharge();

    float launchDelay = sys.getTime() + triggerDelay;
    nextAttack = sys.getTime() + fireRate;

    fired();

    playAnim( ANIMCHANNEL_ALL, "fire" );

    while( !animDone( ANIMCHANNEL_ALL, SUPPLYPACK_FIRE_TO_IDLE ) ) {
        sys.waitFrame();
        if( !launched && ( sys.getTime() > launchDelay ) ) {
            launched = true;

            if ( !sys.isClient() ) {
                entity projectile;
                if ( myPlayer.getProficiency( g_proficiencyFieldOps ) >= 2 && myPlayer.getPlayerClass() == g_playerClassFieldOps ) {
                    projectile = createProjectile( 1 );
                } else {
                    projectile = createProjectile( 0 );
                }
                launchProjectiles( 1, 0, 0.f, 0, 1, 1 );
                projectile.setLinearVelocity( projectile.getLinearVelocity() + myPlayer.getLinearVelocity() );
            }
        }
    }

    weaponState( "Raise", SUPPLYPACK_FIRE_TO_IDLE );
}

boolean item_supplypack::AllowSprint() {
    return sys.getTime() > nextAttack;
}






// fieldops charge reduction
object item_supplypack_fieldops : item_supplypack {
    void        vCheckProficiency();
};

void item_supplypack_fieldops::vCheckProficiency() {
    UpdateCrosshair();
}



// medic charge reduction
object item_supplypack_medic : item_supplypack {
    void        vCheckProficiency();
};

void item_supplypack_medic::vCheckProficiency() {
    if ( myPlayer.getProficiency( g_proficiencyMedic ) >= 1 ) {
        chargePerUse = baseChargePerUse * 0.8f;
    }
    UpdateCrosshair();
}




// medictech charge reduction
object item_supplypack_meditech : item_supplypack {
    void        vCheckProficiency();
};

void item_supplypack_meditech::vCheckProficiency() {
    if ( myPlayer.getProficiency( g_proficiencyTechnician ) >= 1 ) {
        chargePerUse = baseChargePerUse * 0.8f;
    }
    UpdateCrosshair();
}












// actual projectile
object supplypack {
    void                preinit();
    void                init();
    void                destroy();

    void                OnPickup( entity o );

    string                ignoreAbility;
    handle                pickupText;
    boolean                isAmmo;

    float                pickupProficiency;
}

void supplypack::preinit() {
    ignoreAbility        = getKey( "ability_ignore" );
    pickupText            = sys.localizeString( getKey( "text_pickup" ) );
    isAmmo                = getIntKey( "is_ammo" );
    pickupProficiency    = GetProficiency( getKey( "prof_pickup" ) );
}

void supplypack::init() {
    setClipmask( MASK_PROJECTILE );

//mal: let the bots know there is a supply pack out there in the world.
    if ( !sys.isClient() ) {
        entity owner = getOwner();

        if ( owner != $null_entity ) {
            player p = owner;
            if ( p != $null_entity ) {
                p.setPlayerItemState( self, false );
            }
        }
    }
}

void supplypack::destroy() {
//mal: by the time we reach here, any owner info has been destroyed, so we get rid of the owners tracker code side in idItem::~idItem
//mal: we need to do this, else there would be no way to see health packs that expired. 
}

void supplypack::OnPickup( entity o ) {
    player p = o;
    if ( p != $null_entity ) {

        if ( !sys.isClient() ) {
            p.setPlayerItemState( self, true ); //mal: someone picked up the supply pack, let the bots know.
        }

        if ( p.isLocalPlayer() ) {
            // FIXME: localization
            //sys.consoleCommand( "addChatLine \"" + pickupText + "\"\n" );
        }

        if ( isAmmo ) {
            p.OnAmmoPickup();
        }
    }

    entity owner = getOwner();
    if ( owner == $null_entity ) {
        return;
    }

    if ( ignoreAbility != "" ) {
        if ( p.hasAbility( ignoreAbility ) ) {
            return;
        }
    }

    team_base team = getGameTeam();
    if ( team != $null ) {
        string statName = team.getName() + "_supply_uses";    
        sys.increaseStatInt( sys.allocStatInt( statName ), owner.getEntityNumber(), 1 );

        if ( pickupProficiency != -1 ) {
            owner.giveProficiency( pickupProficiency, 1.f, $null, "supply success" );
        }
    }
}