static void Howler_Howl( void ) { gentity_t *radiusEnts[ 128 ]; int numEnts; const float radius = (NPC->spawnflags&1)?256:128; const float halfRadSquared = ((radius/2)*(radius/2)); const float radiusSquared = (radius*radius); float distSq; int i; vec3_t boltOrg; AddSoundEvent( NPC, NPC->currentOrigin, 512, AEL_DANGER, qfalse, qtrue ); numEnts = NPC_GetEntsNearBolt( radiusEnts, radius, NPC->handLBolt, boltOrg ); for ( i = 0; i < numEnts; i++ ) { if ( !radiusEnts[i]->inuse ) { continue; } if ( radiusEnts[i] == NPC ) {//Skip the rancor ent continue; } if ( radiusEnts[i]->client == NULL ) {//must be a client continue; } if ( radiusEnts[i]->client->NPC_class == CLASS_HOWLER ) {//other howlers immune continue; } distSq = DistanceSquared( radiusEnts[i]->currentOrigin, boltOrg ); if ( distSq <= radiusSquared ) { if ( distSq < halfRadSquared ) {//close enough to do damage, too if ( Q_irand( 0, g_spskill->integer ) ) {//does no damage on easy, does 1 point every other frame on medium, more often on hard G_Damage( radiusEnts[i], NPC, NPC, vec3_origin, NPC->currentOrigin, 1, DAMAGE_NO_KNOCKBACK, MOD_IMPACT ); } } if ( radiusEnts[i]->health > 0 && radiusEnts[i]->client && radiusEnts[i]->client->NPC_class != CLASS_RANCOR && radiusEnts[i]->client->NPC_class != CLASS_ATST && !PM_InKnockDown( &radiusEnts[i]->client->ps ) ) { if ( PM_HasAnimation( radiusEnts[i], BOTH_SONICPAIN_START ) ) { if ( radiusEnts[i]->client->ps.torsoAnim != BOTH_SONICPAIN_START && radiusEnts[i]->client->ps.torsoAnim != BOTH_SONICPAIN_HOLD ) { NPC_SetAnim( radiusEnts[i], SETANIM_LEGS, BOTH_SONICPAIN_START, SETANIM_FLAG_NORMAL ); NPC_SetAnim( radiusEnts[i], SETANIM_TORSO, BOTH_SONICPAIN_START, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); radiusEnts[i]->client->ps.torsoAnimTimer += 100; radiusEnts[i]->client->ps.weaponTime = radiusEnts[i]->client->ps.torsoAnimTimer; } else if ( radiusEnts[i]->client->ps.torsoAnimTimer <= 100 ) {//at the end of the sonic pain start or hold anim NPC_SetAnim( radiusEnts[i], SETANIM_LEGS, BOTH_SONICPAIN_HOLD, SETANIM_FLAG_NORMAL ); NPC_SetAnim( radiusEnts[i], SETANIM_TORSO, BOTH_SONICPAIN_HOLD, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); radiusEnts[i]->client->ps.torsoAnimTimer += 100; radiusEnts[i]->client->ps.weaponTime = radiusEnts[i]->client->ps.torsoAnimTimer; } } /* else if ( distSq < halfRadSquared && radiusEnts[i]->client->ps.groundEntityNum != ENTITYNUM_NONE && !Q_irand( 0, 10 ) )//FIXME: base on skill {//within range G_Knockdown( radiusEnts[i], NPC, vec3_origin, 500, qfalse ); } */ } } } float playerDist = NPC_EntRangeFromBolt( player, NPC->genericBolt1 ); if ( playerDist < 256.0f ) { CGCam_Shake( 1.0f*playerDist/128.0f, 200 ); } }
float NPC_EnemyRangeFromBolt( int boltIndex ) { return (NPC_EntRangeFromBolt( NPC->enemy, boltIndex )); }