Script:Files:script/projectiles/homingmissile.script

From Mod Wiki
/***********************************************************************

projectile_homingmissile.script

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

object projectile_homingmissile : projectile_missile {
    void        preinit();
    void        init();
    void        Idle();
    void        destroy();
    void        OnSetEnemy( entity oldEnemy, entity newEnemy );
    void        UpdateFocusedTargeting();
    void        vSetNewTarget( entity newTarget );
    entity        vGetCurrentTarget();

    void        OnUpdateTargeting();
    void        OnThrustStarted();

    void        syncFields();

    float        spawnTime;
};

void projectile_homingmissile::OnThrustStarted() {
    playEffect( "fx_trail", "", 1 );
    startSound( "snd_fly", SND_WEAPON_FIRE );
}

void projectile_homingmissile::preinit() {
    if ( !sys.isClient() ) {
        spawnTime = sys.getTime();
    }
}

void projectile_homingmissile::syncFields() {
    syncBroadcast( "spawnTime" );
}

void projectile_homingmissile::init() {
    SetupContents();

    setState( "Idle" );
}

void projectile_homingmissile::destroy() {
    setEnemy( $null_entity );
}

void projectile_homingmissile::Idle() {
    startSound( "snd_release", SND_WEAPON_BRASS );
}

void projectile_homingmissile::OnSetEnemy( entity oldEnemy, entity newEnemy ) {
    if ( oldEnemy != $null_entity ) {
        oldEnemy.vStopTargetLockAlarm( self );
    }

    if ( newEnemy != $null_entity ) {
        newEnemy.vTargetLockAlarm( self );
    }
}

void projectile_homingmissile::UpdateFocusedTargeting() {
}

void projectile_homingmissile::OnUpdateTargeting() {
    entity enemy = getEnemy();

    vector enemyOrg;
    vector dir;

    if ( enemy == $null_entity ) {
        UpdateFocusedTargeting();
        return;
    }

    vector absMins = enemy.getVectorKeyWithDefault( "selection_mins", enemy.getMins() );
    vector absMaxs = enemy.getVectorKeyWithDefault( "selection_maxs", enemy.getMaxs() );
    absMins = sys.toWorldSpace( absMins, enemy );
    absMaxs = sys.toWorldSpace( absMaxs, enemy );
    enemyOrg = ( absMins + absMaxs ) * 0.5f ;

    // lead ahead of the enemy a bit - calculate the time it'll take to get there and adjust
    vector myCurrentVel = getLinearVelocity();
    float myCurrentSpeed = sys.vecLength( myCurrentVel );
    vector delta = enemyOrg - getWorldOrigin(); // adjust for own origin
    float distance = sys.vecLength( delta );
    float approxClosingTime = 1;
    if ( myCurrentSpeed > 0.0001f ) {
        approxClosingTime = distance / myCurrentSpeed;
    }

    // estimate where the enemy will be at that time
    vector enemyCurrentVel = enemy.getLinearVelocity();
    enemyOrg += enemyCurrentVel * approxClosingTime;

    delta = enemyOrg - getWorldOrigin();
    dir = sys.vecNormalize( delta );

    turnTowards( dir, 180.f );
}

void projectile_homingmissile::vSetNewTarget( entity newTarget ) {
    setEnemy( newTarget );
}

entity projectile_homingmissile::vGetCurrentTarget() {
    return getEnemy();
}