static void CreateNewZap( gentity_t *creator, gentity_t *target ) { int i; zap_t *zap; for ( i = 0; i < MAX_ZAPS; i++ ) { zap = &zaps[ i ]; if ( zap->used ) { continue; } zap->used = qtrue; zap->timeToLive = LEVEL2_AREAZAP_TIME; zap->creator = creator; zap->targets[ 0 ] = target; zap->numTargets = 1; // the zap chains only through living entities if ( target->health > 0 ) { G_Damage( target, creator, creator, forward, target->s.origin, LEVEL2_AREAZAP_DMG, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); FindZapChainTargets( zap ); for ( i = 1; i < zap->numTargets; i++ ) { G_Damage( zap->targets[ i ], target, zap->creator, forward, target->s.origin, LEVEL2_AREAZAP_DMG * ( 1 - powf( ( zap->distances[ i ] / LEVEL2_AREAZAP_CHAIN_RANGE ), LEVEL2_AREAZAP_CHAIN_FALLOFF ) ) + 1, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); } } zap->effectChannel = G_NewEntity(); zap->effectChannel->s.eType = ET_LEV2_ZAP_CHAIN; zap->effectChannel->classname = "lev2zapchain"; UpdateZapEffect( zap ); return; } }
static void CreateNewZap( gentity_t *creator, gentity_t *target ) { int i; zap_t *zap; for ( i = 0; i < MAX_ZAPS; i++ ) { zap = &zaps[ i ]; if ( zap->used ) { continue; } zap->used = true; zap->timeToLive = LEVEL2_AREAZAP_TIME; zap->creator = creator; zap->targets[ 0 ] = target; zap->numTargets = 1; // Zap chains only originate from alive entities. if (target->entity->Damage((float)LEVEL2_AREAZAP_DMG, creator, Vec3::Load(target->s.origin), Vec3::Load(forward), DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP)) { FindZapChainTargets( zap ); for ( i = 1; i < zap->numTargets; i++ ) { float damage = LEVEL2_AREAZAP_DMG * ( 1 - powf( ( zap->distances[ i ] / LEVEL2_AREAZAP_CHAIN_RANGE ), LEVEL2_AREAZAP_CHAIN_FALLOFF ) ) + 1; target->entity->Damage(damage, zap->creator, Vec3::Load(target->s.origin), Vec3::Load(forward), DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP); } } zap->effectChannel = G_NewEntity(); zap->effectChannel->s.eType = ET_LEV2_ZAP_CHAIN; zap->effectChannel->classname = "lev2zapchain"; UpdateZapEffect( zap ); return; } }
void G_UpdateZaps( int msec ) { int i, j; zap_t *zap; for ( i = 0; i < MAX_ZAPS; i++ ) { zap = &zaps[ i ]; if ( !zap->used ) { continue; } zap->timeToLive -= msec; // first, the disappearance of players is handled immediately in G_ClearPlayerZapEffects() // the deconstruction or gibbing of a directly targeted buildable destroys the whole zap effect if ( zap->timeToLive <= 0 || !zap->targets[ 0 ]->inuse ) { G_FreeEntity( zap->effectChannel ); zap->used = qfalse; continue; } // the deconstruction or gibbing of chained buildables destroy the appropriate beams for ( j = 1; j < zap->numTargets; j++ ) { if ( !zap->targets[ j ]->inuse ) { zap->targets[ j-- ] = zap->targets[ --zap->numTargets ]; } } UpdateZapEffect( zap ); } }