/* =============== G_CreateNewZap =============== */ static void G_CreateNewZap( gentity_t *creator, gentity_t *target ) { int i, j; zap_t *zap; for( i = 0; i < MAX_ZAPS; i++ ) { zap = &zaps[ i ]; if( !zap->used ) { zap->used = qtrue; zap->timeToLive = LEVEL2_AREAZAP_TIME; zap->creator = creator; zap->targets[ 0 ] = target; zap->numTargets = 1; for( j = 1; j < MAX_ZAP_TARGETS && zap->targets[ j - 1 ]; j++ ) { zap->targets[ j ] = G_FindNewZapTarget( zap->targets[ j - 1 ] ); if( zap->targets[ j ] ) zap->numTargets++; } zap->effectChannel = G_Spawn( ); G_UpdateZapEffect( zap ); return; } } }
/* =============== G_UpdateZaps =============== */ void G_UpdateZaps( int msec ) { int i, j; zap_t *zap; int damage; for( i = 0; i < MAX_ZAPS; i++ ) { zap = &zaps[ i ]; if( zap->used ) { //check each target is valid for( j = 0; j < zap->numTargets; j++ ) { gentity_t *source; gentity_t *target = zap->targets[ j ]; if( j == 0 ) source = zap->creator; else source = zap->targets[ j - 1 ]; if( target->health <= 0 || !target->inuse || //early out Distance( source->s.origin, target->s.origin ) > LEVEL2_AREAZAP_RANGE ) { target = zap->targets[ j ] = G_FindNewZapTarget( source ); //couldn't find a target, so forget about the rest of the chain if( !target ) zap->numTargets = j; } } if( zap->numTargets ) { for( j = 0; j < zap->numTargets; j++ ) { gentity_t *source; gentity_t *target = zap->targets[ j ]; float r = 1.0f / zap->numTargets; float damageFraction = 2 * r - 2 * j * r * r - r * r; vec3_t forward; if( j == 0 ) source = zap->creator; else source = zap->targets[ j - 1 ]; damage = ceil( ( (float)msec / LEVEL2_AREAZAP_TIME ) * LEVEL2_AREAZAP_DMG * damageFraction ); VectorSubtract( target->s.origin, source->s.origin, forward ); VectorNormalize( forward ); //do the damage if( damage ) G_Damage( target, source, zap->creator, forward, target->s.origin, damage, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); } } G_UpdateZapEffect( zap ); zap->timeToLive -= msec; if( zap->timeToLive <= 0 || zap->numTargets == 0 || zap->creator->health <= 0 ) { zap->used = qfalse; G_FreeEntity( zap->effectChannel ); } } } }
/* =============== G_UpdateZaps =============== */ void G_UpdateZaps( int msec ) { int i, j; zap_t *zap; int damage; for( i = 0; i < MAX_ZAPS; i++ ) { zap = &zaps[ i ]; if( zap->used ) { //check each target is valid for( j = 0; j < zap->numTargets; j++ ) { gentity_t *source; gentity_t *target = zap->targets[ j ]; if( j == 0 ) source = zap->creator; else source = zap->targets[ j - 1 ]; if( target->health <= 0 || !target->inuse || //early out Distance( source->s.origin, target->s.origin ) > LEVEL2_AREAZAP_RANGE ) { target = zap->targets[ j ] = G_FindNewZapTarget( source ); //couldn't find a target, so forget about the rest of the chain //remove this and the zap won't change targets once target dies; leaves a cool zap effect floating about dead body though XD if( !target ) { zap->numTargets = j; /* zap->used = qfalse; //we don't have to aim anymore: G_FreeEntity( zap->effectChannel ); //ripped from below (when target dies and zap transfers to something else //reminder: below, there's added coding for gaining health.//Damn! Doesn't work X(*/ } } } if( zap->numTargets ) { for( j = 0; j < zap->numTargets; j++ ) { gentity_t *source; gentity_t *target = zap->targets[ j ]; float r = 1.0f / zap->numTargets; float damageFraction = 2 * r - 2 * j * r * r - r * r; vec3_t forward; if( j == 0 ) source = zap->creator; else source = zap->targets[ j - 1 ]; damage = ceil( ( (float)msec / LEVEL2_AREAZAP_TIME ) * LEVEL2_AREAZAP_DMG * damageFraction ); /* //source->client->ps.health -= ( 1 ); // *damageFraction //try again... this time for health if( j == 0 ) //repeated from above to make sure its only the marauder gaining health { source->client->ps.stats[ STAT_HEALTH ] += 1; //gain health: vampire mode doesn't seem to work with zap so i added this //still doesn't work }*/ // target->client->ps.stats[ STAT_AMMO ] -= 1; //want to drain energy weapons like KoRx // don't let a high msec value inflate the total damage if( damage + zap->damageUsed > LEVEL2_AREAZAP_DMG ) damage = LEVEL2_AREAZAP_DMG - zap->damageUsed; VectorSubtract( target->s.origin, source->s.origin, forward ); VectorNormalize( forward ); //do the damage if( damage ) { G_Damage( target, source, zap->creator, forward, target->s.origin, damage, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); zap->damageUsed += damage; } } } G_UpdateZapEffect( zap ); zap->timeToLive -= msec; if( zap->timeToLive <= 0 || zap->numTargets == 0 || zap->creator->health <= 0 ) { zap->used = qfalse; G_FreeEntity( zap->effectChannel ); } } } }