Asgarath83 Posted January 4, 2016 Posted January 4, 2016 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?
Asgarath83 Posted January 4, 2016 Author Posted January 4, 2016 fixed with negative knockback!many thanks to @@redsaurus TriForce likes this
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now