Script:Files:script/maps/generic/scud trigger.script

From Mod Wiki
object scud_trigger : hackable_objective {
    void        syncFields();

    void        OnHacked( entity p );

    void        vSetActive( boolean value );

    boolean        TryFire( entity firer );
    void        FireThread( entity firer );
    void        FireThreadFake();
    void        TrackScud();

    void        vSetTargetEntity( entity ent );
    void        vSetOwner( entity ent );
    void        vStartObjective();

    void        OnActiveChanged();
    void        OnPostMapSpawn();
    void        OnObjectiveIndexChanged();
    void        OnScudChanged();

    void        DestroyTarget( entity targetEnt );
    void        SpawnDestroyEffect( vector position );

    entity        targetEnt;
    entity        owner;
    entity        trackingScud;

    boolean        active;

    boolean        AllowHack() { return active; }
}

void scud_trigger::syncFields() {
    syncBroadcast( "objectiveIndex" );
    syncCallback( "objectiveIndex", "OnObjectiveIndexChanged" );

    syncBroadcast( "trackingScud" );
    syncCallback( "trackingScud", "OnScudChanged" );

    syncBroadcast( "active" );
    syncCallback( "active", "OnActiveChanged" );

    syncBroadcast( "owner" );
}

void scud_trigger::OnObjectiveIndexChanged() {
    SetObjectiveIndex( objectiveIndex );
}

void scud_trigger::OnScudChanged() {
    if ( trackingScud != $null_entity ) {
        thread TrackScud();
    }
}

void scud_trigger::OnPostMapSpawn() {
    // TEMP: for old style shields
    targetEnt = getEntityKey( "target" );
}

void scud_trigger::OnActiveChanged() {
    if ( active ) {
        setShaderParm( 7, 1 );
    } else {
        setShaderParm( 7, 0 );
    }
}

void scud_trigger::vSetActive( boolean value ) {
    if ( active == value ) {
        return;
    }
    active = value;
    OnActiveChanged();
}

void scud_trigger::OnHacked( entity p ) {
    owner.vSetActive( true );
    vSetActive( false );

    object oldTeam = getGameTeam();
    object newTeam = p.getGameTeam();
    setGameTeam( newTeam );

    objManager.OnHackComplete( self );

    if ( p != $null_entity ) {
        string statName = newTeam.getName() + "_primary_objective_hacked";
        sys.increaseStatInt( sys.allocStatInt( statName ), p.getEntityNumber(), 1 );
        statName = newTeam.getName() + "_hack_uses";
        sys.increaseStatInt( sys.allocStatInt( statName ), p.getEntityNumber(), 1 );
    }

    objManager.PlaySound( getKey( "snd_hacked_strogg" ), stroggTeam );
    objManager.PlaySound( getKey( "snd_hacked_gdf" ), gdfTeam );

    thread FireThread( p );
}

boolean scud_trigger::TryFire( entity firer ) {
    // set any MCP up to fire
    if ( G_TryFireScud( firer, targetEnt ) ) {
        return true;
    }

    return false;
}

void scud_trigger::FireThread( entity firer ) {
    sys.wait( 5.f );

    if ( !TryFire( firer ) ) {
        objManager.CPrintEvent( sys.localizeString( "game/misc/shield_generator_hacked_reenable" ), gdfTeam );
        objManager.CPrintEvent( sys.localizeString( "game/misc/shield_generator_hacked_attack" ), stroggTeam );

        while ( true ) {
            if ( TryFire( firer ) ) {
                break;
            }
            sys.wait( 0.2f );
        }
    }

    objManager.PlaySound( getKey( "snd_launched_strogg" ), stroggTeam );
    objManager.PlaySound( getKey( "snd_launched_gdf" ), gdfTeam );
}

void scud_trigger::FireThreadFake() {
    sys.wait( 5.f );

    while ( true ) {
        if ( TryFire( $null_entity ) ) {
            break;
        }
        sys.wait( 0.2f );
    }

    objManager.PlaySound( getKey( "snd_launched_strogg" ), stroggTeam );
    objManager.PlaySound( getKey( "snd_launched_gdf" ), gdfTeam );

    while ( true ) {
        float count = entitiesOfCollection( "nuke" );
        if ( count > 0 ) {
            trackingScud = getBoundsCacheEntity( 0 );
            break;
        }

        sys.waitFrame();
    }

    TrackScud();
}

void scud_trigger::TrackScud() {
    while ( true ) {
        sys.waitFrame();

        if ( trackingScud == $null_entity ) {
            return;
        }

        float range = sys.vecLength( trackingScud.getWorldOrigin() - getWorldOrigin() );

        if ( range > 6144.f ) {
            continue;
        }

        DestroyTarget( trackingScud );

        if ( !sys.isClient() ) {
            objManager.PlaySound( getKey( "snd_stopped_strogg" ), stroggTeam );
            objManager.PlaySound( getKey( "snd_stopped_gdf" ), gdfTeam );

            objManager.OnShieldDestroyedScud( self );
        }

        break;
    }
}

void scud_trigger::DestroyTarget( entity targetEnt ) {
    if ( targetEnt.vGetDestroyed() ) {
        return;
    }

    SpawnDestroyEffect( targetEnt.getWorldOrigin() );
    targetEnt.vSetDestroyed();
}

void scud_trigger::SpawnDestroyEffect( vector position ) {
    vector startPos = owner.getJointPos( owner.getJointHandle( "top_comprezzor_joint" ) ); // start at the roof of the deployable
    vector diff = startPos - position;
    vector forward = '1 0 0';
    diff = sys.vecNormalize( diff );
    vector angles = sys.vecToAngles( diff );

    // Charge up and cool down effect
    owner.playOriginEffect( "fx_charge", "", startPos, forward, false );

    // The electrial beam and shockwave
    object effect = owner.spawnClientEffect( "fx_hit" );
    if ( effect != $null_entity ) {
        effect.setEffectLooping( 0 );
        effect.setOrigin( position );
        effect.setEffectEndOrigin( startPos );
        effect.setAngles( angles );
    }
}

void scud_trigger::vSetOwner( entity ent ) {
    owner = ent;
}

void scud_trigger::vSetTargetEntity( entity ent ) {
    targetEnt = ent;
}

void scud_trigger::vStartObjective() {
    thread FireThreadFake();
}




object scud_trigger_structure {
    void            preinit();
    void            syncFields();

    void            vOnDeploy();
    void            vSetOwner( entity ent );
    void            vSetActive( boolean value );

    void            OnDeadChanged();

    void            BoundsKillThread();

    void            InitEffectThread();

    string            vGetQuickChatString( entity p );

    scud_trigger    triggerEnt;
    entity            targetEnt;
    float            objectiveIndex;

    boolean            dead;

    vector            effectOffset;
}

void scud_trigger_structure::preinit() {
    effectOffset = getVectorKey( "effect_offset" );

    thread InitEffectThread();

    if ( !sys.isClient() ) {
        thread BoundsKillThread();
    }
}

void scud_trigger_structure::syncFields() {
    syncBroadcast( "dead" );
    syncCallback( "dead", "OnDeadChanged" );
}

void scud_trigger_structure::OnDeadChanged() {
    if ( dead ) {
        playAnim( ANIMCHANNEL_ALL, "destroyed" );
        stopEffect( "fx_active" );
    } else {
        playCycle( ANIMCHANNEL_ALL, "idle" );
        playOriginEffect( "fx_active", "", getWorldOrigin() + effectOffset, '1 0 0', true );
    }
}

void scud_trigger_structure::BoundsKillThread() {
    float damageIndex = GetDamage( getKey( "dmg_crush" ) );

    while ( true ) {
        BoundsDamage( self, damageIndex );
        sys.waitFrame();
    }
}

void scud_trigger_structure::vSetActive( boolean value ) {
    if ( dead == value ) {
        return;
    }    
    dead = value;

    OnDeadChanged();
}

void scud_trigger_structure::vOnDeploy() {
    if ( !sys.isClient() ) {
        triggerEnt = sys.spawn( getKey( "def_trigger" ) );
        triggerEnt.setOrigin( getWorldOrigin() );
        triggerEnt.setAngles( getAngles() );
        triggerEnt.setGameTeam( getGameTeam() );
        triggerEnt.vSetTargetEntity( targetEnt );
        triggerEnt.vSetOwner( self );
        triggerEnt.SetObjectiveIndex( objectiveIndex );

        objManager.OnShieldDeployed( self, triggerEnt );

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

    sys.killThread( "InitEffectThread_" + getName() );

    if ( !dead ) {
        playOriginEffect( "fx_active", "", getWorldOrigin() + effectOffset, '1 0 0', true );
    }
}

void scud_trigger_structure::vSetOwner( entity ent ) {
    targetEnt = ent.getEntityKey( "target" );    
    objectiveIndex = ent.getIntKey( "objective_index" );
}

void scud_trigger_structure::InitEffectThread() {
    sys.wait( 5 );
    OnDeadChanged();
}

string scud_trigger_structure::vGetQuickChatString( entity p ) {
    return triggerEnt.vGetQuickChatString( p );
}