예제 #1
0
void CG_FragmentBounceMark( localEntity_t *le, trace_t *trace ) {
#if 0
	if ( le->leMarkType == LEMT_BLOOD )
		CG_ImpactMark( media.gfx.world.bloodMark, trace->endpos, trace->plane.normal, random()*360, 1,1,1,1, qtrue, radius, qfalse );
	else if ( le->leMarkType == LEMT_BURN )
		CG_ImpactMark( media.gfx.world.burnMark, trace->endpos, trace->plane.normal, random()*360, 1,1,1,1, qtrue, radius, qfalse );
#endif

	// don't allow a fragment to make multiple marks, or they
	// pile up while settling
	le->leMarkType = LEMT_NONE;
}
예제 #2
0
/*
=======================================================================================================================================
CG_FragmentBounceMark
=======================================================================================================================================
*/
void CG_FragmentBounceMark(localEntity_t *le, trace_t *trace) {
	int markRadius;

	if (le->leMarkType == LEMT_BLOOD) {
		markRadius = 16 + (rand()&31);
		CG_ImpactMark(cgs.media.bloodMarkShader, trace->endpos, trace->plane.normal, random() * 360, 1, 1, 1, 1, qtrue, markRadius, qfalse);
	} else if (le->leMarkType == LEMT_BURN) {
		markRadius = 8 + (rand()&15);
		CG_ImpactMark(cgs.media.burnMarkShader, trace->endpos, trace->plane.normal, random() * 360, 1, 1, 1, 1, qtrue, markRadius, qfalse);
	}
	// don't allow a fragment to make multiple marks, or they pile up while settling
	le->leMarkType = LEMT_NONE;
}
예제 #3
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 );
	}
}
예제 #4
0
/*
================
CG_FragmentBounceMark
================
*/
void CG_FragmentBounceMark( localEntity_t *le, trace_t *trace )
{
	int    radius;
	vec4_t projection, color;

	if ( le->leMarkType == LEMT_BLOOD )
	{
		static int lastBloodMark;

		// don't drop too many blood marks
		if ( !( lastBloodMark > cg.time || lastBloodMark > cg.time - 100 ) )
		{
			radius = 16 + ( rand() & 31 );
			//% CG_ImpactMark( cgs.media.bloodDotShaders[rand()%5], trace->endpos, trace->plane.normal, random()*360,
			//%     1,1,1,1, qtrue, radius, qfalse, cg_bloodTime.integer * 1000 );
#if 0
			VectorSubtract( vec3_origin, trace->plane.normal, projection );
			projection[ 3 ] = radius * 2.0f;
			VectorMA( trace->endpos, -8.0f, projection, markOrigin );
			CG_ImpactMark( cgs.media.bloodDotShaders[ rand() % 5 ], markOrigin, projection, radius, random() * 360.0f, 1.0f, 1.0f,
			               1.0f, 1.0f, cg_bloodTime.integer * 1000 );
#else
			VectorSet( projection, 0, 0, -1 );
			projection[ 3 ] = radius;
			Vector4Set( color, 1.0f, 1.0f, 1.0f, 1.0f );
			trap_R_ProjectDecal( cgs.media.bloodDotShaders[ rand() % 5 ], 1, ( vec3_t * ) trace->endpos, projection, color,
			                     cg_bloodTime.integer * 1000, ( cg_bloodTime.integer * 1000 ) >> 4 );
#endif
			lastBloodMark = cg.time;
		}
	}
void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm )
{
	localEntity_t	*le;
	FXTrail			*fx;
	vec3_t			direction, org;

	//Orient the explosions to face the camera
	VectorSubtract( cg.refdef.vieworg, origin, direction );
	VectorNormalize( direction );

	VectorMA( origin, 12, direction, org );
	// Add an explosion and tag a light to it
	le = CG_MakeExplosion( org, direction, cgs.media.explosionModel, 6, cgs.media.surfaceExplosionShader, 700, qfalse, 1.2f + (random()*0.3f) );
	le->light = 150;
	le->refEntity.renderfx |= RF_NOSHADOW;
	VectorSet( le->lightColor, 1.0f, 0.6f, 0.6f );

	for ( int i = 0; i < 6; i++)
	{
	fx = FX_AddTrail( origin, NULL, NULL, 16.0f, -15.0f,
								1.5, -1.5, 1.0f, 1.0f, 0.2f, 1000.0f,  cgs.media.orangeTrailShader, rand() & FXF_BOUNCE );

	if ( fx == NULL )
		return;

	FXE_Spray( norm, 500, 175, 0.8f, 512, (FXPrimitive *) fx );
	}

	cgi_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeAltExplodeSnd );	

	CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse, 
					random() * 16 + 48, qfalse );

	CG_ExplosionEffects( origin, 2.0, 350 );
}
예제 #6
0
void FX_ProtonAltMiss( vec3_t origin, vec3_t normal )
{
	vec3_t	new_org;
	vec3_t	velocity;
	float	scale, dscale;
	int		i;

	// Smoke puffs
	for ( i = 0; i < 8; i++ )
	{
		scale = random() * 12.0f + 4.0f;
		dscale = random() * 12.0f + 8.0f;

		VectorMA( origin, random() * 8.0f, normal, new_org );
		
		velocity[0] = normal[0] * crandom() * 24.0f;
		velocity[1] = normal[1] * crandom() * 24.0f;
		velocity[2] = normal[2] * ( random() * 24.0f + 8.0f ) + 8.0f; // move mostly up

		FX_AddSprite( new_org, 
					velocity, NULL, 
					scale, dscale,
					random() * 0.5f + 0.5f, 0.0f,
					random() * 45.0f,
					0.0f,
					800 + random() * 300.0f,
					cgs.media.steamShader );
	}

	// Scorch mark
	CG_ImpactMark( cgs.media.bulletmarksShader, origin, normal, random()*360, 1,1,1,1, qfalse, 6, qfalse );
//	FX_ProtonHit( origin );

	CG_ExplosionEffects( origin, 1.0f, 150 );
}
예제 #7
0
/*
==================
CG_Creep
==================
*/
static void CG_Creep( centity_t *cent )
{
  int           msec;
  float         size, frac;
  trace_t       tr;
  vec3_t        temp, origin;
  int           scaleUpTime = BG_Buildable( cent->currentState.modelindex )->buildTime;
  int           time;
  // int creepSize;
  time = cent->currentState.time;

  //should the creep be growing or receding?
  if( time >= 0 )
  {
    msec = cg.time - time;
    if( msec >= 0 && msec < scaleUpTime )
      frac = (float)msec / scaleUpTime;
    else
      frac = 1.0f;
  }
  else if( time < 0 )
  {
    msec = cg.time + time;
    if( msec >= 0 && msec < CREEP_SCALEDOWN_TIME )
      frac = 1.0f - ( (float)msec / CREEP_SCALEDOWN_TIME );
    else
      frac = 0.0f;
  }

  VectorCopy( cent->currentState.origin2, temp );
  VectorScale( temp, -CREEP_DISTANCE, temp );
  VectorAdd( temp, cent->lerpOrigin, temp );

  
  
  CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, temp, cent->currentState.number, MASK_PLAYERSOLID );
  VectorCopy( tr.endpos, origin );
  

//  size = CREEP_SIZE * frac;
size = BG_Buildable( cent->currentState.modelindex )->creepSize * frac;

  if( size > 0.0f && tr.fraction < 1.0f )
    CG_ImpactMark( cgs.media.creepShader, //qhandle_t markShader
								  origin, //const vec3_t origin 
			  cent->currentState.origin2, //const vec3_t dir
									0.0f, //float orientation
									1.0f, //red
									1.0f, //green
									1.0f, //blue
									1.0f, //float alpha
								  qtrue, //qboolean alphaFade
								    size, //float radius
								   qtrue);//qboolean temporary
								   
					   

}
예제 #8
0
// LEILEI 
void CG_GoreMark( localEntity_t *le, trace_t *trace ) {
	int			radius;

	if ( le->leMarkType == LEMT_BURN ) {

		radius = 6 + (rand()&16);
		CG_ImpactMark( cgs.media.lbldShader2, trace->endpos, trace->plane.normal, random()*360,
			1,1,1,1, qtrue, radius, qfalse );
	
	}

	le->leMarkType = LEMT_NONE;
}
예제 #9
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 );
	}
}
예제 #10
0
/*
================
CG_FragmentBounceMark
================
*/
void CG_FragmentBounceMark(localEntity_t * le, trace_t * trace)
{
	int             radius, r = 0;
	qhandle_t       h;

	if(le->leMarkType == LEMT_BLOOD)
	{

		radius = 16 + (rand() & 31);
		r = rand() & 3;

		if(r == 0)
		{
			h = cgs.media.bloodMarkShader;
		}
		else if(r == 1)
		{
			h = cgs.media.bloodMark2Shader;
		}
		else
		{
			h = cgs.media.bloodMark3Shader;
		}
		CG_ImpactMark(h, trace->endpos, trace->plane.normal, random() * 360, 1, 1, 1, 1, qtrue, radius, qfalse);
	}
	else if(le->leMarkType == LEMT_BURN)
	{

		radius = 8 + (rand() & 15);
		CG_ImpactMark(cgs.media.burnMarkShader, trace->endpos, trace->plane.normal, random() * 360,
					  1, 1, 1, 1, qtrue, radius, qfalse);
	}


	// don't allow a fragment to make multiple marks, or they
	// pile up while settling
	le->leMarkType = LEMT_NONE;
}
예제 #11
0
/*
==================
CG_Creep
==================
*/
static void CG_Creep( centity_t *cent )
{
  int           msec;
  float         size, frac;
  trace_t       tr;
  vec3_t        temp, origin;
  int           scaleUpTime = BG_FindBuildTimeForBuildable( cent->currentState.modelindex );
  int           time;

  time = cent->currentState.time;

  //should the creep be growing or receding?
  if( time >= 0 )
  {
    msec = cg.time - time;
    if( msec >= 0 && msec < scaleUpTime )
      frac = (float)msec / scaleUpTime;
    else
      frac = 1.0f;
  }
  else if( time < 0 )
  {
    msec = cg.time + time;
    if( msec >= 0 && msec < CREEP_SCALEDOWN_TIME )
      frac = 1.0f - ( (float)msec / CREEP_SCALEDOWN_TIME );
    else
      frac = 0.0f;
  }

  VectorCopy( cent->currentState.origin2, temp );
  VectorScale( temp, -4096, temp );
  VectorAdd( temp, cent->lerpOrigin, temp );

  CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, temp, cent->currentState.number, MASK_PLAYERSOLID );

  VectorCopy( tr.endpos, origin );

  size = CREEP_SIZE * frac;

  if( size > 0.0f )
    CG_ImpactMark( cgs.media.creepShader, origin, cent->currentState.origin2,
                   0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, size, qtrue );
}
예제 #12
0
/*
================
CG_FragmentBounceMark
================
*/
void CG_FragmentBounceMark( localEntity_t *le, trace_t *trace ) {
	int			radius;

	if ( le->leMarkType == LEMT_BLOOD ) {
		static int lastBloodMark;

		// don't drop too many blood marks
		if (!(lastBloodMark > cg.time || lastBloodMark > cg.time-100)) {
			radius = 16 + (rand()&31);
			CG_ImpactMark( cgs.media.bloodDotShaders[rand()%5], trace->endpos, trace->plane.normal, random()*360,
				1,1,1,1, qtrue, radius, qfalse, cg_bloodTime.integer * 1000 );

			lastBloodMark = cg.time;
		}
	}

	// don't allow a fragment to make multiple marks, or they
	// pile up while settling
	le->leMarkType = LEMT_NONE;
}
예제 #13
0
/*
================
CG_ProjectedSpotLight
================
*/
void CG_ProjectedSpotLight( vec3_t start, vec3_t dir ) {
	vec3_t end, proj;
	trace_t tr;
	float alpha, radius;

	VectorMA( start, 1000, dir, end );
	CG_Trace( &tr, start, NULL, NULL, end, -1, CONTENTS_SOLID );
	if ( tr.fraction == 1.0 ) {
		return;
	}
	//
	alpha = ( 1.0 - tr.fraction );
	if ( alpha > 1.0 ) {
		alpha = 1.0;
	}
	//
	radius = 32 + 64 * tr.fraction;
	VectorNegate( dir, proj );
	CG_ImpactMark( cgs.media.spotLightShader, tr.endpos, proj, 0, alpha, alpha, alpha, 1.0, qfalse, radius, qtrue, -2 );
}
void FX_GrenadeExplode( vec3_t origin, vec3_t normal )
{
	localEntity_t	*le;
	FXTrail			*fx;
	vec3_t			direction, org;

	VectorSet( direction, 0,0,1 );

	// Add an explosion and tag a light to it
	le = CG_MakeExplosion( origin, direction, cgs.media.nukeModel, 5, NULL, 250, qfalse, 25.0f, LEF_FADE_RGB );
	le->light = 150;
	le->refEntity.renderfx |= RF_NOSHADOW;

	VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );

	// Ground ring
	FX_AddQuad( origin, normal, NULL, NULL, 5, 330, 1.0, 0.0, random() * 360, 0, 0, 300, cgs.media.bigShockShader );
	// Flare
	VectorMA( origin, 12, direction, org );
	FX_AddSprite( org, NULL, NULL, 160.0, -540.0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.sunnyFlareShader );

	for ( int i = 0; i < 12; i++)
	{
		fx = FX_AddTrail( origin, NULL, NULL, 24.0f + random() * 12, -40.0f,
								0.5 + random() * 2, -3.0, 1.0f, 1.0f, 0.5f, 1000.0f,  cgs.media.orangeTrailShader, rand() & FXF_BOUNCE );


		if ( fx == NULL )
			return;
		
		FXE_Spray( normal, 470, 325, 0.5f, 700, (FXPrimitive *) fx );
	}

	cgi_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSnd );	

	// Smoke and impact
	CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse, 
					random() * 16 + 48, qfalse );

	CG_ExplosionEffects( origin, 3.0f, 400 );
}
예제 #15
0
void FX_GrenadeExplode( vec3_t origin, vec3_t normal )
{
	localEntity_t	*le;
	qhandle_t	null = 0;
	vec3_t			direction, org, vel;
	int i;

	VectorSet( direction, 0,0,1 );

	// Add an explosion and tag a light to it
	le = CG_MakeExplosion2( origin, direction, cgs.media.nukeModel, 5, null, 250, qfalse, 25.0f, LEF_FADE_RGB);
	le->light = 150;
	le->refEntity.renderfx |= RF_NOSHADOW;

	VectorSet( le->lightColor, 1.0f, 0.6f, 0.2f );

	// Ground ring
	FX_AddQuad( origin, normal, 5, 100, 1.0, 0.0, random() * 360, 300, cgs.media.bigShockShader );
	// Flare
	VectorMA( origin, 12, direction, org );
	FX_AddSprite( org, NULL, qfalse, 160.0, -160.0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.sunnyFlareShader );//, FXF_NON_LINEAR_FADE );

	for (i = 0; i < 12; i++)
	{
		float width, length;
		FXE_Spray( normal, 470, 325, 0.5f, vel);
		length = 24.0 + random() * 12;
		width = 0.5 + random() * 2;
		FX_AddTrail( origin, vel, qtrue, length, -length, width, -width, 
						1.0f, 1.0f, 0.5f, 1000.0f,  cgs.media.orangeTrailShader);
	}

	trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeExplodeSound );	

	// Smoke and impact
//	FX_AddSpawner( origin, normal, NULL, NULL, 100, 25.0f, 2000.0f, (void *) CG_SmokeSpawn, NULL, 1024 );
	CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse, 
				random() * 16 + 48, qfalse );
}
예제 #16
0
//-----------------------------------
//By: RedTechie - Imported/Modifyed from SP
//-----------------------------------
void FX_GrenadeShrapnelExplode( vec3_t origin, vec3_t norm )
{
	localEntity_t	*le;
	//FXTrail			*fx;
	vec3_t			direction, org, vel;
	int				i;

	CG_InitLensFlare( origin, 
						350, 350,
						colorTable[CT_DKRED1], 1.2, 2.0, 1600, 200,
						colorTable[CT_DKRED1], 1600, 200, 800, 20,  qtrue, 
						0, 0, qfalse, qtrue, 
						qfalse, 1.0, cg.time, 90, 0, 300);

	//Orient the explosions to face the camera
	VectorSubtract( cg.refdef.vieworg, origin, direction );
	VectorNormalize( direction );

	VectorMA( origin, 12, direction, org );
	// Add an explosion and tag a light to it
	le = CG_MakeExplosion2( org, direction, cgs.media.explosionModel, 6, cgs.media.surfaceExplosionShader, 700, qfalse, 1.2f + (random()*0.5f),LEF_FADE_RGB ); //RPG-X: RedTechie - Scale use to be 1.2f + (random()*0.3f)
	le->light = 150;
	le->refEntity.renderfx |= RF_NOSHADOW;
	VectorSet( le->lightColor, 1.0f, 0.6f, 0.6f );

	VectorMA( org, 8, norm, direction );
	VectorSet(vel, 0, 0, 8);
	//Some smoke
	FX_AddSprite(	direction, 
					vel, 
					qfalse, 
					20.0f + random()*50.0f,//1.2f + (random()*0.5f),//60.0f - random()*60.0f
					16.0f,
					100.0f,//1.0f
					100.0f,//0.0f
					random()*45.0f,
					-12.0f,
					8000.0f,
					cgs.media.steamShader );


	for ( i = 0; i < 6; i++)
	{	
		float width, length;
		FXE_Spray( norm, 500, 175, 0.8f, vel);//, (FXPrimitive *) fx 
		length = 24.0 + random() * 12;
		width = 0.5 + random() * 2;
		FX_AddTrail( origin, vel, qtrue, length, -length, width, -width, 
						1.0f, 1.0f, 0.5f, 2500.0f,  cgs.media.orangeTrailShader);//RPG-X: RedTechie - Killtime use to be 1000.0f
	
		/*FX_AddTrail( origin, NULL, NULL, 16.0f, -15.0f,
								1.5, -1.5, 1.0f, 1.0f, 0.2f, 1000.0f,  cgs.media.orangeTrailShader, rand() & FXF_BOUNCE );
*/
	/*if ( fx == NULL )
		return;*/

	
	}

	trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeAltExplodeSnd );	

	CG_ImpactMark( cgs.media.compressionMarkShader, origin, norm, random()*360, 1,1,1,1.0, qfalse, 
					random() * 16 + 48, qfalse );

	CG_ExplosionEffects( origin, 2.0, 350 );
}
예제 #17
0
void CG_GibPlayer(centity_t *cent, vec3_t playerOrigin, vec3_t gdir)
{
	int            i, count = 0, tagIndex, gibIndex;
	vec3_t         origin, velocity, dir;
	trace_t        trace;
	qboolean       foundtag;
	clientInfo_t   *ci;
	int            clientNum;
	bg_character_t *character;
	vec4_t         projection, color;

	// Rafael
	// BloodCloud
	qboolean newjunction[MAXJUNCTIONS];
	vec3_t   junctionOrigin[MAXJUNCTIONS];
	int      junction;
	int      j;
	vec3_t   axis[3], angles;

	char *JunctiongibTags[] =
	{
		// leg tag
		"tag_footright",
		"tag_footleft",
		"tag_legright",
		"tag_legleft",

		// torsotags
		"tag_armright",
		"tag_armleft",

		"tag_torso",
		"tag_chest"
	};

	char *ConnectTags[] =
	{
		// legs tags
		"tag_legright",
		"tag_legleft",
		"tag_torso",
		"tag_torso",

		// torso tags
		"tag_chest",
		"tag_chest",

		"tag_chest",
		"tag_torso",
	};

	char *gibTags[] =
	{
		// tags in the legs
		"tag_footright",
		"tag_footleft",
		"tag_legright",
		"tag_legleft",
		"tag_torso",

		// tags in the torso
		"tag_chest",
		"tag_armright",
		"tag_armleft",
		"tag_head",
		NULL
	};

	if (cg_blood.integer)
	{
		// Rafael
		for (i = 0; i < MAXJUNCTIONS; i++)
			newjunction[i] = qfalse;

		clientNum = cent->currentState.clientNum;
		if (clientNum < 0 || clientNum >= MAX_CLIENTS)
		{
			CG_Error("Bad clientNum on player entity");
		}
		ci        = &cgs.clientinfo[clientNum];
		character = CG_CharacterForClientinfo(ci, cent);

		// Ridah, fetch the various positions of the tag_gib*'s
		// and spawn the gibs from the correct places (especially the head)
		for (gibIndex = 0, count = 0, foundtag = qtrue; foundtag && gibIndex < MAX_GIB_MODELS && gibTags[gibIndex]; gibIndex++)
		{

			refEntity_t *re = 0;

			foundtag = qfalse;

			if (!character->gibModels[gibIndex])
			{
				continue;
			}

			re = &cent->pe.bodyRefEnt;

			for (tagIndex = 0; (tagIndex = CG_GetOriginForTag(cent, re, gibTags[gibIndex], tagIndex, origin, axis)) >= 0; count++, tagIndex++)
			{

				foundtag = qtrue;

				VectorSubtract(origin, re->origin, dir);
				VectorNormalize(dir);

				// spawn a gib
				velocity[0] = dir[0] * (0.5 + random()) * GIB_VELOCITY * 0.3;
				velocity[1] = dir[1] * (0.5 + random()) * GIB_VELOCITY * 0.3;
				velocity[2] = GIB_JUMP + dir[2] * (0.5 + random()) * GIB_VELOCITY * 0.5;

				VectorMA(velocity, GIB_VELOCITY, gdir, velocity);
				AxisToAngles(axis, angles);

				CG_LaunchGib(cent, origin, angles, velocity, character->gibModels[gibIndex], 1.0, 0);

				for (junction = 0; junction < MAXJUNCTIONS; junction++)
				{
					if (!Q_stricmp(gibTags[gibIndex], JunctiongibTags[junction]))
					{
						VectorCopy(origin, junctionOrigin[junction]);
						newjunction[junction] = qtrue;
					}
				}
			}
		}

		for (i = 0; i < MAXJUNCTIONS; i++)
		{
			if (newjunction[i] == qtrue)
			{
				for (j = 0; j < MAXJUNCTIONS; j++)
				{
					if (!Q_stricmp(JunctiongibTags[j], ConnectTags[i]))
					{
						if (newjunction[j] == qtrue)
						{
							// spawn a blood cloud somewhere on the vec from
							VectorSubtract(junctionOrigin[i], junctionOrigin[j], dir);
							CG_ParticleBloodCloud(cent, junctionOrigin[i], dir);
						}
					}
				}
			}
		}

		// Ridah, spawn a bunch of blood dots around the place
		#define GIB_BLOOD_DOTS  3
		for (i = 0, count = 0; i < GIB_BLOOD_DOTS * 2; i++)
		{
			// TTimo: unused
			//static vec3_t mins = {-10,-10,-10};
			//static vec3_t maxs = { 10, 10, 10};

			if (i > 0)
			{
				velocity[0] = ((i % 2) * 2 - 1) * (40 + 40 * random());
				velocity[1] = (((i / 2) % 2) * 2 - 1) * (40 + 40 * random());
				velocity[2] = (((i < GIB_BLOOD_DOTS) * 2) - 1) * 40;
			}
			else
			{
				VectorClear(velocity);
				velocity[2] = -64;
			}

			VectorAdd(playerOrigin, velocity, origin);

			CG_Trace(&trace, playerOrigin, NULL, NULL, origin, -1, CONTENTS_SOLID);
			if (trace.fraction < 1.0)
			{
				//%	BG_GetMarkDir( velocity, trace.plane.normal, velocity );
				//%	CG_ImpactMark( cgs.media.bloodDotShaders[rand()%5], trace.endpos, velocity, random()*360,
				//%		1,1,1,1, qtrue, 30, qfalse, cg_bloodTime.integer * 1000 );
				#if 0
				BG_GetMarkDir(velocity, trace.plane.normal, projection);
				VectorSubtract(vec3_origin, projection, projection);
				projection[3] = 64;
				VectorMA(trace.endpos, -8.0f, projection, markOrigin);
				CG_ImpactMark(cgs.media.bloodDotShaders[rand() % 5], markOrigin, projection, 30.0f, random() * 360.0f, 1.0f, 1.0f, 1.0f, 1.0f, cg_bloodTime.integer * 1000);
				#else
				VectorSet(projection, 0, 0, -1);
				projection[3] = 30.0f;
				Vector4Set(color, 1.0f, 1.0f, 1.0f, 1.0f);
				trap_R_ProjectDecal(cgs.media.bloodDotShaders[rand() % 5], 1, (vec3_t *) trace.endpos, projection, color,
				                    cg_bloodTime.integer * 1000, (cg_bloodTime.integer * 1000) >> 4);
				#endif

				if (count++ > GIB_BLOOD_DOTS)
				{
					break;
				}
			}
		}
	}
예제 #18
0
파일: cg_localents.c 프로젝트: Razish/QtZ
void CG_FragmentBounceMark( localEntity_t *le, trace_t *trace ) {
		 if ( le->leMarkType == LEMT_BLOOD )	CG_ImpactMark( cgs.media.bloodMarkShader, &trace->endpos, &trace->plane.normal, random()*360, 1, 1, 1, 1, qtrue, 16.0f+flrand( 0, 31 ), qfalse );
	else if ( le->leMarkType == LEMT_BURN )		CG_ImpactMark( cgs.media.burnMarkShader, &trace->endpos, &trace->plane.normal, random()*360, 1, 1, 1, 1, qtrue, 8.0f+flrand( 0, 15 ), qfalse );

	le->leMarkType = LEMT_NONE; // don't allow a fragment to make multiple marks, or they pile up while settling
}
예제 #19
0
void FX_PhaserFire( vec3_t startpos, vec3_t endpos, vec3_t normal, qboolean spark, qboolean impact, qboolean empty )
{
	refEntity_t		beam;
	sfxHandle_t		sfx;
	float			size;
	vec3_t			velocity;
	int				sparks;
	vec3_t			rgb = { 1,0.9,0.6}, rgb2={1,0.3,0};

	//vec3_t			rgb3 = { 1.0, 1.0, 1.0 };

	sfx = 0;

	// Draw beam first.
	memset( &beam, 0, sizeof( beam ) );

	VectorCopy( startpos, beam.origin);
	VectorCopy( endpos, beam.oldorigin );
	beam.reType = RT_LINE;
	if (empty)
	{
		beam.customShader = cgs.media.phaserEmptyShader;
	}
	else
	{
		beam.customShader = cgs.media.phaserShader;
	}
	AxisClear( beam.axis );
	beam.shaderRGBA[0] = 0xff;
	beam.shaderRGBA[1] = 0xff;
	beam.shaderRGBA[2] = 0xff;
	beam.shaderRGBA[3] = 0xff;
	if (empty)
	{
		beam.data.line.width = 1.0f + ( crandom() * 0.6f );
	}
	else
	{
		beam.data.line.width = 2.0f + ( crandom() * 0.6f );
	}
	beam.data.line.stscale = 5.0;
	trap_R_AddRefEntityToScene( &beam );

	// Now draw the hit graphic
 
	// no explosion at LG impact, it is added with the beam

	if ( sfx )
	{
		Com_Printf("playing %s\n", "phaser sound");
		trap_S_StartSound( endpos, ENTITYNUM_WORLD, CHAN_AUTO, sfx );
	}

	//
	// impact mark
	//
	if (impact)
	{
		if (!empty)
		{	// normal.
			CG_ImpactMark( cgs.media.scavMarkShader, endpos, normal, random()*360, 1,1,1,0.2, qfalse, 
						random() + 1, qfalse );
			
			//VectorCopy( endpos, phaserFlare.worldCoord );

			/*CG_InitLensFlare( endpos,
									80,
									80,
									rgb,
									1.2,
									1.5,
									1600,
									200,
									colorTable[CT_BLACK],
									1600,
									200,
									80,
									5,
									qfalse,
									5,
									40,
									qfalse,
									qfalse,
									qfalse,
									1.0,
									1.0,
									200.0,
									200.0,
									200.0 );*/
			
			//CG_InitLensFlare( endpos, 
			//		30, 30,
			//		rgb, 1.2, 2.0, 1600, 200,
			//		colorTable[CT_BLACK], 1600, 200, 410, 15, qfalse, 
			//		0, 0, qfalse, qtrue, 
			//		qfalse, 1.0, cg.time, 0, 0, 50);

			//TiM : Add your basic cheesy 'seen-way-too-much-in-movies-these-days' anamorphic lens streak :)
			//CG_DrawLensFlare( &phaserFlare );
			//FX_AddSprite( endpos, NULL, qfalse, random() * 1.25 + 5.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 50.0, cgs.media.blueParticleStreakShader ); //1.5f
			
			//FX_AddQuad2(  endpos, normal, random() * 1.25 + 8.0f, 0.0f, 1.0f, 1.0f, rgb3, rgb3, 270, 50.0, cgs.media.blueParticleStreakShader );
			//eh... looked bad :P

			FX_AddQuad2( endpos, normal, random() * 1.25 + 1.5f, 0.0f, 1.0f, 0.0f, rgb, rgb2, rand() % 360, 500 + random() * 200, 
						cgs.media.sunnyFlareShader );
		}
		else
		{	// Wuss hit when empty.
			FX_AddQuad2( endpos, normal, random() * .75 + 1.0f, 0.0f, 0.5f, 0.0f, rgb, rgb2, rand() % 360, 300 + random() * 200, 
						cgs.media.sunnyFlareShader );
		}
	}

	// "Fun" sparks...  Not when empty.
	if ( spark && !empty)
	{
		sparks = (rand() & 1) + 1;
		for(;sparks>0;sparks--)
		{	
			size = 0.2f + (random() * 0.4);
			FXE_Spray( normal, 200, 75, 0.8f, velocity);
			if (rand() & LEF_USE_COLLISION)
			{	// This spark bounces.
				FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
										size, -size, 1.0f, 0.5f, 0.4f, 500.0f, cgs.media.sparkShader);
			}
			else
			{
				FX_AddTrail( endpos, velocity, qtrue, 5.0f, -15.0f,
										size, -size, 1.0f, 0.5f, 0.0, 500.0f, cgs.media.sparkShader);
			}
		}
	}
}
예제 #20
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 );
	}
}
예제 #21
0
void CG_Spotlight( centity_t *cent, float *color, vec3_t realstart, vec3_t lightDir, int segs, float range, int startWidth, float coneAngle, int flags ) {
	int i, j;
	vec3_t start, traceEnd, proj;
	vec3_t right, up;
	vec3_t v1, v2;
	vec3_t startvec, endvec;        // the vectors to rotate around lightDir to create the circles
	vec3_t conevec;
	vec3_t start_points[MAX_SPOT_SEGS], end_points[MAX_SPOT_SEGS];
	vec3_t coreright;
	polyVert_t verts[MAX_SPOT_SEGS * 4]; // x4 for 4 verts per poly
	polyVert_t plugVerts[MAX_SPOT_SEGS];
	vec3_t endCenter;
	polyVert_t coreverts[4];
	trace_t tr;
	float alpha;
	float radius = 0.0; // TTimo might be used uninitialized
	float coreEndRadius;
	qboolean capStart = qtrue;
	float hitDist;          // the actual distance of the trace impact	(0 is no hit)
	float beamLen;          // actual distance of the drawn beam
	float endAlpha    = 0.0;
	vec4_t colorNorm;       // normalized color vector
	refEntity_t ent;
	vec3_t angles;

	VectorCopy( realstart, start );

	// normalize color
	colorNorm[3] = 0;   // store normalize multiplier in alpha index
	for ( i = 0; i < 3; i++ ) {
		if ( color[i] > colorNorm[3] ) {
			colorNorm[3] = color[i];    // find largest color value in RGB
		}
	}

	if ( colorNorm[3] != 1 ) {     // it needs to be boosted
		VectorMA( color, 1.0 / colorNorm[3], color, colorNorm );    // FIXME: div by 0
	} else {
		VectorCopy( color, colorNorm );
	}
	colorNorm[3] = color[3];


	if ( flags & SL_NOSTARTCAP ) {
		capStart = qfalse;
	}

	if ( startWidth == 0 ) {   // cone, not cylinder
		capStart = qfalse;
	}

	if ( flags & SL_LOCKTRACETORANGE ) {
		VectorMA( start, range, lightDir, traceEnd );           // trace out to 'range'
	} else {
		VectorMA( start, MAX_SPOT_RANGE, lightDir, traceEnd );  // trace all the way out to max dist
	}

	// first trace to see if anything is hit
	if ( flags & SL_NOTRACE ) {
		tr.fraction = 1.0;  // force no hit
	} else {
		if ( flags & SL_TRACEWORLDONLY ) {
			CG_Trace( &tr, start, NULL, NULL, traceEnd, -1, CONTENTS_SOLID );
		} else {
			CG_Trace( &tr, start, NULL, NULL, traceEnd, -1, MASK_SHOT );
		}
//		CG_Trace( &tr, start, NULL, NULL, traceEnd, -1, MASK_ALL &~(CONTENTS_MONSTERCLIP|CONTENTS_AREAPORTAL|CONTENTS_CLUSTERPORTAL));
	}


	if ( tr.fraction < 1.0 ) {
		hitDist = beamLen = MAX_SPOT_RANGE * tr.fraction;
		if ( beamLen > range ) {
			beamLen = range;
		}
	} else {
		hitDist = 0;
		beamLen = range;
	}


	if ( flags & SL_LOCKUV ) {
		if ( beamLen < range ) {
			endAlpha = 255.0f * ( color[3] - ( color[3] * beamLen / range ) );
		}
	}


	if ( segs >= MAX_SPOT_SEGS ) {
		segs = MAX_SPOT_SEGS - 1;
	}

	// TODO: adjust segs based on r_lodbias
	// TODO: move much of this to renderer


// model at base
	if ( cent->currentState.modelindex ) {
		memset( &ent, 0, sizeof( ent ) );
		ent.frame = 0;
		ent.oldframe = 0;
		ent.backlerp = 0;
		VectorCopy( cent->lerpOrigin, ent.origin );
		VectorCopy( cent->lerpOrigin, ent.oldorigin );
		ent.hModel = cgs.gameModels[cent->currentState.modelindex];
		//	AnglesToAxis( cent->lerpAngles, ent.axis );
		vectoangles( lightDir, angles );
		AnglesToAxis( angles, ent.axis );
		trap_R_AddRefEntityToScene( &ent );
		memcpy( &cent->refEnt, &ent, sizeof( refEntity_t ) );

		// push start out a bit so the beam fits to the front of the base model
		VectorMA( start, 14, lightDir, start );
	}

//// BEAM

	PerpendicularVector( up, lightDir );
	CrossProduct( lightDir, up, right );

	// find first vert of the start
	VectorScale( right, startWidth, startvec );
	// find the first vert of the end
	RotatePointAroundVector( conevec, up, lightDir, -coneAngle );
	VectorMA( startvec, beamLen, conevec, endvec );   // this applies the offset of the start diameter before finding the end points

	VectorScale( lightDir, beamLen, endCenter );
	VectorSubtract( endCenter, endvec, coreverts[3].xyz );    // get a vector of the radius out at the end for the core to use
	coreEndRadius = VectorLength( coreverts[3].xyz );
#define CORESCALE 0.6f

//
//	generate the flat beam 'core'
//
	if ( !( flags & SL_NOCORE ) ) {
		VectorSubtract( start, cg.refdef.vieworg, v1 );
		VectorNormalize( v1 );
		VectorSubtract( traceEnd, cg.refdef.vieworg, v2 );
		VectorNormalize( v2 );
		CrossProduct( v1, v2, coreright );
		VectorNormalize( coreright );

		memset( &coreverts[0], 0, 4 * sizeof( polyVert_t ) );
		VectorMA( start, startWidth * 0.5f, coreright, coreverts[0].xyz );
		VectorMA( start, -startWidth * 0.5f, coreright, coreverts[1].xyz );
		VectorMA( endCenter, -coreEndRadius * CORESCALE, coreright, coreverts[2].xyz );
		VectorAdd( start, coreverts[2].xyz, coreverts[2].xyz );
		VectorMA( endCenter, coreEndRadius * CORESCALE, coreright, coreverts[3].xyz );
		VectorAdd( start, coreverts[3].xyz, coreverts[3].xyz );

		for ( i = 0; i < 4; i++ ) {
			coreverts[i].modulate[0] = color[0] * 200.0f;
			coreverts[i].modulate[1] = color[1] * 200.0f;
			coreverts[i].modulate[2] = color[2] * 200.0f;
			coreverts[i].modulate[3] = color[3] * 200.0f;
			if ( i > 1 ) {
				coreverts[i].modulate[3] = 0;
			}
		}

		trap_R_AddPolyToScene( cgs.media.spotLightBeamShader, 4, &coreverts[0] );
	}


//
// generate the beam cylinder
//



	for ( i = 0; i <= segs; i++ ) {
		RotatePointAroundVector( start_points[i], lightDir, startvec, ( 360.0f / (float)segs ) * i );
		VectorAdd( start_points[i], start, start_points[i] );

		RotatePointAroundVector( end_points[i], lightDir, endvec, ( 360.0f / (float)segs ) * i );
		VectorAdd( end_points[i], start, end_points[i] );
	}

	for ( i = 0; i < segs; i++ ) {

		j = ( i * 4 );

		VectorCopy( start_points[i], verts[( i * 4 )].xyz );
		verts[j].st[0]  = 0;
		verts[j].st[1]  = 1;
		verts[j].modulate[0] = color[0] * 255.0f;
		verts[j].modulate[1] = color[1] * 255.0f;
		verts[j].modulate[2] = color[2] * 255.0f;
		verts[j].modulate[3] = color[3] * 255.0f;
		j++;

		VectorCopy( end_points[i], verts[j].xyz );
		verts[j].st[0]  = 0;
		verts[j].st[1]  = 0;
		verts[j].modulate[0] = color[0] * 255.0f;
		verts[j].modulate[1] = color[1] * 255.0f;
		verts[j].modulate[2] = color[2] * 255.0f;
		verts[j].modulate[3] = endAlpha;
		j++;

		VectorCopy( end_points[i + 1], verts[j].xyz );
		verts[j].st[0]  = 1;
		verts[j].st[1]  = 0;
		verts[j].modulate[0] = color[0] * 255.0f;
		verts[j].modulate[1] = color[1] * 255.0f;
		verts[j].modulate[2] = color[2] * 255.0f;
		verts[j].modulate[3] = endAlpha;
		j++;

		VectorCopy( start_points[i + 1], verts[j].xyz );
		verts[j].st[0]  = 1;
		verts[j].st[1]  = 1;
		verts[j].modulate[0] = color[0] * 255.0f;
		verts[j].modulate[1] = color[1] * 255.0f;
		verts[j].modulate[2] = color[2] * 255.0f;
		verts[j].modulate[3] = color[3] * 255.0f;

		if ( capStart ) {
			VectorCopy( start_points[i], plugVerts[i].xyz );
			plugVerts[i].st[0]  = 0;
			plugVerts[i].st[1]  = 0;
			plugVerts[i].modulate[0] = color[0] * 255.0f;
			plugVerts[i].modulate[1] = color[1] * 255.0f;
			plugVerts[i].modulate[2] = color[2] * 255.0f;
			plugVerts[i].modulate[3] = color[3] * 255.0f;
		}
	}

	trap_R_AddPolysToScene( cgs.media.spotLightBeamShader, 4, &verts[0], segs );


	// plug up the start circle
	if ( capStart ) {
		trap_R_AddPolyToScene( cgs.media.spotLightBeamShader, segs, &plugVerts[0] );
	}


	// show the endpoint

	if ( !( flags & SL_NOIMPACT ) ) {
		if ( hitDist ) {
			VectorMA( startvec, hitDist, conevec, endvec );

			alpha = 0.3f;
			radius = coreEndRadius * ( hitDist / beamLen );

			VectorNegate( lightDir, proj );
			CG_ImpactMark( cgs.media.spotLightShader, tr.endpos, proj, 0, colorNorm[0], colorNorm[1], colorNorm[2], alpha, qfalse, radius, qtrue, -1 );
		}
	}



	// add d light at end
	if ( !( flags & SL_NODLIGHT ) ) {
		vec3_t dlightLoc;
//		VectorMA(tr.endpos, -60, lightDir, dlightLoc);	// back away from the hit
//		trap_R_AddLightToScene(dlightLoc, 200, colorNorm[0], colorNorm[1], colorNorm[2], 0);	// ,REF_JUNIOR_DLIGHT);
		VectorMA( tr.endpos, 0, lightDir, dlightLoc );    // back away from the hit
//		trap_R_AddLightToScene(dlightLoc, radius*2, colorNorm[0], colorNorm[1], colorNorm[2], 0);	// ,REF_JUNIOR_DLIGHT);
		trap_R_AddLightToScene( dlightLoc, radius * 2, 0.3, 0.3, 0.3, 0 );  // ,REF_JUNIOR_DLIGHT);
	}



	// draw flare at source
	if ( !( flags & SL_NOFLARE ) ) {
		qboolean lightInEyes = qfalse;
		vec3_t camloc, dirtolight;
		float dot, deg, dist;
		float flarescale = 0.0;       // TTimo: might be used uninitialized

		// get camera position and direction to lightsource
		VectorCopy( cg.snap->ps.origin, camloc );
		camloc[2] += cg.snap->ps.viewheight;
		VectorSubtract( start, camloc, dirtolight );
		dist = VectorNormalize( dirtolight );

		// first use dot to determine if it's facing the camera
		dot = DotProduct( lightDir, dirtolight );

		// it's facing the camera, find out how closely and trace to see if the source can be seen

		deg = RAD2DEG( M_PI - acos( dot ) );
		if ( deg <= 35 ) { // start flare a bit before the camera gets inside the cylinder
			lightInEyes = qtrue;
			flarescale = 1 - ( deg / 35 );
		}

		if ( lightInEyes ) {   // the dot check succeeded, now do a trace
			CG_Trace( &tr, start, NULL, NULL, camloc, -1, MASK_ALL & ~( CONTENTS_MONSTERCLIP | CONTENTS_AREAPORTAL | CONTENTS_CLUSTERPORTAL ) );
			if ( tr.fraction != 1 ) {
				lightInEyes = qfalse;
			}

		}

		if ( lightInEyes ) {
			float coronasize = flarescale;
			if ( dist < 512 ) { // make even bigger if you're close enough
				coronasize *= ( 512.0f / dist );
			}

			trap_R_AddCoronaToScene( start, colorNorm[0], colorNorm[1], colorNorm[2], coronasize, cent->currentState.number, qtrue );
		} else {
			// even though it's off, still need to add it, but turned off so it can fade in/out properly
			trap_R_AddCoronaToScene( start, colorNorm[0], colorNorm[1], colorNorm[2], 0, cent->currentState.number, qfalse );
		}
	}

}
예제 #22
0
//------------------------------------------------
void FX_ParasiteAcidHitWall( vec3_t origin, vec3_t dir )
//------------------------------------------------
{
	FXTrail		*particle;
	float		detail;
	vec3_t		rgb={0.2f,0.8f,0.0f};
	int			i;

	// Spawn some smoke from the acid burn
	for ( i = 0; i < 4; i ++ )
	{
		CG_Smoke( origin, dir, random() * 4.0f + 8.0f, random() * 16.0f + 2.0f, cgs.media.steamShader );
	}

	FX_AddQuad( origin, dir, NULL, NULL, 4.0, 6.0, 0.5, 0.0, rgb, rgb, 0.0, 0.0, 0.0, 550, cgs.media.waterDropShader );

	// Leave a melted spot
	CG_ImpactMark( cgs.media.bulletmarksShader, origin, dir, random()*360, 1,1,1,0.2f, qfalse, 
					random() * 3.0f + 8.0, qfalse );

	//Sound
	cgi_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cg_weapons[WP_PARASITE].missileHitSound );

	// See if it's worth doing a splash
	detail = FX_DetailLevel( origin, 16, 400 );
	if (detail == 0)
		return;

	// splash the acid
	for ( i = 0; i < 10; i++ )
	{	
		particle = FX_AddTrail( origin, NULL, NULL, 3.0f, -1.0f, 2.0, -1.0,
								0.3f, 0.1f, rgb, rgb, 0.4f, 500.0f, cgs.media.waterDropShader, rand() & FXF_BOUNCE );

		if ( particle != NULL )
		{
			FXE_Spray( dir, 80, 100, 0.95f, 512, (FXPrimitive *) particle );
		}
	}

	// Make a real splash

	vec3_t		org;
	FXSprite	*fx;
	vec3_t		moveDir;
	vec3_t		accel = { 0, 0, -400 };

	for ( i = 0; i < 6; i++ )
	{
		VectorSet( org,
					origin[0] + crandom() * 2.5f,
					origin[1] + crandom() * 2.5f,
					origin[2] + crandom() * 2.5f );
	
		for ( int j = 0; j < 3; j++ )
		{
			moveDir[j] = crandom() * 55.0;
		}
		moveDir[2] += 120.0f;

		VectorSet( rgb,
					random() * 0.3f + 0.2f,
					random() * 0.4f + 0.5f,
					random() * 0.2f + 0.05f );


		fx = FX_AddSprite( org, moveDir, accel, 2.0f + ( random() * 1.0f ), -2.0f, 
					1.0f, 1.0f, 
					rgb, rgb, 
					0, 0.0f, 
					400 + random() * 700, 
					cgs.media.spooShader );

		if ( fx == NULL )
			return;

		fx->SetRoll( 0 );
	}

}
예제 #23
0
void FX_DisruptorWeaponHitWall( vec3_t origin, vec3_t dir, int size )
{
	vec3_t			vel, /*accel,*/ hitpos, direction, org;
	//int				i, t;
	weaponInfo_t	*weaponInfo = &cg_weapons[WP_10];

	CG_InitLensFlare( origin, 
					375, 375,
					colorTable[CT_GREEN], 1.2, 2.0, 1600, 200,
					colorTable[CT_GREEN], 1600, 200, 800, 20,  qtrue, 
					0, 0, qfalse, qtrue, 
					qfalse, 1.0, cg.time, 0, 0, 200);

	// Generate "crawling" electricity		// eh, don't it doesn't look that great.
	FX_DisruptorDischarge( origin, dir, NUM_DISCHARGES, DISCHARGE_DIST, DISCHARGE_SIDE_DIST );

	VectorMA(origin, size, dir, hitpos);

	// Set an oriented residual glow effect
	FX_AddQuad( hitpos, dir, size * size * 15.0f, -150.0f, 
				1.0f, 0.0f, 0, 300, cgs.media.greenParticleShader );

	CG_ImpactMark( cgs.media.scavMarkShader, origin, dir, random()*360, 1,1,1,0.6, qfalse, 
					size * 12 + 1, qfalse );

	FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f, 
				1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleShader );

/*	FX_AddSprite( hitpos, NULL, qfalse, size * size * 15.0f, -150.0f, 
				1.0f, 0.0f, 360*random(), 0, 400, cgs.media.greenParticleStreakShader ); */

	FX_AddSprite( hitpos, NULL, qfalse, size * size * 25.0f, -150.0f, 
				1.0f, 0.0f, 0.0f, 0, 400, cgs.media.greenParticleStreakShader );

	VectorSubtract( cg.refdef.vieworg, origin, direction );
	VectorNormalize( direction );

	VectorMA( origin, 12, direction, org );
	VectorMA( org, 8, dir, direction );
	VectorSet(vel, 0, 0, 32 ); //8

	FX_AddSprite( origin, 
						vel, qfalse, 
						random() * 4 + 2, 12,
						0.6 + random() * 0.4, 0.0,
						random() * 180, 
						0.0, 
						random() * 200 + 1200, //300
						cgs.media.steamShader );

	//FX_AddSprite(

	// Only play the impact sound and throw off the purple particles when it's the main projectile
/*	if ( size < 3 )
		return;

	for ( i = 0; i < 4; i++ )
	{
		for ( t = 0; t < 3; t++ )
			vel[t] = ( dir[t] + crandom() * 0.9 ) * ( random() * 100 + 250 );

		VectorScale( vel, -2.2, accel );
		FX_AddSprite( hitpos, vel, qfalse, random() * 8 + 8, 0, 1.0, 0.0, 0.0, 0.0, 200, cgs.media.purpleParticleShader );

	}*/
	trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound );
}
예제 #24
0
/*
-------------------------
FX_fxfunc_Explosion
-------------------------
*/
void FX_fxfunc_Explosion( vec3_t start, vec3_t origin, vec3_t normal )
{
	localEntity_t	*le;
	vec3_t			dir;
	vec3_t			velocity;
//	vec3_t			end;
//	trace_t			trace;
	float			scale;
	int				i, j, numSparks;
	//weaponInfo_t	*weaponInfo = &cg_weapons[WP_6];
	//float	scale, dscale;
//	int		s;
//	vec3_t	new_org;

	//Sparks
	numSparks = 20 + (random() * 4.0f);//4

	for ( i = 0; i < numSparks; i++ )
	{	
		scale = 0.25f + (random() * 1.0f);

		//Randomize the direction
		for (j = 0; j < 3; j ++ )
		{
			dir[j] = normal[j] + (0.75 * crandom());
		}

		VectorNormalize(dir);

		//set the speed
		VectorScale( dir, 200 + (50 * crandom()), velocity);

		le = FX_AddTrail( origin,
								velocity,
								qtrue,
								4.0f,
								-4.0f,
								scale,
								-scale,
								1.0f,
								1.0f,
								0.5f,
								1000.0f,
								cgs.media.sparkShader);

	}

	VectorMA( origin, 8, normal, dir );
	VectorSet(velocity, 0, 0, 8);

	// Smoke puffs
	FX_AddSprite(	dir,
					velocity, 
					qfalse, 
					20.0f + random()*60.0f,//2.2f + ( crandom() * 0.9f),//60.0f - random()*60.0f
					16.0f,
					100.0f,//1.0f
					100.0f,//0.0f
					random()*45.0f,
					-12.0f,
					8000.0f,
					cgs.media.steamShader );

	//Orient the explosions to face the camera
	VectorSubtract( cg.refdef.vieworg, origin, dir );
	VectorNormalize( dir );

	le = CG_MakeExplosion2( origin, dir, cgs.media.explosionModel, 5, cgs.media.electricalExplosionSlowShader, 475, qfalse, 2.2f + ( crandom() * 0.9f), LEF_NONE);//RPG-X: RedTechie - Scale use to be - 1.2f + ( crandom() * 0.3f)
	le->light = 150;
	le->refEntity.renderfx |= RF_NOSHADOW;
	VectorSet( le->lightColor, 0.8f, 0.8f, 1.0f );

	CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1.0, qfalse, 
					random() * 16 + 48, qfalse );
	//CG_ImpactMark( cgs.media.compressionMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 12, qfalse );

	//Shake the camera
	CG_ExplosionEffects( origin, 2, 400 );

	// nice explosion sound at the point of impact
	trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, cgs.media.grenadeAltExplodeSnd );
	//trap_S_StartSound(origin, ENTITYNUM_WORLD, CHAN_AUTO, weaponInfo->mainHitSound);
}
예제 #25
0
static void CG_RainParticleRender(cg_atmosphericParticle_t * particle)
{
	// Draw a raindrop

	vec3_t forward, right;
	polyVert_t verts[4];
	vec2_t line;
	float len, frac;
	vec3_t start, finish;

	if (!particle->active)
		return;

	VectorCopy(particle->pos, start);
	len = particle->height;
	if (start[2] <= particle->minz) {
		// Stop rain going through surfaces.
		len = particle->height - particle->minz + start[2];
		frac = start[2];
		VectorMA(start, len - particle->height, particle->deltaNormalized, start);

		if (!cg_lowEffects.integer) {
			frac = (ATMOSPHERIC_CUTHEIGHT - particle->minz + frac) / (float) ATMOSPHERIC_CUTHEIGHT;
			// Splash effects on different surfaces
			if (particle->contents & (CONTENTS_WATER | CONTENTS_SLIME)) {
				// Water splash
				if (cg_atmFx.effectwatershader && frac > 0 && frac < 1)
					CG_EffectMark(cg_atmFx.effectwatershader, start, particle->surfacenormal,
						      frac * 0.5, 8 - frac * 8);
			} else if (!(particle->contents & CONTENTS_LAVA)
				   && !(particle->
					surface & (SURF_NODAMAGE | SURF_NOIMPACT | SURF_NOMARKS | SURF_SKY))) {
				// Solid splash
				if (cg_atmFx.effectlandshader && frac > 0 && frac < 1)
					CG_ImpactMark(cg_atmFx.effectlandshader, start, particle->surfacenormal, 0, 1,
						      1, 1, frac * 0.5, qfalse, 3 - frac * 2, qtrue);
			}
		}
	}
	if (len <= 0)
		return;

	VectorCopy(particle->deltaNormalized, forward);
	VectorMA(start, -len, forward, finish);

	line[0] = DotProduct(forward, cg.refdef.viewaxis[1]);
	line[1] = DotProduct(forward, cg.refdef.viewaxis[2]);

	VectorScale(cg.refdef.viewaxis[1], line[1], right);
	VectorMA(right, -line[0], cg.refdef.viewaxis[2], right);
	VectorNormalize(right);

	VectorMA(finish, particle->weight, right, verts[0].xyz);
	verts[0].st[0] = 1;
	verts[0].st[1] = 0;
	verts[0].modulate[0] = 255;
	verts[0].modulate[1] = 255;
	verts[0].modulate[2] = 255;
	verts[0].modulate[3] = 0;

	VectorMA(finish, -particle->weight, right, verts[1].xyz);
	verts[1].st[0] = 0;
	verts[1].st[1] = 0;
	verts[1].modulate[0] = 255;
	verts[1].modulate[1] = 255;
	verts[1].modulate[2] = 255;
	verts[1].modulate[3] = 0;

	VectorMA(start, -particle->weight, right, verts[2].xyz);
	verts[2].st[0] = 0;
	verts[2].st[1] = 1;
	verts[2].modulate[0] = 255;
	verts[2].modulate[1] = 255;
	verts[2].modulate[2] = 255;
	verts[2].modulate[3] = 127;

	VectorMA(start, particle->weight, right, verts[3].xyz);
	verts[3].st[0] = 1;
	verts[3].st[1] = 1;
	verts[3].modulate[0] = 255;
	verts[3].modulate[1] = 255;
	verts[3].modulate[2] = 255;
	verts[3].modulate[3] = 127;

	trap_R_AddPolyToScene(*particle->effectshader, 4, verts);
}
예제 #26
0
/*
=================
CG_MissileHitWall

Caused by an EV_MISSILE_MISS event, or directly by local bullet tracing
=================
*/
void CG_MissileHitWall( weapon_t weaponNum, weaponMode_t weaponMode, int clientNum,
                        vec3_t origin, vec3_t dir, impactSound_t soundType )
{
  qhandle_t           mark = 0;
  qhandle_t           ps = 0;
  int                 c;
  float               radius = 1.0f;
  weaponInfo_t        *weapon = &cg_weapons[ weaponNum ];

  if( weaponMode <= WPM_NONE || weaponMode >= WPM_NUM_WEAPONMODES )
    weaponMode = WPM_PRIMARY;

  mark = weapon->wim[ weaponMode ].impactMark;
  radius = weapon->wim[ weaponMode ].impactMarkSize;
  ps = weapon->wim[ weaponMode ].impactParticleSystem;

  if( soundType == IMPACTSOUND_FLESH )
  {
    //flesh sound
    for( c = 0; c < 4; c++ )
    {
      if( !weapon->wim[ weaponMode ].impactFleshSound[ c ] )
        break;
    }

    if( c > 0 )
    {
      c = rand( ) % c;
      if( weapon->wim[ weaponMode ].impactFleshSound[ c ] )
        trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactFleshSound[ c ] );
    }
  }
  else
  {
    //normal sound
    for( c = 0; c < 4; c++ )
    {
      if( !weapon->wim[ weaponMode ].impactSound[ c ] )
        break;
    }

    if( c > 0 )
    {
      c = rand( ) % c;
      if( weapon->wim[ weaponMode ].impactSound[ c ] )
        trap_S_StartSound( origin, ENTITYNUM_WORLD, CHAN_AUTO, weapon->wim[ weaponMode ].impactSound[ c ] );
    }
  }

  //create impact particle system
  if( ps )
  {
    particleSystem_t *partSystem = CG_SpawnNewParticleSystem( ps );

    if( CG_IsParticleSystemValid( &partSystem ) )
    {
      CG_SetAttachmentPoint( &partSystem->attachment, origin );
      CG_SetParticleSystemNormal( partSystem, dir );
      CG_AttachToPoint( &partSystem->attachment );
    }
  }

  //
  // impact mark
  //
  if( radius > 0.0f )
    CG_ImpactMark( mark, origin, dir, random( ) * 360, 1, 1, 1, 1, qfalse, radius, qfalse );
}