Ejemplo n.º 1
0
static void CG_AddWeaponWithPowerups( refEntity_t *gun, int powerups ) {
	// add powerup effects
	SE_R_AddRefEntityToScene( gun, MAX_CLIENTS );

	// add electrocution shell
	if ( cg.predictedPlayerState.electrifyTime > cg.time ) {
		int preShader = gun->customShader;
		if ( rand() & 1 )
			gun->customShader = media.gfx.world.electricBody;
		else
			gun->customShader = media.gfx.world.electricBody2;
		SE_R_AddRefEntityToScene( gun, MAX_CLIENTS );
		gun->customShader = preShader; //set back just to be safe
	}
}
Ejemplo n.º 2
0
// For forcefields/other rectangular things
void CG_AddOLine( localEntity_t *le ) {
	refEntity_t	*re;
	float		frac, alpha;

	re = &le->refEntity;

	frac = (cg.time - le->startTime) / (float)(le->endTime - le->startTime);
	if ( frac > 1 )
		frac = 1.0f;	// can happen during connection problems
	else if ( frac < 0 )
		frac = 0.0f;

	// Use the liferate to set the scale over time.
	re->data.line.width = le->data.line.width + (le->data.line.dwidth * frac);
	if ( re->data.line.width <= 0 ) {
		CG_FreeLocalEntity( le );
		return;
	}

	// We will assume here that we want additive transparency effects.
	alpha = le->alpha + (le->dalpha * frac);
	re->shaderRGBA[0] = 0xff * alpha;
	re->shaderRGBA[1] = 0xff * alpha;
	re->shaderRGBA[2] = 0xff * alpha;
	re->shaderRGBA[3] = 0xff * alpha;	// Yes, we could apply c to this too, but fading the color is better for lines.

	re->shaderTexCoord.x = 1;
	re->shaderTexCoord.y = 1;

	re->rotation = 90;

	re->reType = RT_ORIENTEDLINE;

	SE_R_AddRefEntityToScene( re, MAX_CLIENTS );
}
Ejemplo n.º 3
0
void CG_AddRefEntity( localEntity_t *le ) {
	if ( le->endTime < cg.time ) {
		CG_FreeLocalEntity( le );
		return;
	}
	SE_R_AddRefEntityToScene( &le->refEntity, MAX_CLIENTS );
}
Ejemplo n.º 4
0
// This is just an optimized CG_AddMoveScaleFade for blood mists that drift down, fade out, and are emoved if the view
//	passes through them.
// There are often 100+ of these, so it needs to be simple.
static void CG_AddFallScaleFade( localEntity_t *le ) {
	refEntity_t	*re;
	float		c;
	vector3		delta;
	float		len;
	refdef_t *refdef = CG_GetRefdef();

	re = &le->refEntity;

	// fade time
	c = (le->endTime - cg.time) * le->lifeRate;

	re->shaderRGBA[3] = 0xff * c * le->color[3];

	re->origin.z = le->pos.trBase.z - (1.0f - c) * le->pos.trDelta.z;

	re->radius = le->radius * (1.0f - c) + 16;

	// if the view would be "inside" the sprite, kill the sprite
	// so it doesn't add too much overdraw
	VectorSubtract( &re->origin, &refdef->vieworg, &delta );
	len = VectorLength( &delta );
	if ( len < le->radius ) {
		CG_FreeLocalEntity( le );
		return;
	}

	SE_R_AddRefEntityToScene( re, MAX_CLIENTS );
}
Ejemplo n.º 5
0
static void CG_AddPuff( localEntity_t *le ) {
	refEntity_t	*re;
	float		c;
	vector3		delta;
	float		len;
	refdef_t *refdef = CG_GetRefdef();

	re = &le->refEntity;

	// fade / grow time
	c = (le->endTime - cg.time) / (float)(le->endTime - le->startTime);

	re->shaderRGBA[0] = le->color[0] * c;
	re->shaderRGBA[1] = le->color[1] * c;
	re->shaderRGBA[2] = le->color[2] * c;

	if ( !(le->leFlags & LEF_PUFF_DONT_SCALE) ) {
		re->radius = le->radius * (1.0f - c) + 8;
	}

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

	// if the view would be "inside" the sprite, kill the sprite
	// so it doesn't add too much overdraw
	VectorSubtract( &re->origin, &refdef->vieworg, &delta );
	len = VectorLength( &delta );
	if ( len < le->radius ) {
		CG_FreeLocalEntity( le );
		return;
	}

	SE_R_AddRefEntityToScene( re, MAX_CLIENTS );
}
Ejemplo n.º 6
0
static void CG_AddFadeScaleModel( localEntity_t *le ) {
	refEntity_t	*ent = &le->refEntity;

	float frac = (cg.time - le->startTime) / ((float)(le->endTime - le->startTime));

	frac *= frac * frac; // yes, this is completely ridiculous...but it causes the shell to grow slowly then "explode" at the end

	ent->nonNormalizedAxes = qtrue;

	AxisCopy( axisDefault, ent->axis );

	VectorScale( &ent->axis[0], le->radius*frac, &ent->axis[0] );
	VectorScale( &ent->axis[1], le->radius*frac, &ent->axis[1] );
	VectorScale( &ent->axis[2], le->radius*0.5f*frac, &ent->axis[2] );

	frac = 1.0f - frac;

	ent->shaderRGBA[0] = le->color[0] * frac;
	ent->shaderRGBA[1] = le->color[1] * frac;
	ent->shaderRGBA[2] = le->color[2] * frac;
	ent->shaderRGBA[3] = le->color[3] * frac;

	// add the entity
	SE_R_AddRefEntityToScene( ent, MAX_CLIENTS );
}
Ejemplo n.º 7
0
/*
================
CG_AddSpriteExplosion
================
*/
static void CG_AddSpriteExplosion( localEntity_t *le ) {
	refEntity_t	re;
	float c;

	re = le->refEntity;

	c = ( le->endTime - cg.time ) / ( float ) ( le->endTime - le->startTime );
	if ( c > 1 ) {
		c = 1.0;	// can happen during connection problems
	}

	re.shaderRGBA[0] = 0xff;
	re.shaderRGBA[1] = 0xff;
	re.shaderRGBA[2] = 0xff;
	re.shaderRGBA[3] = 0xff * c * 0.33;

	re.reType = RT_SPRITE;
	re.radius = 42 * ( 1.0 - c ) + 30;

	SE_R_AddRefEntityToScene( &re, MAX_CLIENTS );

	// add the dlight
	if ( le->light ) {
		float		light;

		light = (float)( cg.time - le->startTime ) / ( le->endTime - le->startTime );
		if ( light < 0.5 ) {
			light = 1.0;
		} else {
			light = 1.0 - ( light - 0.5 ) * 2;
		}
		light = le->light * light;
		trap->R_AddLightToScene(&re.origin, light, le->lightColor.r, le->lightColor.g, le->lightColor.b );
	}
}
Ejemplo n.º 8
0
// for beams and the like.
void CG_AddLine( localEntity_t *le ) {
	refEntity_t	*re;

	re = &le->refEntity;

	re->reType = RT_LINE;

	SE_R_AddRefEntityToScene( re, MAX_CLIENTS );
}
Ejemplo n.º 9
0
void CG_AddFadeRGB( localEntity_t *le ) {
	refEntity_t *re;
	float c;

	re = &le->refEntity;

	c = (le->endTime - cg.time) * le->lifeRate;
	c *= 0xff;

	re->shaderRGBA[0] = le->color[0] * c;
	re->shaderRGBA[1] = le->color[1] * c;
	re->shaderRGBA[2] = le->color[2] * c;
	re->shaderRGBA[3] = le->color[3] * c;

	SE_R_AddRefEntityToScene( re, MAX_CLIENTS );
}
Ejemplo n.º 10
0
/*
================
CG_AddExplosion
================
*/
static void CG_AddExplosion( localEntity_t *ex ) {
	refEntity_t	*ent;

	ent = &ex->refEntity;

	// add the entity
	SE_R_AddRefEntityToScene(ent, MAX_CLIENTS);

	// add the dlight
	if ( ex->light ) {
		float		light;

		light = (float)( cg.time - ex->startTime ) / ( ex->endTime - ex->startTime );
		if ( light < 0.5 ) {
			light = 1.0;
		} else {
			light = 1.0 - ( light - 0.5 ) * 2;
		}
		light = ex->light * light;
		trap->R_AddLightToScene(&ent->origin, light, ex->lightColor.r, ex->lightColor.g, ex->lightColor.b );
	}
}
Ejemplo n.º 11
0
void CG_AddScorePlum( localEntity_t *le ) {
	refEntity_t	*re;
	vector3		origin, delta, dir, vec, up = { 0, 0, 1 };
	float		c, len;
	int			i, score, digits[10], numdigits, negative;
	refdef_t *refdef = CG_GetRefdef();

	re = &le->refEntity;

	c = (le->endTime - cg.time) * le->lifeRate;

	score = le->radius;
	if ( score < 0 ) {
		re->shaderRGBA[0] = 0xff;
		re->shaderRGBA[1] = 0x11;
		re->shaderRGBA[2] = 0x11;
	}
	else {
		re->shaderRGBA[0] = 0xff;
		re->shaderRGBA[1] = 0xff;
		re->shaderRGBA[2] = 0xff;
		if ( score >= 50 ) {
			re->shaderRGBA[1] = 0;
		}
		else if ( score >= 20 ) {
			re->shaderRGBA[0] = re->shaderRGBA[1] = 0;
		}
		else if ( score >= 10 ) {
			re->shaderRGBA[2] = 0;
		}
		else if ( score >= 2 ) {
			re->shaderRGBA[0] = re->shaderRGBA[2] = 0;
		}

	}
	if ( c < 0.25f )
		re->shaderRGBA[3] = 0xff * 4 * c;
	else
		re->shaderRGBA[3] = 0xff;

	re->radius = NUMBER_SIZE / 2;

	VectorCopy( &le->pos.trBase, &origin );
	origin.z += 110 - c * 100;

	VectorSubtract( &refdef->vieworg, &origin, &dir );
	CrossProduct( &dir, &up, &vec );
	VectorNormalize( &vec );

	VectorMA( &origin, -10 + 20 * sinf( c * 2 * M_PI ), &vec, &origin );

	// if the view would be "inside" the sprite, kill the sprite
	// so it doesn't add too much overdraw
	VectorSubtract( &origin, &refdef->vieworg, &delta );
	len = VectorLength( &delta );
	if ( len < 20 ) {
		CG_FreeLocalEntity( le );
		return;
	}

	negative = qfalse;
	if ( score < 0 ) {
		negative = qtrue;
		score = -score;
	}

	for ( numdigits = 0; !(numdigits && !score); numdigits++ ) {
		digits[numdigits] = score % 10;
		score = score / 10;
	}

	if ( negative ) {
		digits[numdigits] = 10;
		numdigits++;
	}

	for ( i = 0; i < numdigits; i++ ) {
		VectorMA( &origin, (float)(((float)numdigits / 2) - i) * NUMBER_SIZE, &vec, &re->origin );
		re->customShader = media.gfx.interface.numbers[digits[numdigits - 1 - i]];
		SE_R_AddRefEntityToScene( re, MAX_CLIENTS );
	}
}
Ejemplo n.º 12
0
void CG_AddFragment( localEntity_t *le ) {
	vector3	newOrigin;
	trace_t	trace;

	if ( le->forceAlpha ) {
		le->refEntity.renderfx |= RF_FORCE_ENT_ALPHA;
		le->refEntity.shaderRGBA[3] = le->forceAlpha;
	}

	if ( le->pos.trType == TR_STATIONARY ) {
		// sink into the ground if near the removal time
		int		t;
		float	t_e;

		t = le->endTime - cg.time;
		if ( t < (SINK_TIME * 2) ) {
			le->refEntity.renderfx |= RF_FORCE_ENT_ALPHA;
			t_e = (float)((float)(le->endTime - cg.time) / (SINK_TIME * 2));
			t_e = (int)((t_e)* 255);

			if ( t_e > 255 ) {
				t_e = 255;
			}
			if ( t_e < 1 ) {
				t_e = 1;
			}

			if ( le->refEntity.shaderRGBA[3] && t_e > le->refEntity.shaderRGBA[3] ) {
				t_e = le->refEntity.shaderRGBA[3];
			}

			le->refEntity.shaderRGBA[3] = t_e;

			SE_R_AddRefEntityToScene( &le->refEntity, MAX_CLIENTS );
		}
		else {
			SE_R_AddRefEntityToScene( &le->refEntity, MAX_CLIENTS );
		}

		return;
	}

	// calculate new position
	BG_EvaluateTrajectory( &le->pos, cg.time, &newOrigin );

	// trace a line from previous position to new position
	CG_Trace( &trace, &le->refEntity.origin, NULL, NULL, &newOrigin, -1, CONTENTS_SOLID );
	if ( trace.fraction == 1.0f ) {
		// still in free fall
		VectorCopy( &newOrigin, &le->refEntity.origin );

		if ( le->leFlags & LEF_TUMBLE ) {
			vector3 angles;

			BG_EvaluateTrajectory( &le->angles, cg.time, &angles );
			AnglesToAxis( &angles, le->refEntity.axis );
			ScaleModelAxis( &le->refEntity );
		}

		SE_R_AddRefEntityToScene( &le->refEntity, MAX_CLIENTS );

		// add a blood trail
		if ( le->leBounceSoundType == LEBS_BLOOD ) {
			CG_BloodTrail( le );
		}

		return;
	}

	// 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;
	}

	if ( !trace.startsolid ) {
		// leave a mark
		CG_FragmentBounceMark( le, &trace );

		// do a bouncy sound
		CG_FragmentBounceSound( le, &trace );

		if ( le->bounceSound ) { //specified bounce sound (debris)
			trap->S_StartSound( &le->pos.trBase, ENTITYNUM_WORLD, CHAN_AUTO, le->bounceSound );
		}

		// reflect the velocity on the trace plane
		CG_ReflectVelocity( le, &trace );

		SE_R_AddRefEntityToScene( &le->refEntity, MAX_CLIENTS );
	}
}
Ejemplo n.º 13
0
void UI_DoSFXSaber( vector3 *blade_muz, vector3 *blade_tip, vector3 *trail_tip, vector3 *trail_muz, float lengthMax, float radius, saber_colors_t color, int rfx, qboolean doLight, qboolean doTrail, int cnum, int bnum ) {
	vector3	mid, blade_dir, end_dir, trail_dir, base_dir;
	float	radiusmult, effectradius, coreradius, effectalpha = 1.0f, AngleScale = 1.0f;
	float	blade_len, trail_len, base_len;
	vector3 rgb = { 1, 1, 1 };
	int i;

	qhandle_t	glow = 0;
	refEntity_t saber, sbak;

	VectorSubtract( blade_tip, blade_muz, &blade_dir );
	VectorSubtract( trail_tip, trail_muz, &trail_dir );
	blade_len = lengthMax;//VectorLength(blade_dir);
	trail_len = VectorLength( &trail_dir );
	VectorNormalize( &blade_dir );
	VectorNormalize( &trail_dir );

	if ( lengthMax < 1.0f ) {
		return;
	}

	VectorSubtract( trail_tip, blade_tip, &end_dir );
	VectorSubtract( trail_muz, blade_muz, &base_dir );
	base_len = VectorLength( &base_dir );
	VectorNormalize( &end_dir );
	VectorNormalize( &base_dir );

	switch ( color ) {
	case SABER_RED:
		glow = redSaberGlowShader;
		break;
	case SABER_ORANGE:
		glow = orangeSaberGlowShader;
		break;
	case SABER_YELLOW:
		glow = yellowSaberGlowShader;
		break;
	case SABER_GREEN:
		glow = greenSaberGlowShader;
		break;
	case SABER_PURPLE:
		glow = purpleSaberGlowShader;
		break;
		//	case SABER_WHITE:
	case SABER_RGB:
	case SABER_FLAME1:
	case SABER_ELEC1:
	case SABER_FLAME2:
	case SABER_ELEC2:
		glow = rgbSaberGlowShader;
		break;
	case SABER_BLACK:
		glow = blackSaberGlowShader;
		break;
	default:
		glow = blueSaberGlowShader;
		break;
	}

	VectorMA( blade_muz, blade_len * 0.5f, &blade_dir, &mid );

	memset( &saber, 0, sizeof(refEntity_t) );

	if ( blade_len < lengthMax ) {
		radiusmult = 0.5f + ((blade_len / lengthMax) / 2);
	}
	else {
		radiusmult = 1.0f;
	}

	effectradius = ((radius * 1.6f * 1.0f) + crandom() * 0.1f)*radiusmult;
	coreradius = ((radius * 0.4f * 1.0f) + crandom() * 0.1f)*radiusmult;

	UI_RGBForSaberColor( color, &rgb, bnum );
	for ( i = 0; i<3; i++ )
		rgb.data[i] *= 255;
	{
		saber.renderfx = rfx;
		if ( blade_len - ((effectradius*1.0f) / 2) > 0 ) {
			saber.radius = effectradius*AngleScale;
			saber.saberLength = (blade_len - (saber.radius / 2));
			VectorCopy( blade_muz, &saber.origin );
			VectorCopy( &blade_dir, &saber.axis[0] );
			saber.reType = RT_SABER_GLOW;
			saber.customShader = glow;
			if ( color < SABER_RGB /*&& color != SABER_WHITE*/ )
				saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff * 1.0f;
			else {
				for ( i = 0; i < 3; i++ )
					saber.shaderRGBA[i] = rgb.data[i] * effectalpha;
				saber.shaderRGBA[3] = 255 * effectalpha;
			}

			SE_R_AddRefEntityToScene( &saber, cnum );
		}

		// Do the hot core
		VectorMA( blade_muz, blade_len, &blade_dir, &saber.origin );
		VectorMA( blade_muz, -1, &blade_dir, &saber.oldorigin );

		saber.customShader = sfxSaberBladeShader;
		saber.reType = RT_LINE;

		saber.radius = coreradius;

		saber.shaderTexCoord.x = saber.shaderTexCoord.y = 1.0f;
		if ( color < SABER_RGB /*&& color != SABER_WHITE*/ )
			saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;
		else {
			for ( i = 0; i < 3; i++ )
				saber.shaderRGBA[i] = rgb.data[i];
		}
		sbak = saber;
		SE_R_AddRefEntityToScene( &saber, cnum );

		if ( color >= SABER_RGB /*|| color == SABER_WHITE*/ ) {// Add the saber surface that provides color.

			sbak.customShader = sfxSaberBlade2Shader;
			sbak.reType = RT_LINE;
			sbak.shaderTexCoord.x = sbak.shaderTexCoord.y = 1.0f;
			sbak.shaderRGBA[0] = sbak.shaderRGBA[1] = sbak.shaderRGBA[2] = sbak.shaderRGBA[3] = 0xff;
			sbak.radius = coreradius;
			SE_R_AddRefEntityToScene( &sbak, cnum );
		}
	}

	{
		saber.renderfx = rfx;
		if ( trail_len - ((effectradius*AngleScale) / 2) > 0 ) {
			saber.radius = effectradius*AngleScale;
			saber.saberLength = (trail_len - (saber.radius / 2));
			VectorCopy( trail_muz, &saber.origin );
			VectorCopy( &trail_dir, &saber.axis[0] );
			saber.reType = RT_SABER_GLOW;
			saber.customShader = glow;
			if ( color < SABER_RGB /*&& color != SABER_WHITE*/ )
				saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff * effectalpha;
			else {
				for ( i = 0; i < 3; i++ )
					saber.shaderRGBA[i] = rgb.data[i] * effectalpha;
				saber.shaderRGBA[3] = 255 * effectalpha;
			}

			SE_R_AddRefEntityToScene( &saber, cnum );
		}

		// Do the hot core
		VectorMA( trail_muz, trail_len, &trail_dir, &saber.origin );
		VectorMA( trail_muz, -1, &trail_dir, &saber.oldorigin );

		saber.customShader = sfxSaberBladeShader;
		saber.reType = RT_LINE;

		saber.radius = coreradius;

		saber.shaderTexCoord.x = saber.shaderTexCoord.y = 1.0f;
		if ( color < SABER_RGB /*&& color != SABER_WHITE*/ )
			saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;
		else {
			for ( i = 0; i < 3; i++ )
				saber.shaderRGBA[i] = rgb.data[i];
			saber.shaderRGBA[3] = 255;
		}
		sbak = saber;
		SE_R_AddRefEntityToScene( &saber, cnum );

		if ( color >= SABER_RGB /*|| color == SABER_WHITE*/ ) {// Add the saber surface that provides color.

			sbak.customShader = sfxSaberBlade2Shader;
			sbak.reType = RT_LINE;
			sbak.shaderTexCoord.x = sbak.shaderTexCoord.y = 1.0f;
			sbak.shaderRGBA[0] = sbak.shaderRGBA[1] = sbak.shaderRGBA[2] = sbak.shaderRGBA[3] = 0xff;
			sbak.radius = coreradius;
			SE_R_AddRefEntityToScene( &sbak, cnum );
		}
	}

	VectorMA( blade_muz, blade_len - 0.5f, &blade_dir, blade_tip );
	VectorMA( trail_muz, trail_len - 0.5f, &trail_dir, trail_tip );

	if ( base_len > 2 ) {
		saber.renderfx = rfx;
		if ( base_len - (effectradius*AngleScale) > 0 ) {
			saber.radius = effectradius*AngleScale;
			saber.saberLength = (base_len - (effectradius*AngleScale));
			VectorMA( blade_muz, ((effectradius*AngleScale) / 2), &base_dir, &saber.origin );
			VectorCopy( &base_dir, &saber.axis[0] );
			saber.reType = RT_SABER_GLOW;
			saber.customShader = glow;
			if ( color < SABER_RGB /*&& color != SABER_WHITE*/ )
				saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff * effectalpha;
			else {
				for ( i = 0; i < 3; i++ )
					saber.shaderRGBA[i] = rgb.data[i] * effectalpha;
				saber.shaderRGBA[3] = 255 * effectalpha;
			}
			SE_R_AddRefEntityToScene( &saber, cnum );
		}

		// Do the hot core
		VectorMA( blade_muz, base_len, &base_dir, &saber.origin );
		VectorMA( blade_muz, -0.1f, &base_dir, &saber.oldorigin );

		saber.customShader = sfxSaberBladeShader;
		saber.reType = RT_LINE;

		saber.radius = coreradius;
		saber.saberLength = base_len;

		saber.shaderTexCoord.x = saber.shaderTexCoord.y = 1.0f;
		if ( color < SABER_RGB /*&& color != SABER_WHITE*/ )
			saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;
		else {
			for ( i = 0; i < 3; i++ )
				saber.shaderRGBA[i] = rgb.data[i];
			saber.shaderRGBA[3] = 255;
		}
		sbak = saber;
		SE_R_AddRefEntityToScene( &saber, cnum );

		if ( color >= SABER_RGB /*|| color == SABER_WHITE*/ ) {// Add the saber surface that provides color.

			sbak.customShader = sfxSaberBlade2Shader;
			saber.reType = RT_LINE;
			saber.shaderTexCoord.x = saber.shaderTexCoord.y = 1.0f;
			saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;
			saber.radius = coreradius;
			saber.saberLength = base_len;
			SE_R_AddRefEntityToScene( &sbak, cnum );
		}
	}
}
Ejemplo n.º 14
0
void UI_DoSaber( vector3 *origin, vector3 *dir, float length, float lengthMax, float radius, saber_colors_t color, int rfx, qboolean doLight, int cnum, int bnum )
//void CG_DoSaber( vector3 *origin, vector3 *dir, float length, float lengthMax, float radius, saber_colors_t color, int rfx, qboolean doLight )
{
	vector3		mid;
	qhandle_t	blade = 0, glow = 0;
	refEntity_t saber;
	float radiusmult;
	float radiusRange;
	float radiusStart;
	refEntity_t sbak;
	vector3 rgb = { 1, 1, 1 };
	int i;
	float lol;

	// if the thing is so short, just forget even adding me.
	if ( length < 0.5f )
		return;

	// Find the midpoint of the saber for lighting purposes
	VectorMA( origin, length * 0.5f, dir, &mid );

	switch ( color ) {
	case SABER_RED:
		glow = redSaberGlowShader;
		blade = redSaberCoreShader;
		break;
	case SABER_ORANGE:
		glow = orangeSaberGlowShader;
		blade = orangeSaberCoreShader;
		break;
	case SABER_YELLOW:
		glow = yellowSaberGlowShader;
		blade = yellowSaberCoreShader;
		break;
	case SABER_GREEN:
		glow = greenSaberGlowShader;
		blade = greenSaberCoreShader;
		break;
	case SABER_BLUE:
		glow = blueSaberGlowShader;
		blade = blueSaberCoreShader;
		break;
	case SABER_PURPLE:
		glow = purpleSaberGlowShader;
		blade = purpleSaberCoreShader;
		break;
	default:
	case SABER_RGB:
		glow = rgbSaberGlowShader;
		blade = rgbSaberCoreShader;
		break;
	case SABER_FLAME1:
		glow = rgbSaberGlow2Shader;
		blade = rgbSaberCore2Shader;
		break;
	case SABER_ELEC1:
		glow = rgbSaberGlow3Shader;
		blade = rgbSaberCore3Shader;
		break;
	case SABER_FLAME2:
		glow = rgbSaberGlow4Shader;
		blade = rgbSaberCore4Shader;
		break;
	case SABER_ELEC2:
		glow = rgbSaberGlow5Shader;
		blade = rgbSaberCore5Shader;
		break;
	case SABER_BLACK:
		glow = blackSaberGlowShader;
		blade = blackSaberCoreShader;
		break;
	}

	UI_RGBForSaberColor( color, &rgb, bnum );

	memset( &saber, 0, sizeof(refEntity_t) );

	// Saber glow is it's own ref type because it uses a ton of sprites, otherwise it would eat up too many
	//	refEnts to do each glow blob individually
	saber.saberLength = length;

	// Jeff, I did this because I foolishly wished to have a bright halo as the saber is unleashed.
	// It's not quite what I'd hoped tho.  If you have any ideas, go for it!  --Pat
	if ( length < lengthMax )
		radiusmult = 1.0f + (2.0f / length);		// Note this creates a curve, and length cannot be < 0.5.
	else
		radiusmult = 1.0f;

	for ( i = 0; i < 3; i++ )
		rgb.data[i] *= 255;
	radiusRange = radius * 0.075f;
	radiusStart = radius - radiusRange;

	saber.radius = (radiusStart + crandom() * radiusRange)*radiusmult;
	//saber.radius = (2.8f + crandom() * 0.2f)*radiusmult;

	VectorCopy( origin, &saber.origin );
	VectorCopy( dir, &saber.axis[0] );
	saber.reType = RT_SABER_GLOW;
	saber.customShader = glow;

	if ( color < SABER_RGB )
		saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;
	else {
		for ( i = 0; i < 3; i++ )
			saber.shaderRGBA[i] = rgb.data[i];
		saber.shaderRGBA[3] = 0xff;
	}
	//	saber.renderfx = rfx;

	//RAZTODO: Pass in cent info so we can cull!!!
	//Raz: Glow
	//	saber.renderfx = RF_DEPTHHACK;
	SE_R_AddRefEntityToScene( &saber, MAX_CLIENTS );
	saber.renderfx = 0;

	// Do the hot core
	VectorMA( origin, length, dir, &saber.origin );
	VectorMA( origin, -1, dir, &saber.oldorigin );


	saber.customShader = blade;
	saber.reType = RT_LINE;
	radiusStart = radius / 3.0f;
	saber.radius = (radiusStart + crandom() * radiusRange)*radiusmult;
	//	saber.radius = (1.0f + crandom() * 0.2f)*radiusmult;

	saber.shaderTexCoord.x = saber.shaderTexCoord.y = 1.0f;

	memcpy( &sbak, &saber, sizeof(sbak) );

	if ( color >= SABER_RGB ) {
		switch ( color ) {
		default:
		case SABER_RGB:
			sbak.customShader = rgbSaberCoreShader;
			break;
		case SABER_FLAME1:
			sbak.customShader = rgbSaberCore2Shader;
			break;
		case SABER_ELEC1:
			sbak.customShader = rgbSaberCore3Shader;
			break;
		case SABER_FLAME2:
			sbak.customShader = rgbSaberCore4Shader;
			break;
		case SABER_ELEC2:
			sbak.customShader = rgbSaberCore5Shader;
			break;
		case SABER_BLACK:
			sbak.customShader = blackSaberCoreShader;
			break;
		}
	}

	sbak.shaderRGBA[0] = sbak.shaderRGBA[1] = sbak.shaderRGBA[2] = sbak.shaderRGBA[3] = 0xff;

	lol = Q_fabs( (sinf( (float)trap->Milliseconds() / 400.0f )) );
	lol = (lol * 0.1f) + 1.0f;
	sbak.radius = lol;

	SE_R_AddRefEntityToScene( &sbak, MAX_CLIENTS );
}