Esempio n. 1
0
void CSimpleGlowEmitter::RenderParticles(CParticleRenderIterator *pIterator)
{
    unsigned char viewMask = CurrentViewMask();
    if (!WasTestedInView(CurrentViewMask()))
    {
        pixelvis_queryparams_t params;
        params.Init(GetSortOrigin());

        float visible = PixelVisibility_FractionVisible(params, &m_queryHandle);
        if (visible == 0.0f)
        {
            if ((gpGlobals->curtime - m_startTime) <= 0.1f)
                return;
            SetVisibleInView(viewMask, false);
        }
        else
        {
            SetVisibleInView(viewMask, true);
        }

        SetTestedInView(viewMask, true);
    }
    if (!IsVisibleInView(viewMask))
        return;

    BaseClass::RenderParticles(pIterator);
}
void Gunship_DrawSprite( const Vector &vecOrigin, float size, const color32 &color, bool glow )
{
	if ( glow )
	{
		pixelvis_queryparams_t params;
		params.Init( vecOrigin );
		if ( PixelVisibility_FractionVisible( params, NULL ) <= 0.0f )
			return;
	}

	DrawSpriteTangentSpace( vecOrigin, size, size, color );
}
float CParticleSystemQuery::GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale )
{
#ifdef CLIENT_DLL
	pixelvis_queryparams_t params;
	params.Init( vecOrigin, flScale, 1.0 );
	float flVisibility = PixelVisibility_FractionVisible( params, pQueryHandle );
	flVisibility = max( 0.0f, flVisibility );
	return flVisibility;
#else
	return 0.0f;
#endif
}
float CParticleSystemQuery::GetPixelVisibility( int *pQueryHandle, const Vector &vecOrigin, float flScale )
{
#ifdef CLIENT_DLL
	int slot = GET_ACTIVE_SPLITSCREEN_SLOT();
	ACTIVE_SPLITSCREEN_PLAYER_GUARD( slot );
	pixelvis_queryparams_t params;
	params.Init( vecOrigin, flScale, 1.0 );
	float flVisibility = PixelVisibility_FractionVisible( params, pQueryHandle );
	flVisibility = MAX( 0.0f, flVisibility );
	return flVisibility;
#else
	return 0.0f;
#endif
}
Esempio n. 5
0
void CGlowOverlay::UpdateSkyGlowObstruction( float zFar, bool bCacheFullSceneState )
{
	Assert( m_bInSky );

	// If we already cached the sky obstruction and are still using that, early-out
	if ( bCacheFullSceneState && m_bCacheSkyObstruction )
		return;

	// Turning on sky obstruction caching mode
	if ( bCacheFullSceneState && !m_bCacheSkyObstruction )	
	{
		m_bCacheSkyObstruction = true;
	}

	// Turning off sky obstruction caching mode
	if ( !bCacheFullSceneState && m_bCacheSkyObstruction )
	{
		m_bCacheSkyObstruction = false;
	}

	if ( PixelVisibility_IsAvailable() )
	{
		// Trace a ray at the object. 
		Vector pos = CurrentViewOrigin() + m_vDirection * zFar * 0.99f; // GSTRINGMIGRATION

		// UNDONE: Can probably do only the pixelvis query in this case if you can figure out where
		// to put it - or save the position of this trace
		pixelvis_queryparams_t params;
		params.Init( pos, m_flProxyRadius );
		params.bSizeInScreenspace = true;
		m_skyObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle );
		return;
	}
	// Trace a ray at the object.
	trace_t trace;
	UTIL_TraceLine( CurrentViewOrigin(), CurrentViewOrigin() + (m_vDirection*MAX_TRACE_LENGTH), 
		CONTENTS_SOLID, NULL, COLLISION_GROUP_NONE, &trace );
	
	// back the trace with a pixel query to occlude with models
	if ( trace.surface.flags & SURF_SKY )
	{
		m_skyObstructionScale = 1.0f;
	}
	else
	{
		m_skyObstructionScale = 0.0f;
	}
}
Esempio n. 6
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : &pos - 
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool EffectOccluded(const Vector &pos, pixelvis_handle_t *queryHandle)
{
    if (!queryHandle)
    {
        // NOTE: This is called by networking code before the current view is set up.
        // so use the main view instead
        trace_t	tr;
        UTIL_TraceLine(pos, MainViewOrigin(), MASK_OPAQUE, NULL, COLLISION_GROUP_NONE, &tr);

        return (tr.fraction < 1.0f) ? true : false;
    }
    pixelvis_queryparams_t params;
    params.Init(pos);

    return PixelVisibility_FractionVisible(params, queryHandle) > 0.0f ? false : true;
}
Esempio n. 7
0
//-----------------------------------------------------------------------------
// Purpose: Determine glow brightness/scale based on distance to render origin and trace results
// Input  : entorigin - 
//			rendermode - 
//			renderfx - 
//			alpha - 
//			pscale - Pointer to the value for scale, will be changed based on distance and rendermode.
//-----------------------------------------------------------------------------
float StandardGlowBlend( const pixelvis_queryparams_t &params, pixelvis_handle_t *queryHandle, int rendermode, int renderfx, int alpha, float *pscale )
{
	float dist;
	float brightness;

	brightness = PixelVisibility_FractionVisible( params, queryHandle );
	if ( brightness <= 0.0f )
	{
		return 0.0f;
	}
	dist = GlowSightDistance( params.position, false );
	if ( dist <= 0.0f )
	{
		return 0.0f;
	}

	if ( renderfx == kRenderFxNoDissipation )
	{
		return (float)alpha * (1.0f/255.0f) * brightness;
	}

	// UNDONE: Tweak these magic numbers (1200 - distance at full brightness)
	float fadeOut = (1200.0f*1200.0f) / (dist*dist);
	fadeOut = clamp( fadeOut, 0.0f, 1.0f );

	if (rendermode != kRenderWorldGlow)
	{
		// Make the glow fixed size in screen space, taking into consideration the scale setting.
		if ( *pscale == 0.0f )
		{
			*pscale = 1.0f;
		}

		*pscale *= dist * (1.0f/200.0f);
	}

	return fadeOut * brightness;
}
Esempio n. 8
0
void CGlowOverlay::UpdateGlowObstruction( const Vector &vToGlow, bool bCacheFullSceneState )
{
	// If we already cached the glow obstruction and are still using that, early-out
	if ( bCacheFullSceneState && m_bCacheGlowObstruction )
		return;
	
	if ( bCacheFullSceneState && !m_bCacheGlowObstruction )	// If turning on sky obstruction caching mode
	{
		m_bCacheGlowObstruction = true;
	}

	if ( !bCacheFullSceneState && m_bCacheGlowObstruction )
	{
		m_bCacheGlowObstruction = false;
	}

	if ( PixelVisibility_IsAvailable() )
	{
		if ( m_bInSky )
		{
			const CViewSetup *pViewSetup = view->GetViewSetup();
			Vector pos = CurrentViewOrigin() + m_vDirection * (pViewSetup->zFar * 0.99f); // GSTRINGMIGRATION
			pixelvis_queryparams_t params;
			params.Init( pos, m_flProxyRadius, CalcGlowAspect() );
			params.bSizeInScreenspace = true;
			// use a pixel query to occlude with models
			m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle ) * m_skyObstructionScale;
		}
		else
		{
			// If it's not in the sky, then we need a valid position or else we don't
			// know what's in front of it.
			Assert( !m_bDirectional );

			pixelvis_queryparams_t params;
			params.Init( m_vPos, m_flProxyRadius, CalcGlowAspect() );

			m_flGlowObstructionScale = PixelVisibility_FractionVisible( params, &m_queryHandle );
		}
		return;
	}

	bool bFade = false;
	if ( m_bInSky )
	{
		// Trace a ray at the object.
		trace_t trace;
		UTIL_TraceLine( CurrentViewOrigin(), CurrentViewOrigin() + (vToGlow*MAX_TRACE_LENGTH), 
			CONTENTS_SOLID, NULL, COLLISION_GROUP_NONE, &trace );
		
		bFade = (trace.fraction < 1 && !(trace.surface.flags & SURF_SKY));
	}
	else
	{
		// If it's not in the sky, then we need a valid position or else we don't
		// know what's in front of it.
		Assert( !m_bDirectional );

		pixelvis_queryparams_t params;
		params.Init( m_vPos, m_flProxyRadius );

		bFade = PixelVisibility_FractionVisible( params, &m_queryHandle ) < 1.0f ? true : false;

	}

	if ( bFade )
	{
		if ( building_cubemaps.GetBool() )
		{
			m_flGlowObstructionScale = 0.0f;
		}
		else
		{
			m_flGlowObstructionScale -= gpGlobals->frametime / cl_sun_decay_rate.GetFloat();
			m_flGlowObstructionScale = MAX( m_flGlowObstructionScale, 0.0f );
		}
	}
	else
	{
		if ( building_cubemaps.GetBool() )
		{
			m_flGlowObstructionScale = 1.0f;
		}
		else
		{
			m_flGlowObstructionScale += gpGlobals->frametime / cl_sun_decay_rate.GetFloat();
			m_flGlowObstructionScale = MIN( m_flGlowObstructionScale, 1.0f );
		}
	}
}
Esempio n. 9
0
int	C_StriderFX::DrawModel( int )
{
	static color32 white = {255,255,255,255};
	Vector params[STRIDERFX_PARAMETERS];
	bool hasParam[STRIDERFX_PARAMETERS];

	if ( !m_active )
		return 1;

	C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex );
	if ( ent )
	{
		QAngle angles;
		ent->GetAttachment( m_attachment, m_worldPosition, angles );
	}

	// This forces time to drive from the main clock instead of being integrated per-draw below
	// that way the effect moves on even when culled for visibility
	if ( m_limitHitTime > 0 && m_tMax > 0 )
	{
		float dt = m_limitHitTime - gpGlobals->curtime;
		if ( dt < 0 )
		{
			dt = 0;
		}
		// if the clock needs to move, update it.
		if ( m_tMax - dt > m_t )
		{
			m_t = m_tMax - dt;
			m_beamEndPosition = m_worldPosition;
		}
	}
	else
	{
		// don't have enough info to derive the time, integrate current frame time
		m_t += gpGlobals->frametime;
		if ( m_tMax > 0 )
		{
			m_t = clamp( m_t, 0, m_tMax );
			m_beamEndPosition = m_worldPosition;
		}
	}
	float t = m_t;

	bool hasAny = false;
	memset( hasParam, 0, sizeof(hasParam) );
	for ( int i = 0; i < STRIDERFX_PARAMETERS; i++ )
	{
		hasParam[i] = g_StriderCannonEnvelope.m_parameters[i].Interp( params[i], t );
		hasAny = hasAny || hasParam[i];
	}

	pixelvis_queryparams_t gunParams;
	gunParams.Init(m_worldPosition, 4.0f);
	float gunFractionVisible = PixelVisibility_FractionVisible( gunParams, &m_queryHandleGun );
	bool gunVisible = gunFractionVisible > 0.0f ? true : false;

	// draw the narrow beam
	if ( hasParam[STRIDERFX_NARROW_BEAM_COLOR] && hasParam[STRIDERFX_NARROW_BEAM_SIZE] )
	{
		IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS );
		float width = NARROW_BEAM_WIDTH * params[STRIDERFX_NARROW_BEAM_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_NARROW_BEAM_COLOR].x;
		ScaleColor( color, white, bright );

		Strider_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
	}

	// draw the wide beam
	if ( hasParam[STRIDERFX_WIDE_BEAM_COLOR] && hasParam[STRIDERFX_WIDE_BEAM_SIZE] )
	{
		IMaterial *pMat = materials->FindMaterial( "effects/blueblacklargebeam", TEXTURE_GROUP_CLIENT_EFFECTS );
		float width = WIDE_BEAM_WIDTH * params[STRIDERFX_WIDE_BEAM_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_WIDE_BEAM_COLOR].x;
		ScaleColor( color, white, bright );
		Vector wideBeamEnd = m_beamEndPosition;
		if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
		{
			float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
			wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
		}

		Strider_DrawLine( wideBeamEnd, m_targetPosition, width, pMat, color );
	}

// after glow sprite
	bool updated = false;
	CMatRenderContextPtr pRenderContext( materials );
// warpy sprite bit
	if ( hasParam[STRIDERFX_WARP_SCALE] && !hasParam[STRIDERFX_BUBBLE_SIZE] && gunVisible )
	{
		if ( !updated )
		{
			updated = true;
			pRenderContext->Flush();
			UpdateRefractTexture();
		}

		IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
		float size = WARP_SIZE;
		float refract = params[STRIDERFX_WARP_SCALE].x * WARP_REFRACT * gunFractionVisible;

		pRenderContext->Bind( pMat, (IClientRenderable*)this );
		IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
		pVar->SetFloatValue( refract );
		Strider_DrawSprite( m_worldPosition, size, white );
	}
// darkening sprite
// glowy blue flare sprite
	if ( hasParam[STRIDERFX_FLARE_COLOR] && hasParam[STRIDERFX_FLARE_SIZE] && hasParam[STRIDERFX_DARKNESS] && gunVisible )
	{
		IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
		float size = FLARE_SIZE * params[STRIDERFX_FLARE_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_FLARE_COLOR].x * gunFractionVisible;
		ScaleColor( color, white, bright );
		color.a = (int)(255 * params[STRIDERFX_DARKNESS].x);
		pRenderContext->Bind( pMat, (IClientRenderable*)this );
		Strider_DrawSprite( m_worldPosition, size, color );
	}
// bubble warpy sprite
	if ( hasParam[STRIDERFX_BUBBLE_SIZE] )
	{
		Vector wideBeamEnd = m_beamEndPosition;
		if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
		{
			float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
			wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
		}
		pixelvis_queryparams_t endParams;
		endParams.Init(wideBeamEnd, 4.0f, 0.001f);
		float endFractionVisible = PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
		bool endVisible = endFractionVisible > 0.0f ? true : false;

		if ( endVisible )
		{
			if ( !updated )
			{
				updated = true;
				pRenderContext->Flush();
				UpdateRefractTexture();
			}
			IMaterial *pMat = materials->FindMaterial( "effects/strider_bulge_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
			float refract = endFractionVisible * WARP_BUBBLE_REFRACT * params[STRIDERFX_BUBBLE_REFRACT].x;
			float size = WARP_BUBBLE_SIZE * params[STRIDERFX_BUBBLE_SIZE].x;
			IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
			pVar->SetFloatValue( refract );

			pRenderContext->Bind( pMat, (IClientRenderable*)this );
			Strider_DrawSprite( wideBeamEnd, size, white );
		}
	}
	else
	{
		// call this to have the check ready on the first frame
		pixelvis_queryparams_t endParams;
		endParams.Init(m_beamEndPosition, 4.0f, 0.001f);
		PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
	}
	if ( hasParam[STRIDERFX_AFTERGLOW_COLOR] && gunVisible )
	{
		IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
		float size = AFTERGLOW_SIZE;// * params[STRIDERFX_FLARE_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_AFTERGLOW_COLOR].x * gunFractionVisible;
		ScaleColor( color, white, bright );

		pRenderContext->Bind( pMat, (IClientRenderable*)this );
		Strider_DrawSprite( m_worldPosition, size, color );

		dlight_t *dl = effects->CL_AllocDlight( m_entityIndex );
		dl->origin = m_worldPosition;
		dl->color.r = 40;
		dl->color.g = 60;
		dl->color.b = 255;
		dl->color.exponent = 5;
		dl->radius = bright * 128;
		dl->die = gpGlobals->curtime + 0.001;
	}

	if ( m_t >= STRIDERFX_END_ALL_TIME && !hasAny )
	{
		EffectShutdown();
	}
	return 1;
}
Esempio n. 10
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : timeDelta - 
//-----------------------------------------------------------------------------
void C_Flare::Update( float timeDelta )
{
	if ( !IsVisible() )
		return;

	CSimpleEmitter::Update( timeDelta );

	//Make sure our stored resources are up to date
	RestoreResources();

	//Don't do this if the console is down
	if ( timeDelta <= 0.0f )
		return;

	//Check for LOS
	pixelvis_queryparams_t params;
	params.Init(GetAbsOrigin());
	params.proxySize = 8.0f; // Inches
	
	float visible = PixelVisibility_FractionVisible( params, &m_queryHandle );

	float	fColor;
#ifdef HL2_CLIENT_DLL
	float	baseScale = m_flScale;
#else
	// NOTE!!!  This is bigger by a factor of 1.2 to deal with fixing a bug from HL2.  See dlight_t.h
	float	baseScale = m_flScale * 1.2f;
#endif

	//Account for fading out
	if ( ( m_flTimeBurnOut != -1.0f ) && ( ( m_flTimeBurnOut - gpGlobals->curtime ) <= 10.0f ) )
	{
		baseScale *= ( ( m_flTimeBurnOut - gpGlobals->curtime ) / 10.0f );
	}

	bool bVisible = (baseScale < 0.01f || visible == 0.0f) ? false : true;
	//Clamp the scale if vanished
	if ( !bVisible )
	{
		if ( m_pParticle[0] != NULL )
		{	
			m_pParticle[0]->m_flDieTime		= gpGlobals->curtime;
			m_pParticle[0]->m_uchStartSize	= m_pParticle[0]->m_uchEndSize = 0;
			m_pParticle[0]->m_uchColor[0]	= 0;
			m_pParticle[0]->m_uchColor[1]	= 0;
			m_pParticle[0]->m_uchColor[2]	= 0;
		}

		if ( m_pParticle[1] != NULL )
		{	
			m_pParticle[1]->m_flDieTime		= gpGlobals->curtime;
			m_pParticle[1]->m_uchStartSize	= m_pParticle[1]->m_uchEndSize = 0;
			m_pParticle[1]->m_uchColor[0]	= 0;
			m_pParticle[1]->m_uchColor[1]	= 0;
			m_pParticle[1]->m_uchColor[2]	= 0;
		}
	}

	if ( baseScale < 0.01f )
		return;
	//
	// Dynamic light
	//

	if ( m_bLight )
	{
		dlight_t *dl= effects->CL_AllocDlight( index );

		

		if ( m_bPropFlare == false )
		{
			dl->origin	= GetAbsOrigin();
			dl->color.r = 255;
			dl->die		= gpGlobals->curtime + 0.1f;

			dl->radius	= baseScale * random->RandomFloat( 110.0f, 128.0f );
			dl->color.g = dl->color.b = random->RandomInt( 32, 64 );
		}
		else
		{
			if ( m_iAttachment == -1 )
			{
				m_iAttachment =  LookupAttachment( "fuse" );
			}

			if ( m_iAttachment != -1 )
			{
				Vector effect_origin;
				QAngle effect_angles;
				
				GetAttachment( m_iAttachment, effect_origin, effect_angles );

				//Raise the light a little bit away from the flare so it lights it up better.
				dl->origin	= effect_origin + Vector( 0, 0, 4 );
				dl->color.r = 255;
				dl->die		= gpGlobals->curtime + 0.1f;

				dl->radius	= baseScale * random->RandomFloat( 245.0f, 256.0f );
				dl->color.g = dl->color.b = random->RandomInt( 95, 128 );
		
				dlight_t *el= effects->CL_AllocElight( index );

				el->origin	= effect_origin;
				el->color.r = 255;
				el->color.g = dl->color.b = random->RandomInt( 95, 128 );
				el->radius	= baseScale * random->RandomFloat( 260.0f, 290.0f );
				el->die		= gpGlobals->curtime + 0.1f;
			}
		}
	}

	//
	// Smoke
	//

	float dt = timeDelta;

	if ( m_bSmoke )
	{
		while ( m_teSmokeSpawn.NextEvent( dt ) )
		{
			Vector	smokeOrg = GetAbsOrigin();

			Vector	flareScreenDir = ( smokeOrg - MainViewOrigin() );
			VectorNormalize( flareScreenDir );

			smokeOrg = smokeOrg + ( flareScreenDir * 2.0f );
			smokeOrg[2] += baseScale * 4.0f;

			SimpleParticle *sParticle = (SimpleParticle *) AddParticle( sizeof( SimpleParticle ), g_Mat_DustPuff[1], smokeOrg );
				
			if ( sParticle == NULL )
				return;

			sParticle->m_flLifetime		= 0.0f;
			sParticle->m_flDieTime		= 1.0f;
			
			sParticle->m_vecVelocity	= Vector( random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( -16.0f, 16.0f ), random->RandomFloat( 8.0f, 16.0f ) + 32.0f );

			if ( m_bPropFlare )
			{
				sParticle->m_uchColor[0]	= 255;
				sParticle->m_uchColor[1]	= 100;
				sParticle->m_uchColor[2]	= 100;
			}
			else
			{
				sParticle->m_uchColor[0]	= 255;
				sParticle->m_uchColor[1]	= 48;
				sParticle->m_uchColor[2]	= 48;
			}

			sParticle->m_uchStartAlpha	= random->RandomInt( 64, 90 );
			sParticle->m_uchEndAlpha	= 0;
			sParticle->m_uchStartSize	= random->RandomInt( 2, 4 );
			sParticle->m_uchEndSize		= sParticle->m_uchStartSize * 8.0f;
			sParticle->m_flRoll			= random->RandomInt( 0, 2*M_PI );
			sParticle->m_flRollDelta	= random->RandomFloat( -(M_PI/6.0f), M_PI/6.0f );
		}
	}

	if ( !bVisible )
		return;

	//
	// Outer glow
	//

	Vector	offset;
	
	//Cause the base of the effect to shake
	offset.Random( -0.5f * baseScale, 0.5f * baseScale );
	offset += GetAbsOrigin();

	if ( m_pParticle[0] != NULL )
	{
		m_pParticle[0]->m_Pos			= offset;
		m_pParticle[0]->m_flLifetime	= 0.0f;
		m_pParticle[0]->m_flDieTime		= 2.0f;
		
		m_pParticle[0]->m_vecVelocity.Init();

		fColor = random->RandomInt( 100.0f, 128.0f ) * visible;

		m_pParticle[0]->m_uchColor[0]	= fColor;
		m_pParticle[0]->m_uchColor[1]	= fColor;
		m_pParticle[0]->m_uchColor[2]	= fColor;
		m_pParticle[0]->m_uchStartAlpha	= fColor;
		m_pParticle[0]->m_uchEndAlpha	= fColor;
		m_pParticle[0]->m_uchStartSize	= baseScale * (float) random->RandomInt( 32, 48 );
		m_pParticle[0]->m_uchEndSize	= m_pParticle[0]->m_uchStartSize;
		m_pParticle[0]->m_flRollDelta	= 0.0f;
		
		if ( random->RandomInt( 0, 4 ) == 3 )
		{
			m_pParticle[0]->m_flRoll	+= random->RandomInt( 2, 8 );
		}
	}

	//
	// Inner core
	//

	//Cause the base of the effect to shake
	offset.Random( -1.0f * baseScale, 1.0f * baseScale );
	offset += GetAbsOrigin();

	if ( m_pParticle[1] != NULL )
	{
		m_pParticle[1]->m_Pos			= offset;
		m_pParticle[1]->m_flLifetime	= 0.0f;
		m_pParticle[1]->m_flDieTime		= 2.0f;
		
		m_pParticle[1]->m_vecVelocity.Init();

		fColor = 255 * visible;

		m_pParticle[1]->m_uchColor[0]	= fColor;
		m_pParticle[1]->m_uchColor[1]	= fColor;
		m_pParticle[1]->m_uchColor[2]	= fColor;
		m_pParticle[1]->m_uchStartAlpha	= fColor;
		m_pParticle[1]->m_uchEndAlpha	= fColor;
		m_pParticle[1]->m_uchStartSize	= baseScale * (float) random->RandomInt( 2, 4 );
		m_pParticle[1]->m_uchEndSize	= m_pParticle[0]->m_uchStartSize;
		m_pParticle[1]->m_flRoll		= random->RandomInt( 0, 360 );
	}
}