Exemplo n.º 1
0
static edict_t *G_Fire_WeakBolt( vec3_t origin, vec3_t angles, firedef_t *firedef, edict_t *owner, int seed )
{
	int speed, maxknockback, minknockback, stun, mod;
	float maxdamage, mindamage;
	int timeDelta;

	// FIXME2: projectiles go slower underwater, do this at the actual firing function

	timeDelta = 0;
	if( owner && owner->r.client )
		timeDelta = owner->r.client->timeDelta;

	if( firedef->spread )
		G_LocalSpread( angles, firedef->spread, seed );

	mod = ( firedef->fire_mode == FIRE_MODE_STRONG ) ? MOD_ELECTROBOLT_S : MOD_ELECTROBOLT_W;
	speed = firedef->speed;
	maxdamage = firedef->damage;
	mindamage = firedef->mindamage;
	maxknockback = firedef->knockback;
	minknockback = firedef->minknockback;
	stun = firedef->stun;

	if( is_quad )
	{
		mindamage *= QUAD_DAMAGE_SCALE;
		maxdamage *= QUAD_DAMAGE_SCALE;
		maxknockback *= QUAD_KNOCKBACK_SCALE;
	}
#ifdef ELECTROBOLT_TEST
	W_Fire_Electrobolt_Combined( owner, origin, angles, maxdamage, mindamage,
		maxknockback, minknockback, stun, firedef->timeout, mod, timeDelta );

	return NULL;
#else
	return W_Fire_Electrobolt_Weak( owner, origin, angles, speed, maxdamage, minknockback, maxknockback, stun,
		firedef->timeout, mod, timeDelta );
#endif
}
Exemplo n.º 2
0
/*
* W_Fire_Electrobolt_Combined
*/
void W_Fire_Electrobolt_Combined( edict_t *self, vec3_t start, vec3_t angles, float maxdamage, float mindamage, float maxknockback, float minknockback, int stun, int range, int mod, int timeDelta )
{
	vec3_t from, end, dir;
	trace_t	tr;
	edict_t	*ignore, *event, *hit, *damaged;
	int mask;
	qboolean missed = qtrue;
	int dmgflags = 0;
	int fireMode;

#ifdef ELECTROBOLT_TEST
	fireMode = FIRE_MODE_WEAK;
#else
	fireMode = FIRE_MODE_STRONG;
#endif

	if( GS_Instagib() )
		maxdamage = mindamage = 9999;

	AngleVectors( angles, dir, NULL, NULL );
	VectorMA( start, range, dir, end );
	VectorCopy( start, from );

	ignore = self;
	hit = damaged = NULL;

	mask = MASK_SHOT;
	if( GS_RaceGametype() )
		mask = MASK_SOLID;

	clamp_high( mindamage, maxdamage );
	clamp_high( minknockback, maxknockback );

	tr.ent = -1;
	while( ignore )
	{
		G_Trace4D( &tr, from, NULL, NULL, end, ignore, mask, timeDelta );

		VectorCopy( tr.endpos, from );
		ignore = NULL;

		if( tr.ent == -1 )
			break;

		// some entity was touched
		hit = &game.edicts[tr.ent];
		if( hit == world )  // stop dead if hit the world
			break;
		if( hit->movetype == MOVETYPE_NONE || hit->movetype == MOVETYPE_PUSH )
			break;

		// allow trail to go through BBOX entities (players, gibs, etc)
		if( !ISBRUSHMODEL( hit->s.modelindex ) )
			ignore = hit;

		if( ( hit != self ) && ( hit->takedamage ) )
		{
			float frac, damage, knockback;

			frac = DistanceFast( tr.endpos, start ) / (float)range;
			clamp( frac, 0.0f, 1.0f );

			damage = maxdamage - ( ( maxdamage - mindamage ) * frac );
			knockback = maxknockback - ( ( maxknockback - minknockback ) * frac );

			G_Damage( hit, self, self, dir, dir, tr.endpos, damage, knockback, stun, dmgflags, mod );
			
			// spawn a impact event on each damaged ent
			event = G_SpawnEvent( EV_BOLT_EXPLOSION, DirToByte( tr.plane.normal ), tr.endpos );
			event->s.firemode = fireMode;
			if( hit->r.client )
				missed = qfalse;

			damaged = hit;
		}
	}

	if( missed && self->r.client )
		G_AwardPlayerMissedElectrobolt( self, mod );

	// send the weapon fire effect
	event = G_SpawnEvent( EV_ELECTROTRAIL, ENTNUM( self ), start );
	event->r.svflags = SVF_TRANSMITORIGIN2;
	VectorScale( dir, 1024, event->s.origin2 );
	event->s.firemode = fireMode;

	if( !GS_Instagib() && tr.ent == -1 )	// didn't touch anything, not even a wall
	{
		edict_t *bolt;
		gs_weapon_definition_t *weapondef = GS_GetWeaponDef( self->s.weapon );

		// fire a weak EB from the end position
		bolt = W_Fire_Electrobolt_Weak( self, end, angles, weapondef->firedef_weak.speed, mindamage, minknockback, minknockback, stun, weapondef->firedef_weak.timeout, mod, timeDelta );
		bolt->enemy = damaged;
	}
}