Example #1
0
void FX_RegenBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
{
	trace_t			tr;
	vec3_t			end;

	VectorMA( origin, REGEN_BEAM_LENGTH, dir, end );

	CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );

	trap_R_AddLightToScene( origin, 30, 235.0f / 255, 74.0f / 255, 102.0f / 255 );

	if ( tr.fraction != 1.0f )
	{
		float radius;

		if ( alt_fire )
			radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
		else
			radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));

		if ( !radius )
			return;

		CG_ImpactMark( cgs.media.regenDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
		trap_R_AddLightToScene( origin, radius*5, 235.0f / 255, 74.0f / 255, 102.0f / 255 );
	}
}
Example #2
0
//TiM - Beam FX for the Neutrino Probe weapon
void FX_ProbeBeam( vec3_t origin, vec3_t dir, int clientNum, qboolean alt_fire )
{
	trace_t			tr;
	refEntity_t		beam;
	vec3_t			end;
	float			scale;

	memset( &beam, 0, sizeof( beam ) );

	if ( alt_fire )
		scale = flrandom(7.0f, 12.0f);
	else
		scale = Q_fabs( 12.0f * sin( cg.time * 0.1f ) );

	VectorMA( origin, PROBE_BEAM_LENGTH, dir, end );

	CG_Trace( &tr, origin, NULL, NULL, end, clientNum, CONTENTS_SOLID );

	trap_R_AddLightToScene( origin, 20, 114.0f / 255, 164.0f / 255, 1.0f );

	VectorCopy( origin, beam.origin);
	VectorCopy( tr.endpos, beam.oldorigin );
	beam.reType = RT_LINE;	
	beam.customShader = cgs.media.probeBeam;
	beam.shaderRGBA[0] = 0xff;
	beam.shaderRGBA[1] = 0xff;
	beam.shaderRGBA[2] = 0xff;
	beam.shaderRGBA[3] = 0xff;
	AxisClear( beam.axis );
	
	beam.data.line.width = scale*0.1;
	beam.data.line.width2 = scale;
	beam.data.line.stscale = 1.0;
	trap_R_AddRefEntityToScene( &beam );

	if ( tr.fraction != 1.0f )
	{
		float radius;

		if ( alt_fire )
			radius = flrandom(1.5f, 3.0f) * (1.0 - (tr.fraction*0.3));
		else
			radius = flrandom(0.5f, 1.5f) * (1.0 - (tr.fraction*0.3));

		if ( !radius )
			return;

		CG_ImpactMark( cgs.media.probeDecal, tr.endpos, tr.plane.normal, 0, 1, 1, 1, 0.2*(1.0-tr.fraction), qfalse, radius, qtrue );
		trap_R_AddLightToScene( origin, radius*5, 114.0f / 255, 164.0f / 255, 1.0f );
	}
}
Example #3
0
static void CG_AddSpawner( localEntity_t *le ) 
{
	refEntity_t	*re;
	vec3_t		dir;
	trace_t		trace;

	re = &le->refEntity;
	if (le->leFlags & LEF_MOVE)
	{
		// kef -- do these two lines _before_ copying origin into oldorigin
		VectorSubtract(re->oldorigin, re->origin, dir);
		VectorNormalize(dir);

		VectorCopy(re->origin, re->oldorigin);
		BG_EvaluateTrajectory( &le->pos, cg.time, re->origin );

		if (le->leFlags & LEF_USE_COLLISION)
		{
			// trace a line from previous position to new position
			CG_Trace( &trace, re->oldorigin, NULL, NULL, re->origin, -1, CONTENTS_SOLID );

			if ( trace.fraction != 1.0 ) 
			{	// Hit something.
				// if it is in a nodrop zone, remove it
				// this keeps gibs from waiting at the bottom of pits of death
				// and floating levels
				if ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) {
					CG_FreeLocalEntity( le );
					return;
				}

				// reflect the velocity on the trace plane
				CG_ReflectVelocity( le, &trace );
			}
			VectorSubtract(re->oldorigin, re->origin, dir);
			VectorNormalize(dir);
		}
	}

	// kef -- here's where I, in my infinite wisdom, have decided to emulate the singleplayer
	//particle think function
	if (cg.time < le->data.spawner.nextthink)
	{
		return;
	}
	le->data.spawner.nextthink = cg.time + (le->data.spawner.delay + 
		(le->data.spawner.delay*flrandom(-le->data.spawner.variance,le->data.spawner.variance)));

	if (le->data.spawner.thinkFn)
	{
		le->data.spawner.thinkFn(le);
	}
	if (le->data.spawner.dontDie)
	{
		le->endTime = le->endTime + 10000;
	}
}
Example #4
0
void FX_ExplodeBits( vec3_t org)
{
	float width, length;
	vec3_t vel, pos;
	int i;

	FX_EnergyGibs(org);

	for (i = 0; i < 32; i++)
	{
		VectorSet(vel, flrandom(-320,320), flrandom(-320,320), flrandom(-100,320));
		VectorCopy(org, pos);
		pos[2] += flrandom(-8, 8);
		length = flrandom(10,20);
		width = flrandom(2.0,4.0);
		FX_AddTrail( pos, vel, qtrue, length, -length, width, -width, 
						1.0f, 1.0f, 0.5f, 1000.0f,  cgs.media.orangeTrailShader);
	}
}
Example #5
0
void FX_PhaserAltFire( vec3_t start, vec3_t end, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
	float		scale = flrandom(13.0f, 17.0f), scale2 = flrandom(2.0f, 6.0f);
	vec3_t		vel, diff, end2;
	int			i = 0, sparks = 0;
	refEntity_t	beam;
	vec3_t		rgb = { 1,0.6,0.5}, rgb2={1,0.3,0};
	float		len;
	int color;

	VectorSubtract(end, start, diff);
	len = VectorNormalize(diff);

	color = 0xff * flrandom(0.75, 1.0);

	if (empty)
	{	// More faint and shaky line.
		scale *= flrandom(0.25,0.75);
	}

	if (len > PHASER_ALT_CONE_LEN)
	{	// Draw beam in two parts...

		// Draw main beam first.
		VectorMA(start, PHASER_ALT_CONE_LEN, diff, end2);

		// Draw starting cone
		memset( &beam, 0, sizeof( beam ) );
		VectorCopy( start, beam.origin);
		VectorCopy( end2, beam.oldorigin );
		beam.reType = RT_LINE2;
		if (empty)
		{
			beam.customShader = cgs.media.phaserAltEmptyShader;
		}
		else
		{
			beam.customShader = cgs.media.phaserAltShader;
		}
		AxisClear( beam.axis );
		beam.shaderRGBA[0] = 0xff;
		beam.shaderRGBA[1] = 0xff*0.3;
		beam.shaderRGBA[2] = 0;
		beam.shaderRGBA[3] = 0xff;
		beam.data.line.width = scale*0.1;
		beam.data.line.width2 = scale;
		beam.data.line.stscale = 1.0;
		trap_R_AddRefEntityToScene( &beam );

		// Draw big thick normal beam for the rest.
		memset( &beam, 0, sizeof( beam ) );
		VectorCopy( end2, beam.oldorigin);
		VectorCopy( end, beam.origin );
		beam.reType = RT_LINE;
		if (empty)
		{
			beam.customShader = cgs.media.phaserAltEmptyShader;
		}
		else
		{
			beam.customShader = cgs.media.phaserAltShader;
		}
		AxisClear( beam.axis );
		beam.shaderRGBA[0] = 0xff;
		beam.shaderRGBA[1] = 0xff*0.3;
		beam.shaderRGBA[2] = 0;
		beam.shaderRGBA[3] = 0xff;
		beam.data.line.width = scale;
		beam.data.line.stscale = 1.0;
		trap_R_AddRefEntityToScene( &beam );

		// Draw beam core, all one bit.
		memset( &beam, 0, sizeof( beam ) );
		VectorCopy( start, beam.origin);
		VectorCopy( end, beam.oldorigin );
		beam.reType = RT_LINE2;
		beam.customShader = cgs.media.phaserShader;
		AxisClear( beam.axis );
		beam.shaderRGBA[0] = color*0.75f;
		beam.shaderRGBA[1] = 0xff*0.5f;
		beam.shaderRGBA[2] = 0xff*0.5f;
		beam.shaderRGBA[3] = 0xff;
		beam.data.line.width = scale2*0.2;
		beam.data.line.width2 = scale2;
		beam.data.line.stscale = 1.0;
		trap_R_AddRefEntityToScene( &beam );
	}
	else
	{	// Draw beam in two parts...
		// Draw beam first.
		memset( &beam, 0, sizeof( beam ) );
		VectorCopy( start, beam.origin);
		VectorCopy( end, beam.oldorigin );
		beam.reType = RT_LINE2;
		beam.customShader = cgs.media.phaserAltShader;
		AxisClear( beam.axis );
		beam.shaderRGBA[0] = 0xff;
		beam.shaderRGBA[1] = 0xff*0.3;
		beam.shaderRGBA[2] = 0;
		beam.shaderRGBA[3] = 0xff;
		beam.data.line.width = scale*0.1;
		beam.data.line.width2 = scale;
		beam.data.line.stscale = 1.0;
		trap_R_AddRefEntityToScene( &beam );

		// just one beam is never enough
		memset( &beam, 0, sizeof( beam ) );
		VectorCopy( start, beam.origin);
		VectorCopy( end, beam.oldorigin );
		beam.reType = RT_LINE2;
		beam.customShader = cgs.media.phaserShader;
		AxisClear( beam.axis );
		beam.shaderRGBA[0] = color*0.75f;
		beam.shaderRGBA[1] = 0xff*0.5f;
		beam.shaderRGBA[2] = 0xff*0.5f;
		beam.shaderRGBA[3] = 0xff;
		beam.data.line.width = scale2*0.2;
		beam.data.line.width2 = scale2;
		beam.data.line.stscale = 1.0;
		trap_R_AddRefEntityToScene( &beam );
	}
	

	// Phaser beam
//	FX_AddLine( start, end, 1.0f, scale, 0.0f, 0.9f, 0.9f, 2, cgs.media.phaserShader );
//	FX_AddLine( start, end, 1.0f, scale * 0.5f, 0.0f, 0.8f, 0.8f, 2, cgs.media.phaserShader );
	
	// Per frame impact mark
	FX_AddQuad( end, normal, random() * 1.5 + 1.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.sparkShader );
	FX_AddQuad( end, normal, random() * 5 + 2.75f, 0.0f, 1.0f, 0.0f, 0.0f, 1, cgs.media.yellowParticleShader );

	// Multi frame impacts--never do this when it hits a player because it will just look stupid
	if ( impact )
	{
		FX_AddQuad2( end, normal, random() * 2.0 + 5.0f, 2.5f, 0.6f, 0.0f, rgb, rgb2, 0.0f, 500 + random() * 200, 
					cgs.media.sunnyFlareShader );

		CG_ImpactMark( cgs.media.scavMarkShader, end, normal, random()*360, 1,1,1,0.1, qfalse, 
					random() + 6.0, qfalse );
	}

	// "Fun" sparks
	if ( spark )
	{
		// kef -- fixme. dunno what the deal is with this velocity vector
		VectorClear(vel);
		sparks = (rand() & 3) + 1;

		// Set random starting pos...
		end2[0] = flrandom(-1.0, 1.0) + end[0];
		end2[1] = flrandom(-1.0, 1.0) + end[1];
		end2[2] = flrandom(-1.0, 1.0) + end[2];
		for( i = 0; i < sparks; i++ )
		{	
			scale = 0.5f + (random() * 0.5);
			FXE_Spray( normal, 200, 75, 0.8f, /*1024*/vel);
			FX_AddTrail2(	end2, vel, qfalse,
							8.0f, -8.0f,
							scale, -scale, 0.5f, 0.0f, rgb, rgb2, 0.4f, 500.0f, cgs.media.sparkShader );
		}

		VectorMA(end, -8, diff, end2);
		// Add a hit sprite over everything...
		memset( &beam, 0, sizeof( beam ) );
		VectorCopy( end2, beam.origin);
		beam.reType = RT_SPRITE;
		beam.customShader = cgs.media.sunnyFlareShader;
		AxisClear( beam.axis );
		beam.shaderRGBA[0] = 0xff*1.0f;
		beam.shaderRGBA[1] = 0xff*0.9f;
		beam.shaderRGBA[2] = 0xff*0.8f;
		beam.shaderRGBA[3] = 0xff;
		beam.data.sprite.radius = random()*2.0 + 9.0;
		trap_R_AddRefEntityToScene( &beam );
	}
}
Example #6
0
/**
 * \brief Alt quantum burst projectile think functiom.
 *
 * Alt quantum burst projectile think function.
 *
 * @param ent the projectile
 */
static void WP_QuantumAltThink(gentity_t *ent)
{
	vec3_t start, newdir, targetdir, lup={0,0,1}, lright, search; 
	float dot, dot2;

	ent->health--;
	if (ent->health<=0)
	{
		G_FreeEntity(ent);
		return;
	}

	if (ent->target_ent)
	{	/* Already have a target, start homing. */
		if (ent->health <= 0 || !ent->inuse)
		{	/* No longer target this */
			ent->target_ent = NULL;
			ent->nextthink = level.time + 1000;
			ent->health -= 5;
			return;
		}
		VectorSubtract(ent->target_ent->r.currentOrigin, ent->r.currentOrigin, targetdir);
		VectorNormalize(targetdir);

		/* Now the rocket can't do a 180 in space, so we'll limit the turn to about 45 degrees. */
		dot = DotProduct(targetdir, ent->movedir);
		/* a dot of 1.0 means right-on-target. */
		if (dot < 0.0)
		{	/* Go in the direction opposite, start a 180. */
			CrossProduct(ent->movedir, lup, lright);
			dot2 = DotProduct(targetdir, lright);
			if (dot2 > 0)
			{	/* Turn 45 degrees right. */
				VectorAdd(ent->movedir, lright, newdir);
			}
			else
			{	/* Turn 45 degrees left. */
				VectorSubtract(ent->movedir, lright, newdir);
			}
			/* Yeah we've adjusted horizontally, but let's split the difference vertically, so we kinda try to move towards it. */
			newdir[2] = (targetdir[2] + ent->movedir[2]) * 0.5;
			VectorNormalize(newdir);
		}
		else if (dot < 0.7)
		{	/* Need about one correcting turn.  Generate by meeting the target direction "halfway". */
			/* Note, this is less than a 45 degree turn, but it is sufficient.  We do this because the rocket may have to go UP. */
			VectorAdd(ent->movedir, targetdir, newdir);
			VectorNormalize(newdir);
		}
		else
		{	/* else adjust to right on target. */
			VectorCopy(targetdir, newdir);
		}

		VectorScale(newdir, rpg_altPhotonSpeed.integer, ent->s.pos.trDelta);
		VectorCopy(newdir, ent->movedir);
		SnapVector(ent->s.pos.trDelta);			/* save net bandwidth */
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);
		SnapVector(ent->s.pos.trBase);
		ent->s.pos.trTime = level.time;

		/* Home at a reduced frequency. */
		ent->nextthink = level.time + QUANTUM_ALT_THINK_TIME;	/* Nothing at all spectacular happened, continue. */
	}
	else
	{	/* Search in front of the missile for targets. */
		VectorCopy(ent->r.currentOrigin, start);
		CrossProduct(ent->movedir, lup, lright);

		/* Search straight ahead. */
		VectorMA(start, QUANTUM_ALT_SEARCH_DIST, ent->movedir, search);

		/* Add some small randomness to the search Z height, to give a bit of variation to where we are searching. */
		search[2] += flrandom(-QUANTUM_ALT_SEARCH_DIST*0.075, QUANTUM_ALT_SEARCH_DIST*0.075);

		if (SearchTarget(ent, start, search))
			return;

		/* Search to the right. */
		VectorMA(search, QUANTUM_ALT_SEARCH_DIST*0.1, lright, search);
		if (SearchTarget(ent, start, search))
			return;
		
		/* Search to the left. */
		VectorMA(search, -QUANTUM_ALT_SEARCH_DIST*0.2, lright, search);
		if (SearchTarget(ent, start, search))
			return;

		/* Search at a higher rate than correction. */
		ent->nextthink = level.time + QUANTUM_ALT_SEARCH_TIME;	/* Nothing at all spectacular happened, continue. */

	}
	return;
}
Example #7
0
void FX_EnergyGibs(vec3_t origin )
{
	localEntity_t	*le;
	refEntity_t		*re;
	vec3_t			dir;
	int				i, j, k;
	int				chunkModel=0;
	float			baseScale = 0.7f, dist;
	int				numChunks;

	numChunks = irandom( 10, 15 );

	VectorSubtract(cg.snap->ps.origin, origin, dir);
	dist = VectorLength(dir);
	if (dist > 512)
	{
		numChunks *= 512.0/dist;		// 1/2 at 1024, 1/4 at 2048, etc.
	}

	for ( i = 0; i < numChunks; i++ )
	{
		chunkModel = cgs.media.chunkModels[MT_METAL][irandom(0,5)];

		le = CG_AllocLocalEntity();
		re = &le->refEntity;

		le->leType = LE_FRAGMENT;
		le->endTime = cg.time + 2000;

		VectorCopy( origin, re->origin );

		for ( j = 0; j < 3; j++ )
		{
			re->origin[j] += crandom() * 12;
		}
		VectorCopy( re->origin, le->pos.trBase );

		//Velocity
		VectorSet( dir, crandom(), crandom(), crandom() );
		VectorScale( dir, flrandom( 300, 500 ), le->pos.trDelta );

		//Angular Velocity
		VectorSet( le->angles.trBase, crandom() * 360, crandom() * 360, crandom() * 360 );
		VectorSet( le->angles.trDelta, crandom() * 90, crandom() * 90, crandom() * 90 );

		AxisCopy( axisDefault, re->axis );

		le->data.fragment.radius = flrandom(baseScale * 0.4f, baseScale * 0.8f );

		re->nonNormalizedAxes = qtrue;
		re->hModel = chunkModel;
		re->renderfx |= RF_CAP_FRAMES;
		re->customShader = cgs.media.quantumDisruptorShader;
		re->shaderTime = cg.time/1000.0f;
		
		le->pos.trType = TR_GRAVITY;
		le->pos.trTime = cg.time;
		le->angles.trType = TR_INTERPOLATE;
		le->angles.trTime = cg.time;
		le->bounceFactor = 0.2f + random() * 0.2f;
		le->leFlags |= LEF_TUMBLE;

		re->shaderRGBA[0] = re->shaderRGBA[1] = re->shaderRGBA[2] = re->shaderRGBA[3] = 255;

		// Make sure that we have the desired start size set
		for( k = 0; k < 3; k++)
		{
			VectorScale(le->refEntity.axis[k], le->data.fragment.radius, le->refEntity.axis[k]);
		}
	}
}
Example #8
0
/***
Get a random float from the range of floats defined by and including i and j.
@function flrandom
@param i Number, lower limit.
@param j Number, upper limit.
@return A random float from the range of floats defined by and including i and j.
*/
static int Qmath_FLrandom(lua_State * L)
{
	lua_pushnumber(L, flrandom(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
	return 1;
}