========================================================================================================================================================


cgame\cg_local.h --> Added:


qhandle_t SaberTrailShader;
qhandle_t SaberBladeShader;
qhandle_t SaberEndShader;


========================================================================================================================================================


cgame\cg_main.c --> Added:


cgs.media.SaberTrailShader = trap_R_RegisterShader( "SFX_Sabers/saber_trail" );
cgs.media.SaberBladeShader = trap_R_RegisterShader( "SFX_Sabers/saber_blade" );
cgs.media.SaberEndShader = trap_R_RegisterShader( "SFX_Sabers/saber_end" );


========================================================================================================================================================


cgame\cg_players.c --> CG_DoSaber --> (replaced completely)


void CG_DoSaber( vec3_t blade_muz, vec3_t blade_tip, vec3_t trail_tip, vec3_t trail_muz, float lengthMax, float radius, saber_colors_t color, int rfx, qboolean doLight, qboolean doTrail )
{
	vec3_t	dif, mid, blade_dir, end_dir, trail_dir, base_dir;
	float	radiusmult, effectradius, coreradius, effectalpha, AngleScale;
	float	blade_len, end_len, trail_len, base_len, DisTip, DisMuz, DisDif;
	float	glowscale = 0.5;
	float 	v1, v2, len;

	qhandle_t	glow = 0;
	refEntity_t saber;

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

	if ( blade_len < 1.0f )
	{
		return;
	}

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

	switch( color )
	{
		case SABER_RED:
			glow = cgs.media.redSaberGlowShader;
			break;
		case SABER_ORANGE:
			glow = cgs.media.orangeSaberGlowShader;
			break;
		case SABER_YELLOW:
			glow = cgs.media.yellowSaberGlowShader;
			break;
		case SABER_GREEN:
			glow = cgs.media.greenSaberGlowShader;
			break;
		case SABER_PURPLE:
			glow = cgs.media.purpleSaberGlowShader;
			break;
		default:
			glow = cgs.media.blueSaberGlowShader;
			break;
	}

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

	if (doLight)
	{
		vec3_t rgb={1,1,1};
		CG_RGBForSaberColor( color, rgb );
		VectorScale( rgb, 0.66f, rgb );
		trap_R_AddLightToScene( mid, (blade_len*2.0f) + (random()*10.0f), rgb[0], rgb[1], rgb[2] );
	}

	//Distance Scale
	{
		VectorSubtract( mid, cg.refdef.vieworg, dif );
		len = VectorLength( dif );
		if ( len > 4000 )
		{
			len = 4000;
		}
		else if ( len < 1 )
		{
			len = 1;
		}

		v1 = ((len+400) / 400);
		v2 = ((len+4000) / 4000);

		if(end_len > 1 || base_len > 1)
		{
			if(end_len > base_len)
				glowscale = (end_len+4)*0.1;
			else
				glowscale = (base_len+4)*0.1;

			if(glowscale > 1.0)
				glowscale = 1.0;
		}
		effectalpha = glowscale;
	}

	//Angle Scale
	{
		VectorSubtract( blade_tip, cg.refdef.vieworg, dif );
		DisTip = VectorLength( dif );

		VectorSubtract( blade_muz, cg.refdef.vieworg, dif );
		DisMuz = VectorLength( dif );

		if(DisTip > DisMuz)
		{
			DisDif = DisTip - DisMuz;
		}
		else if(DisTip < DisMuz)
		{
			DisDif = DisMuz - DisTip;
		}
		else
		{
			DisDif = 0;
		}

		AngleScale = 1.2 - (DisDif/blade_len)*(DisDif/blade_len);

		if(AngleScale > 1.0)
			AngleScale = 1.0;
		if(AngleScale < 0.2)
			AngleScale = 0.2;

		effectalpha *= AngleScale;

		AngleScale += 0.3;

		if(AngleScale > 1.0)
			AngleScale = 1.0;
		if(AngleScale < 0.4)
			AngleScale = 0.4;
	}

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

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

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

	if (cg_saberTrail.integer == 2 && cg_shadows.integer != 2 && cgs.glconfig.stencilBits >= 4)
	{
		rfx |= RF_FORCEPOST;
	}

	{
		saber.renderfx = rfx;
		if(blade_len-((effectradius*AngleScale)/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;
			saber.shaderRGBA[0] = 0xff * effectalpha;
			saber.shaderRGBA[1] = 0xff * effectalpha;
			saber.shaderRGBA[2] = 0xff * effectalpha;
			saber.shaderRGBA[3] = 0xff * effectalpha;

			trap_R_AddRefEntityToScene( &saber );
		}

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

		saber.customShader = cgs.media.SaberBladeShader;
		saber.reType = RT_LINE;

		saber.radius = coreradius;

		saber.shaderTexCoord[0] = saber.shaderTexCoord[1] = 1.0f;
		saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;

		trap_R_AddRefEntityToScene( &saber );
	}

	{
		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;
			saber.shaderRGBA[0] = 0xff * effectalpha;
			saber.shaderRGBA[1] = 0xff * effectalpha;
			saber.shaderRGBA[2] = 0xff * effectalpha;
			saber.shaderRGBA[3] = 0xff * effectalpha;

			trap_R_AddRefEntityToScene( &saber );
		}

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

		saber.customShader = cgs.media.SaberBladeShader;
		saber.reType = RT_LINE;

		saber.radius = coreradius;

		saber.shaderTexCoord[0] = saber.shaderTexCoord[1] = 1.0f;
		saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;

		trap_R_AddRefEntityToScene( &saber );
	}

	VectorMA( blade_muz, blade_len - 0.5, blade_dir, blade_tip );
	VectorMA( trail_muz, trail_len - 0.5, 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;
			saber.shaderRGBA[0] = 0xff * effectalpha;
			saber.shaderRGBA[1] = 0xff * effectalpha;
			saber.shaderRGBA[2] = 0xff * effectalpha;
			saber.shaderRGBA[3] = 0xff * effectalpha;
			trap_R_AddRefEntityToScene( &saber );
		}

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

		saber.customShader = cgs.media.SaberBladeShader;
		saber.reType = RT_LINE;

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

		saber.shaderTexCoord[0] = saber.shaderTexCoord[1] = 1.0f;
		saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;

		trap_R_AddRefEntityToScene( &saber );
	}

	if(end_len > 1)
	{
		{
			VectorSubtract( blade_tip, cg.refdef.vieworg, dif );
			DisTip = VectorLength( dif );

			VectorSubtract( trail_tip, cg.refdef.vieworg, dif );
			DisMuz = VectorLength( dif );

			if(DisTip > DisMuz)
			{
				DisDif = DisTip - DisMuz;
			}
			else if(DisTip < DisMuz)
			{
				DisDif = DisMuz - DisTip;
			}
			else
			{
				DisDif = 0;
			}

			if(DisDif > end_len * 0.9)
			{
				effectalpha *= 0.3;
			}
			else if(DisDif > end_len * 0.8)
			{
				effectalpha *= 0.5;
			}
			else if(DisDif > end_len * 0.7)
			{
				effectalpha *= 0.7;
			}
		}


		saber.renderfx = rfx;
		if(end_len-(effectradius*AngleScale) > 0)
		{
			saber.radius = effectradius*AngleScale;
			saber.saberLength = (end_len - (effectradius*AngleScale));
			VectorMA( blade_tip, ((effectradius*AngleScale)/2), end_dir, saber.origin );
			VectorCopy( end_dir, saber.axis[0] );
			saber.reType = RT_SABER_GLOW;
			saber.customShader = glow;
			saber.shaderRGBA[0] = 0xff * effectalpha;
			saber.shaderRGBA[1] = 0xff * effectalpha;
			saber.shaderRGBA[2] = 0xff * effectalpha;
			saber.shaderRGBA[3] = 0xff * effectalpha;
			trap_R_AddRefEntityToScene( &saber );
		}

		// Do the hot core
		VectorMA( blade_tip, end_len, end_dir, saber.origin );
		VectorMA( blade_tip, -0.1, end_dir, saber.oldorigin );

		saber.customShader = cgs.media.SaberEndShader;
		saber.reType = RT_LINE;

		if(end_len > 9)
		{
			AngleScale = 5;
		}
		else if(end_len < 3)
		{
			AngleScale = 1;
		}
		else
		{
			AngleScale = end_len/5;
		}

		{
			AngleScale -= (((DisDif/end_len)*(DisDif/end_len))*AngleScale);

			if(AngleScale < 0.8)
				AngleScale = 0.8;
		}

		saber.radius = (coreradius * AngleScale);
		saber.saberLength = end_len;

		saber.shaderTexCoord[0] = saber.shaderTexCoord[1] = 1.0f;
		saber.shaderRGBA[0] = saber.shaderRGBA[1] = saber.shaderRGBA[2] = saber.shaderRGBA[3] = 0xff;

		trap_R_AddRefEntityToScene( &saber );
	}
}


========================================================================================================================================================


cgame\cg_players.c --> CG_AddSaberBlade --> (replaced everything after: CheckTrail)


CheckTrail:

	saberTrail = &client->saber[saberNum].blade[bladeNum].trail;
	saberTrail->duration = 0;

	if(!saberTrail->base || !saberTrail->tip || !saberTrail->dualbase || !saberTrail->dualtip || !saberTrail->lastTime || !saberTrail->inAction)
	{
		VectorCopy( org_, saberTrail->base );
		VectorMA( end, -1.5f, axis_[0], saberTrail->tip );
		VectorCopy( saberTrail->base, saberTrail->dualbase );
		VectorCopy( saberTrail->tip, saberTrail->dualtip );
		saberTrail->lastTime = cg.time;
		saberTrail->inAction = cg.time;
		return;
	}
	else if ( cg.time > saberTrail->lastTime )
	{
		float dirlen0, dirlen1, dirlen2, lagscale;
		vec3_t dir0, dir1, dir2;

		VectorCopy( saberTrail->base, saberTrail->dualbase );
		VectorCopy( saberTrail->tip, saberTrail->dualtip );

		VectorCopy( org_, saberTrail->base );
		VectorMA( end, -1.5f, axis_[0], saberTrail->tip );

		VectorSubtract( saberTrail->dualtip, saberTrail->tip, dir0 );
		VectorSubtract( saberTrail->dualbase, saberTrail->base, dir1 );
		VectorSubtract( saberTrail->dualtip, saberTrail->dualbase, dir2 );

		dirlen0 = VectorLength(dir0);
		dirlen1 = VectorLength(dir1);
		dirlen2 = VectorLength(dir2);

		if ( saberMoveData[cent->currentState.saberMove].trailLength == 0 )
		{
			dirlen0 *= 0.5;
			dirlen1 *= 0.3;
		}
		else
		{
			dirlen0 *= 1.0;
			dirlen1 *= 0.5;
		}

		lagscale = (cg.time - saberTrail->lastTime);
		lagscale = 1-(lagscale*3/200);

		if(lagscale < 0.1)
			lagscale = 0.1;

		VectorNormalize( dir0 );
		VectorNormalize( dir1 );

		VectorMA( saberTrail->tip, dirlen0*lagscale, dir0, saberTrail->dualtip );
		VectorMA( saberTrail->base, dirlen1*lagscale, dir1, saberTrail->dualbase );
		VectorSubtract( saberTrail->dualtip, saberTrail->dualbase, dir1 );
		VectorNormalize( dir1 );

		VectorMA( saberTrail->dualbase, dirlen2, dir1, saberTrail->dualtip );

		saberTrail->lastTime = cg.time;
	}

	if (!dontDraw)
	{
		vec3_t	rgb1={255.0f,255.0f,255.0f};

		switch( scolor )
		{
			case SABER_RED:
				VectorSet( rgb1, 255.0f, 0.0f, 0.0f );
				break;
			case SABER_ORANGE:
				VectorSet( rgb1, 253.0f, 125.0f, 80.0f );
				break;
			case SABER_YELLOW:
				VectorSet( rgb1, 250.0f, 250.0f, 160.0f );
				break;
			case SABER_GREEN:
				VectorSet( rgb1, 100.0f, 240.0f, 100.0f );
				break;
			case SABER_PURPLE:
				VectorSet( rgb1, 196.0f, 0.0f, 196.0f );
				break;
			default:
				VectorSet( rgb1, 0.0f, 0.0f, 255.0f );
				break;
		}

		VectorCopy( saberTrail->base, fx.mVerts[0].origin );
		VectorCopy( saberTrail->tip, fx.mVerts[1].origin );
		VectorCopy( saberTrail->dualtip, fx.mVerts[2].origin );
		VectorCopy( saberTrail->dualbase, fx.mVerts[3].origin );

		CG_DoSaber( fx.mVerts[0].origin, fx.mVerts[1].origin, fx.mVerts[2].origin, fx.mVerts[3].origin, (client->saber[saberNum].blade[bladeNum].lengthMax), (client->saber[saberNum].blade[bladeNum].radius), scolor, renderfx, (qboolean)(client->saber[saberNum].numBlades < 3 && !(client->saber[saberNum].saberFlags2&SFL2_NO_DLIGHT)), (qboolean)(cg_saberTrail.integer > 0) );
						
		if ( cg.time > saberTrail->inAction )
		{
			saberTrail->inAction = cg.time;

			fx.mShader = cgs.media.SaberTrailShader;
			fx.mKillTime = 0;
			fx.mSetFlags = FX_USE_ALPHA;

			// New muzzle
			VectorCopy( rgb1, fx.mVerts[0].rgb );
			fx.mVerts[0].alpha = 255.0f;

			fx.mVerts[0].ST[0] = 0.0f;
			fx.mVerts[0].ST[1] = 4.0f;
			fx.mVerts[0].destST[0] = 4.0f;
			fx.mVerts[0].destST[1] = 4.0f;

			// new tip
			VectorCopy( rgb1, fx.mVerts[1].rgb );
			fx.mVerts[1].alpha = 255.0f;
						
			fx.mVerts[1].ST[0] = 0.0f;
			fx.mVerts[1].ST[1] = 0.0f;
			fx.mVerts[1].destST[0] = 4.0f;
			fx.mVerts[1].destST[1] = 0.0f;

			// old tip
			VectorCopy( rgb1, fx.mVerts[2].rgb );
			fx.mVerts[2].alpha = 255.0f;

			fx.mVerts[2].ST[0] = 4.0f;
			fx.mVerts[2].ST[1] = 0.0f;
			fx.mVerts[2].destST[0] = 4.0f;
			fx.mVerts[2].destST[1] = 0.0f;

			// old muzzle
			VectorCopy( rgb1, fx.mVerts[3].rgb );
			fx.mVerts[3].alpha = 255.0f;

			fx.mVerts[3].ST[0] = 4.0f;
			fx.mVerts[3].ST[1] = 4.0f;
			fx.mVerts[3].destST[0] = 4.0f;
			fx.mVerts[3].destST[1] = 4.0f;

			trap_FX_AddPrimitive(&fx);

			if ( (client->saber[saberNum].saberFlags2&SFL2_NO_BLADE) )
			{
				if ( client->saber[saberNum].numBlades < 3 && !(client->saber[saberNum].saberFlags2&SFL2_NO_DLIGHT) )
				{
					CG_DoSaberLight( &client->saber[saberNum] );
				}
			}
		}
	}
}


========================================================================================================================================================