Jump to content

A Negative force repulse ...


Recommended Posts

Posted

Hello to all coders.

i am sorry for disturb, but i need a little hint. by alone i not arrive to this.

I am working about some new force powers. they act like the force repulse of Open JA Enhanced, but the difference is that they have different effect and animation to casting, different cost and they making Class Damage and different effect to each classes that be hitted by the shockwave.

for example, there is a power that simply knockback all enemies around the player.

a power that burning enemy with a fire explosion.

another that frost enemies with an ice explosion.

another again that blind the enemies with light explosion and so away.

in totaly i am doing these specific knockback attack:

 

- force

- stone \ earth element (enemy will be stucked )

- sonic (element get sonicpain like affected by howler screams)

- water \ frost (enemy are frosted)

- fire (enemy are burned)

- sun (enemy are blinded, the vampires classes are disintegrated, like the DISRUPTOR MOD_SNIPER letal atk.

- Wind (hard force pushing with damaged)

- Holy (the demonic classes get letal damage and are stunned. the mortal enemies, can fight for players for some second)

- Necro: as holy, but letal for mortals and charming the undeads.

- Dark.

 

i have a trouble with dark.

at level 1, this shockwave emit a darkness cloud that blind all enemies around like confusion level 1-2.

this is very nice to see.

at level 2, the shockwave emit a blow of toxic smoke that blind enemies, and also gasping the mortals. they cannot breath and they take theyr throat with hands, like they are gripped.

level 1 and level 2 works perfectly.

at level 3, i need some little information about how this can work.

at level 3, the player can shoot a black hole.

a black hole appear and suck all enemies.

they get blinding status + chocking status + damage status.

and that's work,.

what i wanna to add to this attack is only one last function:

i wanna that the black one PULLING all enemies around to itself, so enemies should all knockback and falling on player.

basically. it's like the level 3 Force Pull. but it act with a circle radius area, not with a cone.

So i am asking: how can i create the suck AOE function?

 

I post here the Darkglyph code.


casting:

 

void DarkGlyph( gentity_t *self )
{
    
    // Morto non lo casta di certo
    if ( self->health <= 0 )
    {
        return;
    }
    // In cinematic niente glifi!
    if ( !self->s.number && (cg.zoomMode || in_camera) )
    {//can't repulse when zoomed in or in cinematic
        return;
    }
    // Niente glifi in leafing
    if ( self->client->ps.leanofs )
    {//can't repulse while leaning
        return;
    }
    // Costo del potere
    if ( !WP_ForcePowerUsable( self, FP_DARKGLYPH, 50 ) )
    {
        return;
    }

    if ( self->client->ps.weaponTime >= 800 )
    {//just did one!
        return;
    }

    if ( self->client->ps.saberLockTime > level.time )
    {//FIXME: can this be a way to break out?
        return;
    }

    // Non castarlo se è già attivo!
    if ( self->client->ps.repulseChargeStart )
    {
        return;
    }
    // Non castabile in caso di parata.
    if ( self->client->ps.saberLockTime > level.time )
    {//FIXME: can this be a way to break out?
        return;
    }
    // REPEL, CONTROMAGIA E REPEL ARCANO VENGON DISATTIVATI SE LO USI
    // Make sure to turn off Force Protection and Force Absorb.
    if (self->client->ps.forcePowersActive & (1 << FP_PROTECT) )
    {
        WP_ForcePowerStop( self, FP_PROTECT );
    }
    if (self->client->ps.forcePowersActive & (1 << FP_ABSORB) )
    {
        WP_ForcePowerStop( self, FP_ABSORB );
    }

    self->client->ps.repulseChargeStart = level.time;
    // ANIMAZIONE DI CASTING
    NPC_SetAnim( self, SETANIM_TORSO, BOTH_SPINATTACK7, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
    
    self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have been in
    self->client->ps.saberBlocked = BLOCKED_NONE;
    // SUONO DI LOOPING DURANTE IL CASTING.
    G_PlayEffect( G_EffectIndex( "reavers/shadow." ), self->playerModel, self->handRBolt, self->s.number, self->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
    G_PlayEffect( G_EffectIndex( "reavers/shadow" ), self->playerModel, self->handLBolt, self->s.number, self->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
    G_SoundOnEnt( self, CHAN_ITEM, "sound/weapons/shadowclaw/draw.wav" );
    //FIXME: build-up or delay this until in proper part of anim
    self->client->ps.weaponTime = self->client->ps.torsoAnimTimer;
    // CASTATO AL TERMINE DELL'ANIMAZIONE
    WP_ForcePowerStart( self, FP_DARKGLYPH, 1 );
}
 

Damages.

 

void DarkDamage( gentity_t *self, gentity_t *enemy, vec3_t location, int damageLevel7 )
{// DANNO INFLITTO DAL GLIFO A SECONDA DEL LIVELLO DI POTENZA E MOD ELEMENTALE. IL GLIFO DI FORZA NON HA ELEMENTO QUINDI NON HA MOD
    switch (damageLevel7) {
  case FORCE_LEVEL_1:
            G_Damage( enemy, self, self, NULL, location, 0, DAMAGE_NO_KNOCKBACK, MOD_BRYAR );
            break;
  case FORCE_LEVEL_2:
            G_Damage( enemy, self, self, NULL, location, 30, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
            break;
  case FORCE_LEVEL_3:
            G_Damage( enemy, self, self, NULL, location, 50, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
            break;
  default:
            break;
    }
}
 

Now the hard part.

The explosion.

 

void DarkGlyphThrow( gentity_t *self, int chargeTime7 )
{ // CODICE DELL'ONDA D'URTO SONICA!!!!
    //shove things around you away
    qboolean fake = false;
    float        dist;
    gentity_t    *ent, *forwardEnt = NULL;
    gentity_t    *entityList[MAX_GENTITIES];
    gentity_t    *push_list[MAX_GENTITIES];
    int            numListedEntities = 0;
    vec3_t        mins, maxs;
    vec3_t        v;
    int            i, e;
    int            ent_count = 0;
    int            radius;
    vec3_t        center, ent_org, size, forward, right, end, dir, fwdangles = {0};
    trace_t        tr;
    int            anim, hold, soundIndex, cost;
    int            damageLevel7 = FORCE_LEVEL_0;
    qboolean    suck = qtrue;
    
    if ( self->health <= 0 ) // NON la castano i morti
    {
        return;
    }
    if ( self->client->ps.leanofs ) // NON si casta in leaf
    {//can't force-throw while leaning
        return;
    }
    if ( self->client->ps.forcePowerDebounce[FP_DARKGLYPH] > level.time )
    // Non puoi castarla se c'è già un'onda d'urto nella stanza.
    {//already pushing- now you can't haul someone across the room, sorry
        return;
    }
    // X VUOTO
    if ( self->client->ps.pullAttackTime > level.time )
    // Non puoi castarla se stai usando il force pull  
    {//already pushing- now you can't haul someone across the room, sorry
        return;
    }

    // NOn puoi castarla nelle cutscene
    if ( !self->s.number && (cg.zoomMode || in_camera) )
    {//can't force throw/pull when zoomed in or in cinematic
        return;
    }// Non puoi castarla mentre pari un colpo di spada. non sei concentrato.
    if ( self->client->ps.saberLockTime > level.time )
    {
        if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] < FORCE_LEVEL_3 )
        {//this can be a way to break out
            return;
        }
        // A LIVELLO 3 PERO' SI!
        //else, I'm breaking my half of the saberlock
        self->client->ps.saberLockTime = 0;
        self->client->ps.saberLockEnemy = ENTITYNUM_NONE;
    }
    // SE I PERSONAGGI SI STANNO RIALZANDO, L'ONDA NON FUNZIONA ANCORA SU DI LORO. POSSON ESSER SPINTI, NON ALTRO.
    if ( self->client->ps.legsAnim == BOTH_KNOCKDOWN3
        || (self->client->ps.torsoAnim == BOTH_FORCE_GETUP_F1 && self->client->ps.torsoAnimTimer > 400)
        || (self->client->ps.torsoAnim == BOTH_FORCE_GETUP_F2 && self->client->ps.torsoAnimTimer > 900)
        || (self->client->ps.torsoAnim == BOTH_GETUP3 && self->client->ps.torsoAnimTimer > 500)
        || (self->client->ps.torsoAnim == BOTH_GETUP4 && self->client->ps.torsoAnimTimer > 300)
        || (self->client->ps.torsoAnim == BOTH_GETUP5 && self->client->ps.torsoAnimTimer > 500) )
    {//we're face-down, so we'd only be force-push/pulling the floor
        return;
    }
    
    radius = darkglyphRadius[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
    
    if ( !radius )
    {//no ability to do this yet
        return;
    }


    if ( chargeTime7 > 10000.0f )
    {
        damageLevel7 = FORCE_LEVEL_3;
    }
    else if ( chargeTime7 > 8000.0f )
    {
        damageLevel7 = FORCE_LEVEL_2;
    }
    else if ( chargeTime7 > 5000.0f )
    {
        damageLevel7 = FORCE_LEVEL_1;
    }

    

    // COSTO MANA.
    cost = forcePowerNeeded[FP_DARKGLYPH];
    if ( !WP_ForcePowerUsable( self, FP_DARKGLYPH, cost ) )
    {
        return;
    }

    // EFFETTO, ANIMAZIONE E CASTING.
    // LIV 1 MIETITRICE DI TENEBRE
    if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_1 )
        {
            anim = BOTH_SPINATTACK7;
            //BOTH_FORCE_2HANDEDLIGHTNING_HOLD;
            hold = 700;
            G_PlayEffect( G_EffectIndex( "reavers/darkimpact2" ), self->client->renderInfo.handRPoint );
            G_SoundOnEnt( self, CHAN_ITEM, "sound/weapons/Dark_Reaver/Darkreaver_Shield2.mp3" );
            int parts = SETANIM_TORSO;
            if ( !PM_InKnockDown( &self->client->ps ) )
            {
                if ( self->client->ps.saberLockTime > level.time )
                {
                    self->client->ps.saberLockTime = 0;
                    self->painDebounceTime = level.time + 2000;
                    hold += 2000;
                    parts = SETANIM_BOTH;
                }
            }
            NPC_SetAnim( self, parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
            self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have een in
            self->client->ps.saberBlocked = BLOCKED_NONE;
            // AGGIUSTAMENTO TEMPO PER LO SPEED
        
            if ( self->client->ps.forcePowersActive&(1<<FP_SPEED) )
            {
                hold = floor( hold*g_timescale->value );
            }
                // TEMPO DI CASTING
                self->client->ps.weaponTime = hold;//was 1000, but want to swing sooner
            //do effect... FIXME: build-up or delay this until in proper part of anim
            // self->client->ps.powerups[PW_FORCE_REPULSE] = level.time + self->client->ps.torsoAnimTimer + 500;
            //reset to 0 in case it's still > 0 from a previous push
            // self->client->pushEffectFadeTime = 0;
            VectorCopy( self->client->ps.viewangles, fwdangles );
            fwdangles[1] = self->client->ps.viewangles[1];
            AngleVectors( fwdangles, forward, right, NULL );
            VectorCopy( self->currentOrigin, center );
        }
    // LIV 2 MIETITRICE DI FUMO
    else if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_2 )
        {
            anim = BOTH_SPINATTACK6;
            //BOTH_FORCE_2HANDEDLIGHTNING_HOLD;
            hold = 1000;
            G_PlayEffect( G_EffectIndex( "reavers/smogimpact2" ), self->client->renderInfo.handRPoint );
            // G_SoundOnEnt( self, CHAN_ITEM, "sound/weapons/Smog_Reaver/smogreaver_Shield.mp3" );
            int parts = SETANIM_TORSO;
            if ( !PM_InKnockDown( &self->client->ps ) )
            {
                if ( self->client->ps.saberLockTime > level.time )
                {
                    self->client->ps.saberLockTime = 0;
                    self->painDebounceTime = level.time + 2000;
                    hold += 2000;
                    parts = SETANIM_BOTH;
                }
            }
            NPC_SetAnim( self, parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
            self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have een in
            self->client->ps.saberBlocked = BLOCKED_NONE;
            // AGGIUSTAMENTO TEMPO PER LO SPEED
        
            if ( self->client->ps.forcePowersActive&(1<<FP_SPEED) )
            {
                hold = floor( hold*g_timescale->value );
            }
                // TEMPO DI CASTING
                self->client->ps.weaponTime = hold;//was 1000, but want to swing sooner
            //do effect... FIXME: build-up or delay this until in proper part of anim
            // self->client->ps.powerups[PW_FORCE_REPULSE] = level.time + self->client->ps.torsoAnimTimer + 500;
            //reset to 0 in case it's still > 0 from a previous push
            // self->client->pushEffectFadeTime = 0;
            VectorCopy( self->client->ps.viewangles, fwdangles );
            fwdangles[1] = self->client->ps.viewangles[1];
            AngleVectors( fwdangles, forward, right, NULL );
            VectorCopy( self->currentOrigin, center );
        }
    // LIV 3 MIETITRICE DI VUOTO
    else if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_3 )
        {
            anim = BOTH_SPINATTACK7;
            //BOTH_FORCE_2HANDEDLIGHTNING_HOLD;
            hold = 1200;
            G_PlayEffect( G_EffectIndex( "reavers/vacuumimpact2" ), self->client->renderInfo.handRPoint );
            // G_SoundOnEnt( self, CHAN_ITEM, "sound/weapons/Void_Reaver/Vacuumreaver_Shield.mp3" );
            int parts = SETANIM_TORSO;
            if ( !PM_InKnockDown( &self->client->ps ) )
            {
                if ( self->client->ps.saberLockTime > level.time )
                {
                    self->client->ps.saberLockTime = 0;
                    self->painDebounceTime = level.time + 2000;
                    hold += 2000;
                    parts = SETANIM_BOTH;
                }
            }
            NPC_SetAnim( self, parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART );
            self->client->ps.saberMove = self->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have een in
            self->client->ps.saberBlocked = BLOCKED_NONE;
            // AGGIUSTAMENTO TEMPO PER LO SPEED
            self->client->pushEffectFadeTime = 0;
            if ( self->client->ps.forcePowersActive&(1<<FP_SPEED) )
            {
                hold = floor( hold*g_timescale->value );
            }
                // TEMPO DI CASTING
                self->client->ps.weaponTime = hold;//was 1000, but want to swing sooner
            //do effect... FIXME: build-up or delay this until in proper part of anim
            // self->client->ps.powerups[PW_FORCE_REPULSE] = level.time + self->client->ps.torsoAnimTimer + 500;
            //reset to 0 in case it's still > 0 from a previous push
            // self->client->pushEffectFadeTime = 0;
            VectorCopy( self->client->ps.viewangles, fwdangles );
            fwdangles[1] = self->client->ps.viewangles[1];
            AngleVectors( fwdangles, forward, right, NULL );
            VectorCopy( self->currentOrigin, center );
        }
    
    //make sure this plays and that you cannot press fire for about 1 second after this
    // FISICITA' E COLLIDERS
    if ( !numListedEntities )
    {
        for ( i = 0 ; i < 3 ; i++ )
        {
            mins[i] = center[i] - radius;
            maxs[i] = center[i] + radius;
        }
        
        numListedEntities = gi.EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
        
        // IMPORTANTE EFX AOE DI SPINTA  
        for ( e = 0 ; e < numListedEntities ; e++ )
        {
            ent = entityList[ e ];
            
            if ( !WP_ForceThrowable( ent, forwardEnt, self, qfalse, 0.0f, radius, forward ) )
            {
                continue;
            }
            
            //this is all to see if we need to start a saber attack, if it's in flight, this doesn't matter
            // find the distance from the edge of the bounding box
            for ( i = 0 ; i < 3 ; i++ )
            {
                if ( center[i] < ent->absmin[i] )
                {
                    v[i] = ent->absmin[i] - center[i];
                } else if ( center[i] > ent->absmax[i] )
                {
                    v[i] = center[i] - ent->absmax[i];
                } else
                {
                    v[i] = 0;
                }
            }
            
            VectorSubtract( ent->absmax, ent->absmin, size );
            VectorMA( ent->absmin, 0.5, size, ent_org );
            
            //see if they're in front of me
            VectorSubtract( ent_org, center, dir );
            VectorNormalize( dir );
            
            dist = VectorLength( v );
            
            if ( dist >= radius )
            {
                continue;
            }
            
            //in PVS?
            if ( !ent->bmodel && !gi.inPVS( ent_org, self->client->renderInfo.eyePoint ) )
            {//must be in PVS
                continue;
            }
            
            if ( ent != forwardEnt )
            {//don't need to trace against forwardEnt again
                //really should have a clear LOS to this thing...
                gi.trace( &tr, self->client->renderInfo.eyePoint, vec3_origin, vec3_origin, ent_org, self->s.number, MASK_FORCE_PUSH, (EG2_Collision)0, 0 );//was MASK_SHOT, but changed to match above trace and crosshair trace
                if ( tr.fraction < 1.0f && tr.entityNum != ent->s.number )
                {//must have clear LOS
                    continue;
                }
            }
            
            // ok, we are within the radius, add us to the incoming list
            push_list[ent_count] = ent;
            ent_count++;
        }
    }

    for ( int x = 0; x < ent_count; x++ )
    {

        if ( push_list[x]->client )
        {
            vec3_t    pushDir;
            qboolean targetLive = qtrue;
            float    knockback = suck?0:700; // 700 POTENZA DELL'URTO
            //SIGH band-aid...
            if ( push_list[x]->s.number >= MAX_CLIENTS
                && self->s.number < MAX_CLIENTS )
            { // BLOCCA COLORO CHE STANNO USANDO TK E BLEEDING
            // EFFETTO SUGLI AVVERSARI!
            // LIVELLO 1, TENEBRA
if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_1
                && push_list[x]->s.weapon != WP_NONE        //don't charm people who aren't capable of fighting... like ugnaughts and droids, just confuse them
                && !Pilot_AnyVehiclesRegistered())
            {//FA EFFETTO SOLO SULLE SEGUENTI CLASSI
                // CLASSI SU CUI FA EFFETTO
                if ( push_list[x] && push_list[x]->client  )
                    {
                        switch ( push_list[x]->client->NPC_class )
                        {
                            // BLINDED, And DAMAGED
                            case CLASS_SABER_DROID:
                            case CLASS_PROTOCOL:
                            case CLASS_ASSASSIN_DROID:
                            case CLASS_MORGANKATARN:
                            // HEAVY DAMAGED
                            // tutti gli elementali e i boss non posson esser stunnati!
                            if ( push_list[x]->enemy )
                                
                            {
                                G_ClearEnemy( push_list[x] );
                            }
                            //FIXME: maybe pick an enemy right here?
                            //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!!
                            //FIXME: need a *charmed* timer on this...?  Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done?
                            push_list[x]->NPC->confusionTime = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "force/blind" ), push_list[x]->playerModel, push_list[x]->headBolt, push_list[x]->s.number, push_list[x]->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                                G_PlayEffect( G_EffectIndex( "reavers/darkimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 10, DAMAGE_NO_KNOCKBACK, MOD_BRYAR );
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_COWER1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_COWER1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_COWER1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 200;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            };
                            break;
                            // just blinded, not damaged
                            case CLASS_RODIAN:
                            case CLASS_PRISONER:
                            case CLASS_TRANDOSHAN:
                            case CLASS_STORMTROOPER:
                            case CLASS_IMPWORKER:
                            case CLASS_IMPERIAL:
                            case CLASS_REBORN:
                            case CLASS_JEDI:
                            case CLASS_ALORA:
                            case CLASS_MONMOTHA:
                            case CLASS_TUSKEN:
                            case CLASS_WEEQUAY:  
                            case CLASS_SWAMPTROOPER:
                            case CLASS_COMMANDO:
                            case CLASS_TAVION:
                            case CLASS_MINEMONSTER:
                            case CLASS_WAMPA:
                            case CLASS_SWAMP:
                            case CLASS_INTERROGATOR:
                            case CLASS_MARK1:
                            case CLASS_MARK2:
                            case CLASS_R2D2:
                            case CLASS_R5D2:
                            case CLASS_HAZARD_TROOPER:
                            case CLASS_REBEL:
                            case CLASS_ROCKETTROOPER:
                            case CLASS_BARTENDER:
                            case CLASS_GONK:
                            case CLASS_UGNAUGHT:
                            case CLASS_REELO:
                            if ( push_list[x]->enemy )
                                
                            {
                                G_ClearEnemy( push_list[x] );
                            }
                            //FIXME: maybe pick an enemy right here?
                            //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!!
                            //FIXME: need a *charmed* timer on this...?  Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done?
                            push_list[x]->NPC->confusionTime = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            push_list[x]->flags ^= FL_NOTARGET;
                            soundIndex = G_SoundIndex( va("sound/weapons/Dark_Reaver/darkreavershadows%d.wav", Q_irand( 1, 4 ) ) );
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "force/blind" ), push_list[x]->playerModel, push_list[x]->headBolt, push_list[x]->s.number, push_list[x]->currentOrigin, SunGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_COWER1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_COWER1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_COWER1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 200;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            }
                        break;
                        // Damaged, but no Blinded! They are too smarts!
                            case CLASS_JAN:
                            case CLASS_GALAK:
                            case CLASS_GLIDER:
                            case CLASS_NOGHRI:
                            case CLASS_MURJJ:
                            case CLASS_LIZARD:
                            case CLASS_FISH:
                            case CLASS_CLAW:
                            case CLASS_FLIER2:
                            soundIndex = G_SoundIndex( va("sound/weapons/Dark_Reaver/darkreavershadows%d.wav", Q_irand( 1, 4 ) ) );
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "reavers/darkimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 10, DAMAGE_NO_KNOCKBACK, MOD_BRYAR );
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_COWER1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_COWER1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_COWER1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 200;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            }
                        break;
                    default:
                        break;
                    }
                }
            }
            // LIVELLO 2; FUMO
            if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_2
                && push_list[x]->s.weapon != WP_NONE        //don't charm people who aren't capable of fighting... like ugnaughts and droids, just confuse them
                && !Pilot_AnyVehiclesRegistered())
            {//FA EFFETTO SOLO SULLE SEGUENTI CLASSI
                // CLASSI SU CUI FA EFFETTO
                if ( push_list[x] && push_list[x]->client  )
                    {
                        switch ( push_list[x]->client->NPC_class )
                        {
                            // BLINDED, HEAVY DAMAGED, NOT GASPING.
                            case CLASS_SABER_DROID:
                            case CLASS_PROTOCOL:
                            case CLASS_ASSASSIN_DROID:
                            case CLASS_MORGANKATARN:
                            // HEAVY DAMAGED
                            // tutti gli elementali e i boss non posson esser stunnati!
                            if ( push_list[x]->enemy )
                                
                            {
                                G_ClearEnemy( push_list[x] );
                            }
                            //FIXME: maybe pick an enemy right here?
                            //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!!
                            //FIXME: need a *charmed* timer on this...?  Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done?
                            push_list[x]->NPC->confusionTime = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "force/smog" ), push_list[x]->playerModel, push_list[x]->headBolt, push_list[x]->s.number, push_list[x]->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                                G_PlayEffect( G_EffectIndex( "reavers/smogimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 30, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_COWER1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_COWER1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_COWER1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 200;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            };
                            break;
                            // Humans and mortal creatures: blinded, chocked!
                            case CLASS_RODIAN:
                            case CLASS_PRISONER:
                            case CLASS_TRANDOSHAN:
                            case CLASS_STORMTROOPER:
                            case CLASS_IMPWORKER:
                            case CLASS_IMPERIAL:
                            case CLASS_SWAMP:
                            case CLASS_INTERROGATOR:
                            case CLASS_ALORA:
                            case CLASS_MONMOTHA:
                            if ( push_list[x]->enemy )
                            {
                                G_ClearEnemy( push_list[x] );
                            }
                            //FIXME: maybe pick an enemy right here?
                            //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!!
                            //FIXME: need a *charmed* timer on this...?  Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done?
                            push_list[x]->NPC->confusionTime = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            soundIndex = G_SoundIndex( va("sound/weapons/Smog_Reaver/smogreavershadows%d.wav", Q_irand( 1, 4 ) ) );
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "force/smog" ), push_list[x]->playerModel, push_list[x]->headBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_PlayEffect( G_EffectIndex( "reavers/smogimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 0, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_CHOKE1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_CHOKE1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_CHOKE1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 15000;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            }
                        break;
                        // Damaged, but no Blinded! no work on undeads!
                            case CLASS_TUSKEN:
                            case CLASS_NOGHRI:
                            case CLASS_GRAN:
                            case CLASS_REBORN:
                            case CLASS_JEDI:
                            case CLASS_WEEQUAY:  
                            case CLASS_SWAMPTROOPER:
                            case CLASS_COMMANDO:
                            case CLASS_TAVION:
                            case CLASS_MINEMONSTER:
                            case CLASS_WAMPA:
                            case CLASS_HAZARD_TROOPER:
                            case CLASS_REBEL:
                            case CLASS_BARTENDER:
                            case CLASS_UGNAUGHT:
                            case CLASS_REELO:
                            soundIndex = G_SoundIndex( va("sound/weapons/Smog_Reaver/smogreavershadows%d.wav", Q_irand( 1, 4 ) ) );
                            if ( push_list[x]->ghoul2.size() && push_list[x]->torsoBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "reavers/smogimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 20, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_COWER1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_COWER1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_COWER1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 200;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            }
                            // LOW DAMAGED, NO DMG ANIMATION, BOSSES.
                            case CLASS_CLAW:
                            case CLASS_JAN:
                            case CLASS_GALAK:
                            case CLASS_GLIDER:
                            case CLASS_ROCKETTROOPER:
                            case CLASS_MURJJ:
                            case CLASS_LIZARD:
                            case CLASS_FISH:
                            case CLASS_FLIER2:
                            soundIndex = G_SoundIndex( va("sound/weapons/Smog_Reaver/smogreavershadows%d.wav", Q_irand( 1, 4 ) ) );
                            if ( push_list[x]->ghoul2.size() && push_list[x]->torsoBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "reavers/smogimpactbody" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 10, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                            }
                        break;
                    default:
                        break;
                    }
                }
            }
            // LIVELLO 3, VUOTO!
            if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_3
                && push_list[x]->s.weapon != WP_NONE        //don't charm people who aren't capable of fighting... like ugnaughts and droids, just confuse them
                && !Pilot_AnyVehiclesRegistered())
            {//FA EFFETTO SOLO SULLE SEGUENTI CLASSI
                // CLASSI SU CUI FA EFFETTO
                if ( push_list[x] && push_list[x]->client  )
                    {
                        switch ( push_list[x]->client->NPC_class )
                        {
                            // BLINDED, And DAMAGED
                            case CLASS_SABER_DROID:
                            case CLASS_PROTOCOL:
                            case CLASS_ASSASSIN_DROID:
                            case CLASS_MORGANKATARN:
                            // HEAVY DAMAGED
                            // tutti gli elementali e i boss non posson esser stunnati!
                            if ( push_list[x]->enemy )
                                
                            {
                                G_ClearEnemy( push_list[x] );
                            }
                            //FIXME: maybe pick an enemy right here?
                            //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!!
                            //FIXME: need a *charmed* timer on this...?  Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done?
                            push_list[x]->NPC->confusionTime = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "force/void" ), push_list[x]->playerModel, push_list[x]->headBolt, push_list[x]->s.number, push_list[x]->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                                G_PlayEffect( G_EffectIndex( "reavers/vacuumimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 50, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                                // NOT SUCK THE LIGHT ELEMENTAL THEY HAVE NO MASS AND RESIST TO DARKNESS, JUST DAMAGE!  
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_COWER1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_COWER1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_COWER1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 20000;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            };
                            break;
                            // Mortals creatures: blinded, chocked, damaged!
                            case CLASS_RODIAN:
                            case CLASS_PRISONER:
                            case CLASS_TRANDOSHAN:
                            case CLASS_STORMTROOPER:
                            case CLASS_IMPWORKER:
                            case CLASS_IMPERIAL:
                            case CLASS_SWAMP:
                            case CLASS_INTERROGATOR:
                            case CLASS_GALAK:
                            if ( push_list[x]->enemy )
                                
                            {
                                G_ClearEnemy( push_list[x] );
                            }
                            //FIXME: maybe pick an enemy right here?
                            //FIXME: does nothing to TEAM_FREE and TEAM_NEUTRALs!!!
                            //FIXME: need a *charmed* timer on this...?  Or do TEAM_PLAYERS assume that "confusion" means they should switch to team_enemy when done?
                            push_list[x]->NPC->confusionTime = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            push_list[x]->flags ^= FL_NOTARGET;
                            soundIndex = G_SoundIndex( va("sound/weapons/Dark_Reaver/darkreavershadows%d.wav", Q_irand( 1, 4 ) ) );
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "force/void" ), push_list[x]->playerModel, push_list[x]->headBolt, push_list[x]->s.number, push_list[x]->currentOrigin, DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]], qtrue );
                                G_PlayEffect( G_EffectIndex( "reavers/vacuumimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 50, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                                // NOW SUCK THEM!
                                if ( PM_InKnockDown( &push_list[x]->client->ps ) )
                                {
                                 continue;
                                }
                                WP_ForceKnockdown ( push_list[x], self, suck, (!suck&&knockback>150), qfalse );
                                // VectorSubtract(  push_list[x]->currentOrigin, self->currentOrigin, pushDir );
                                if ( suck )
                                {
                                    VectorSubtract( push_list[x]->currentOrigin, self->currentOrigin, pushDir );
                                }
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_CHOKE1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_CHOKE1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_CHOKE1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 20000;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            }
                        break;
                        // VAMPIRES, UNDEADS, Monsters, Sucked and damaged.
                            case CLASS_REBORN:
                            case CLASS_JEDI:
                            case CLASS_LUKE:
                            case CLASS_KYLE:
                            case CLASS_ALORA:
                            case CLASS_MONMOTHA:
                            case CLASS_TUSKEN:
                            case CLASS_GLIDER:
                            case CLASS_NOGHRI:
                            case CLASS_FLIER2:
                            case CLASS_REELO:
                            case CLASS_WEEQUAY:
                            case CLASS_LIZARD:
                            case CLASS_SWAMPTROOPER:
                            case CLASS_FISH:
                            case CLASS_COMMANDO:
                            case CLASS_TAVION:
                            case CLASS_MINEMONSTER:
                            case CLASS_WAMPA:
                            case CLASS_BARTENDER:
                            case CLASS_UGNAUGHT:
                            soundIndex = G_SoundIndex( va("sound/weapons/Vacuum_Reaver/vacuumreavershadows%d.wav", Q_irand( 1, 4 ) ) );
                            if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "reavers/voidimpactbody2" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 35, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                                // NOW SUCK THEM!
                                if ( PM_InKnockDown( &push_list[x]->client->ps ) )
                                {
                                 continue;
                                }
                                WP_ForceKnockdown ( push_list [x], self, suck, qfalse, qtrue );
                            
                            }
                            if ( PM_HasAnimation( push_list[x], BOTH_COWER1 ) )
                            {
                                NPC_SetAnim( push_list[x], SETANIM_LEGS, BOTH_COWER1, SETANIM_FLAG_NORMAL );
                                NPC_SetAnim( push_list[x], SETANIM_TORSO, BOTH_COWER1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
                                push_list[x]->client->ps.torsoAnimTimer += 5000;
                                push_list[x]->client->ps.weaponTime = push_list[x]->client->ps.torsoAnimTimer;
                                // anim = BOTH_SONICPAIN_HOLD;
                                hold = level.time + DarkGlyphTime[self->client->ps.forcePowerLevel[FP_DARKGLYPH]];
                            }
                        break;
                        // Golem, artifact, they resist to void power. Just damaged, not sucked.  
                        case CLASS_MARK1:
                        case CLASS_MARK2:
                        case CLASS_R2D2:
                        case CLASS_R5D2:
                        case CLASS_HAZARD_TROOPER:
                        case CLASS_GALAKMECH:
                        case CLASS_GONK:
                        if ( push_list[x]->ghoul2.size() && push_list[x]->headBolt != -1 )
                            {//FIXME: what if already playing effect?
                                G_PlayEffect( G_EffectIndex( "reavers/voidimpactbody" ), push_list[x]->playerModel, push_list[x]->chestBolt, push_list[x]->s.number, push_list[x]->currentOrigin );
                                G_Damage( push_list[x], self, self, 0, push_list[x]->client->renderInfo.eyePoint, 25, DAMAGE_NO_KNOCKBACK, MOD_BRYAR_ALT );
                            }
                        break;
                    default:
                        break;
                    }
                }
            }

 

Lastest part of the code. sorry for multiple posting, but i cannot post all in one post because forum give me error about too long posting.

:(

 

 

            if ( (push_list[x]->client->ps.forcePowersActive&(1<<FP_GRIP))
                    //&& push_list[x]->client->ps.forcePowerDebounce[FP_GRIP] < level.time
                    && push_list[x]->client->ps.forceGripEntityNum == self->s.number )
                {
                    WP_ForcePowerStop( push_list[x], FP_GRIP );
                }
                if ( (push_list[x]->client->ps.forcePowersActive&(1<<FP_DRAIN))
                    //&& push_list[x]->client->ps.forcePowerDebounce[FP_DRAIN] < level.time
                    && push_list[x]->client->ps.forceDrainEntityNum == self->s.number )
                {
                    WP_ForcePowerStop( push_list[x], FP_DRAIN );
                }
            }
            
            if ( Rosh_BeingHealed( push_list[x] ) )
            {
                continue;
            }
            if ( fake )
            {//always resist
            //    WP_ResistForcePush( push_list[x], self, qfalse );
                continue;
            }

            int powerLevel, powerUse;
            powerLevel = self->client->ps.forcePowerLevel[FP_DARKGLYPH];
            powerUse = FP_DARKGLYPH;
            // LA CONTROMAGIA ASSORBE IL GLIFO E LO NEUTRALIZZA
            int modPowerLevel = WP_AbsorbConversion( push_list[x], push_list[x]->client->ps.forcePowerLevel[FP_ABSORB], self, powerUse, powerLevel, forcePowerNeeded[self->client->ps.forcePowerLevel[powerUse]] );
            // QUESTE CLASSI SON RESISTENTI AL POTERE DELLE TENEBRE
            if (push_list[x]->client->NPC_class==CLASS_SABOTEUR ||
                push_list[x]->client->NPC_class==CLASS_BESPIN_COP ||
                push_list[x]->client->NPC_class==CLASS_SHADOWTROOPER ||
                push_list[x]->client->NPC_class==CLASS_JAN ||
                push_list[x]->client->NPC_class==CLASS_DESANN ||
                push_list[x]->client->NPC_class==CLASS_HOWLER ||
                push_list[x]->client->NPC_class==CLASS_MURJJ ||
                push_list[x]->client->NPC_class==CLASS_GALAKMECH ||
                push_list[x]->client->NPC_class==CLASS_ATST ||
                push_list[x]->client->NPC_class==CLASS_MOUSE ||
                push_list[x]->client->NPC_class==CLASS_JAWA ||
                push_list[x]->client->NPC_class==CLASS_RANCOR ||
                push_list[x]->client->NPC_class==CLASS_SAND_CREATURE ||
                push_list[x]->client->NPC_class==CLASS_KYLE ||
                push_list[x]->client->NPC_class==CLASS_LUKE
                )
            {
                WP_ResistForcePush( push_list[x], self, qfalse );
                modPowerLevel = 0;    // devides throw by 10
            }
            //First, if this is the player we're push/pulling, see if he can counter it

            if ( modPowerLevel != -1
                && InFront( self->currentOrigin, push_list[x]->client->renderInfo.eyePoint, push_list[x]->client->ps.viewangles, 0.3f ) )
            // SE IL LIVELLO DI CONTROMAGIA E' A 3, ESSO VIENE BLOCCATO DA TUTTI!
            {//absorbed and I'm in front of them
                //counter it
                if ( push_list[x]->client->ps.forcePowerLevel[FP_ABSORB] > FORCE_LEVEL_2 )
                {//no reaction at all
                }
                else
                {
                    WP_ResistForcePush( push_list[x], self, qfalse );
                    push_list[x]->client->ps.saberMove = push_list[x]->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have been in
                    push_list[x]->client->ps.saberBlocked = BLOCKED_NONE;
                }
                continue;
            }
            else if ( !push_list[x]->s.number )
            // ALTRIMENTI CERCHERANNON DI RESISTERE
            {//player
                if ( ShouldPlayerResistForceThrow(push_list[x], self, qfalse) )
                {
                //    WP_ResistForcePush( push_list[x], self, qfalse );
                    push_list[x]->client->ps.saberMove = push_list[x]->client->ps.saberBounceMove = LS_READY;//don't finish whatever saber anim you may have been in
                    push_list[x]->client->ps.saberBlocked = BLOCKED_NONE;
                    continue;
                }
            }
            else if ( push_list[x]->client && Jedi_WaitingAmbush( push_list[x] ) )
            {
                WP_ForceKnockdown( push_list[x], self, qfalse, qtrue, qfalse );
                DarkDamage( self, push_list[x], tr.endpos, damageLevel7 );
                continue;
            }
            // L'ONDA D'URTO LIBERA COLORO CHE SON SOTTO L'ABBRACCIO DI UN VAMPIRO!
            if ( push_list[x]->client->ps.forceDrainEntityNum == self->s.number
                && (self->s.eFlags&EF_FORCE_DRAINED) )
            {//stop them from draining me now, dammit!
                WP_ForcePowerStop( push_list[x], FP_DRAIN );
            }
            
            //okay, everyone else (or player who couldn't resist it)... Condizioni di resistenza al glifo.
            if ( ((self->s.number == 0 && Q_irand( 0, 2 ) ) || Q_irand( 0, 2 ) ) && push_list[x]->client && push_list[x]->health > 0 //è vivo
                // && push_list[x]->client->ps.weapon == WP_SABER // è armato di spada
                && push_list[x]->health > 0 // è vivo
                && push_list[x]->client->ps.forceRageRecoveryTime < level.time // ha appena finito di usar la Furia.
                && ((self->client->NPC_class != CLASS_DESANN&&Q_stricmp("Yoda",self->NPC_type)) || !Q_irand( 0, 2 ) )// QUESTE CLASSI RESISTONO CON UN FORCE PUSH AL 30% di possiblità
                && push_list[x]->client->ps.groundEntityNum != ENTITYNUM_NONE //on the ground
                && InFront( self->currentOrigin, push_list[x]->currentOrigin, push_list[x]->client->ps.viewangles, 0.3f ) //è di fronte
                && ( push_list[x]->client->ps.powerups[PW_FORCE_PUSH] > level.time ||//sta sparando un colpo cinetico
                    (push_list[x]->s.number != 0 && push_list[x]->client->ps.weaponTime < level.time)//not the player and not attacking (NPC jedi auto-defend against pushes)
                    )
                )
            {//Jedi don't get pushed, they resist as long as they aren't already attacking and are on the ground
                // SE UNO SPADACCINO TOCCA TERRA, RESISTE!
                if ( push_list[x]->client->ps.saberLockTime > level.time )
                {//they're in a lock
                    if ( push_list[x]->client->ps.saberLockEnemy != self->s.number )
                    {//they're not in a lock with me
                        continue;
                    }
                    // RESISTONO SE IL GLIFO E' PIU' DEBOLE DEL COLPO CINETICO
                    else if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] < FORCE_LEVEL_3 ||
                             push_list[x]->client->ps.forcePowerLevel[FP_ABSORB] > FORCE_LEVEL_2 )
                    {//they're in a lock with me, but my push is too weak
                        continue;
                    }
                    else
                    {// Saranno sbattuti
                        self->painDebounceTime = 0;
                        self->client->ps.weaponTime = 500;
                        if ( self->client->ps.forcePowersActive&(1<<FP_SPEED) )
                        {
                            self->client->ps.weaponTime = floor( self->client->ps.weaponTime * g_timescale->value );
                        }
                    }
                }
                // PROBABILITA' DI RESISTENZA A SECONDA DEL LIVELLO DI DIFFICOLTA'
                int resistChance = Q_irand(0, 2);
                if ( push_list[x]->s.number >= MAX_CLIENTS )
                {//NPC
                    if ( g_spskill->integer == 1 )
                    {//stupid tweak for graham
                        resistChance = Q_irand(0, 3);
                    }
                }
                if ( modPowerLevel == -1
                        && self->client->ps.forcePowerLevel[FP_WATERGLYPH] > FORCE_LEVEL_2
                        && !resistChance
                        && push_list[x]->client->ps.forcePowerLevel[FP_WATERGLYPH] < FORCE_LEVEL_3 )
                {//Glifo di Forza livello 3 spinge sempre gli spadaccini
                    if ( PM_InKnockDown( &push_list[x]->client->ps ) )
                    {//can't knock them down again
                        continue;
                    }
                    WP_ForceKnockdown( push_list[x], self, qfalse, qfalse, qtrue );
                    DarkDamage( self, push_list[x], tr.endpos, damageLevel7 );
                }
                else
                {
                    // WP_ResistForcePush( push_list[x], self, qfalse );
                }
            }
            else
            {
                //UGH: FIXME: for enemy jedi, they should probably always do force pull 3, and not your weapon (if player?)!
                //shove them
                if ( push_list[x]->NPC
                    && push_list[x]->NPC->jumpState == JS_JUMPING )
                {// L'ONDA D'URTO NON BLOCCA CHI SALTA
                    WP_ResistForcePush( push_list[x], self, qfalse );
                    push_list[x]->forcePushTime = level.time + 600; // let the push effect last for 600 ms
                    continue;
                }
                
                if ( push_list[x]->s.number
                    && (push_list[x]->message || (push_list[x]->flags&FL_NO_KNOCKBACK)) )
                {// NON FA EFFETTO SU CHI HA CHIAVI. PUO' DROPPAR LA CHIAVE
                    //don't push me... FIXME: maybe can pull the key off me?
                    WP_ForceKnockdown( push_list[x], self, qfalse, qfalse, qfalse );
                    DarkDamage( self, push_list[x], tr.endpos, damageLevel7 );
                    continue;
                }
                {
                    // Fix potenza urto
                    VectorSubtract( push_list[x]->currentOrigin, self->currentOrigin, pushDir );
                    knockback -= VectorNormalize( pushDir );
                    if ( knockback < 0/* -400 Void Knockback */ )
                    {
                        knockback = 0;
                    }
                    //glifo di forza a uno, l'onda d'urto è ridotta ad un terzo di potenza
                    if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_1 )
                    {//maybe just knock them down
                        knockback = 0;
                    }
                    else if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_2 )
                    {//maybe just knock them down
                        knockback = 0;
                    }
                    else if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] == FORCE_LEVEL_3 )
                    {//Void need to suck the enemies! But How???
                        knockback = suck?0:200/*suck?0:200*/ /*-400*/;
                        suck = -200;
                    }
                    // Glifo a livello 3. Super onda d'urto!!!
                    else if ( self->client->ps.forcePowerLevel[FP_DARKGLYPH] > FORCE_LEVEL_3 )
                    {//super-hard push
                        //Hmm, maybe in this case can even nudge/knockdown a jedi?  Especially if close?
                        knockback = suck?0:700;
                        // QUA METTERE CODICE RISUCCHIO
                    }
                }
                
                if ( modPowerLevel != -1 )
                {
                    if ( !modPowerLevel )
                    {
                        knockback /= 10.0f;
                    }
                    else if ( modPowerLevel == 1 )
                    {
                        knockback /= 6.0f;
                    }
                    else// if ( modPowerLevel == 2 )
                    {
                        knockback /= 2.0f;
                    }
                }
                // Spinge gli avversari
                G_Throw( push_list[x], pushDir, knockback );
                //make it so they don't actually hurt me when pulled at me...
                push_list[x]->forcePuller = self->s.number;
                
                if ( push_list[x]->client->ps.groundEntityNum != ENTITYNUM_NONE )
                {// Se i nemici si trovano al suolo, l'urto viene bilanciato.
                    if ( push_list[x]->client->ps.velocity[2] < knockback )
                    {
                        push_list[x]->client->ps.velocity[2] = knockback;
                    }
                }
                
                if ( push_list[x]->health > 0 )
                {//target is still alive
                    if ( (push_list[x]->s.number||(cg.renderingThirdPerson&&!cg.zoomMode)) //NPC or 3rd person player
                        && ((self->client->ps.forcePowerLevel[FP_DARKGLYPH] < FORCE_LEVEL_2 && push_list[x]->client->ps.forcePowerLevel[FP_ABSORB] < FORCE_LEVEL_1)) )
                    {//NPC or third person player (without force push/pull skill), and force push/pull level is at 1
                        // Se glifo forza è a liv 1 e l'avversario non oppone resistenza  
                        WP_ForceKnockdown( push_list[x], self, qfalse, (knockback>150), qfalse );
                        DarkDamage( self, push_list[x], tr.endpos, damageLevel7 );
                    }
                    else if ( !push_list[x]->s.number )
                    {//player, have to force an anim on him
                        WP_ForceKnockdown( push_list[x], self, qfalse, (knockback>150), qfalse );
                        DarkDamage( self, push_list[x], tr.endpos, damageLevel7 );
                    }
                    else
                    {//NPC and force-push/pull at level 2 or higher
                        WP_ForceKnockdown( push_list[x], self, qfalse, (knockback>100), qfalse );
                        DarkDamage( self, push_list[x], tr.endpos, damageLevel7 );
                    }
                }
                push_list[x]->forcePushTime = level.time + 600; // Durata dell'Onda, 0.6 secondi.
            }
        }
        else if ( !fake )
        {//not a fake push/pull
            // LUCE, FULMINE E RADIANZA NON POSSONO DANNEGGIARE VETRI O RESPINGERE OGGETTI.
            // SE UNA SPADA AGLIATA CONTRO CHI LANCIA L'ONDA D'URTO, L'ONDA LA FA RITORNARE AL MITTENTE!
            // l'onda respinge le granate.
            if ( push_list[x]->s.eType == ET_MISSILE
                     && push_list[x]->s.pos.trType != TR_STATIONARY
                     && (push_list[x]->s.pos.trType != TR_INTERPOLATE||push_list[x]->s.weapon != WP_THERMAL) )//rolling and stationary thermal detonators are dealt with below
            {
                vec3_t dir2Me;
                VectorSubtract( self->currentOrigin, push_list[x]->currentOrigin, dir2Me );
                float dot = DotProduct( push_list[x]->s.pos.trDelta, dir2Me );
                
                if ( push_list[x]->s.eFlags&EF_MISSILE_STICK )
                {//Proiettili metallici (cannone alchimista, vengon respinti)
                    push_list[x]->s.eType = ET_MISSILE;
                    push_list[x]->s.eFlags &= ~EF_MISSILE_STICK;
                    push_list[x]->s.eFlags |= EF_BOUNCE_HALF;
                    push_list[x]->splashDamage /= 1;
                    push_list[x]->splashRadius /= 1;
                    push_list[x]->e_ThinkFunc = thinkF_WP_Explode;
                    push_list[x]->nextthink = level.time + Q_irand( 500, 3000 );
                }
                if ( dot >= 0 )
                {//it's heading towards me
                    G_ReflectMissile( self, push_list[x], forward );
                }
                else
                {
                    VectorScale( push_list[x]->s.pos.trDelta, 1.25f, push_list[x]->s.pos.trDelta );
                }
                //deflect sound
                //G_Sound( push_list[x], G_SoundIndex( va("sound/weapons/blaster/reflect%d.wav", Q_irand( 1, 3 ) ) ) );
                //push_list[x]->forcePushTime = level.time + 600; // let the push effect last for 600 ms
                // PUO' RESPINGEREE I PROIETTILI CINETICI D'ARIA?? (io la togleirei... )
                if ( push_list[x]->s.eType == ET_MISSILE
                    && push_list[x]->s.weapon == WP_BOWCASTER
                    && push_list[x]->damage < 20 )
                {//pushing away a rocket raises it's damage to the max for NPCs
                    push_list[x]->damage = 20;
                }
            }    
            // UN MURO D'ACQUA O UN'ONDA DI GHIACCIO O CRISTALLO SICURAMENTE SPACCA QUALCOSA FRAGILE COME IL VETRO!
            else if ( push_list[x]->svFlags & SVF_GLASS_BRUSH )
            {//break the glass
                trace_t tr;
                vec3_t    pushDir;
                float    damage = 0;
                
                AngleVectors( self->client->ps.viewangles, forward, NULL, NULL );
                VectorNormalize( forward );
                VectorMA( self->client->renderInfo.eyePoint, radius, forward, end );
                gi.trace( &tr, self->client->renderInfo.eyePoint, vec3_origin, vec3_origin, end, self->s.number, MASK_SHOT, (EG2_Collision)0, 0 );
                if ( tr.entityNum != push_list[x]->s.number || tr.fraction == 1.0 || tr.allsolid || tr.startsolid )
                {//must be pointing right at it
                    continue;
                }
                
                VectorSubtract( tr.endpos, self->client->renderInfo.eyePoint, pushDir );
                
                damage -= VectorNormalize( pushDir );
                if ( damage < 0 )
                {
                    damage = 0;
                }
                VectorScale( pushDir, damage, pushDir );
                
                G_Damage( push_list[x], self, self, pushDir, tr.endpos, damage, 0, MOD_BRYAR_ALT );
            }
    
        }
    }

    // COSTO MANA
    WP_ForcePowerDrain(self, FP_SUNGLYPH, cost);

    if ( self->NPC )
    // A seconda della loro abilità gli NPC resistono più o meno bene.
    {//NPCs can push more often
        //FIXME: vary by rank and game skill?
        self->client->ps.forcePowerDebounce[FP_DARKGLYPH] = level.time + 200;
    }
    else
    {
        self->client->ps.forcePowerDebounce[FP_DARKGLYPH] = level.time + self->client->ps.torsoAnimTimer + 500;
    }
}

 

Question is: how to add a force radius pulling function, like force pull level 3, but with effect to ALL enemies around the player, at the level 3 power of the Fp_Darkglyph?

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...