//----------------------------------------------------------------------------- // Purpose: Tesla effect //----------------------------------------------------------------------------- void C_EntityDissolve::BuildTeslaEffect( mstudiobbox_t *pHitBox, const matrix3x4_t &hitboxToWorld, bool bRandom, float flYawOffset ) { Vector vecOrigin; QAngle vecAngles; MatrixGetColumn( hitboxToWorld, 3, vecOrigin ); MatrixAngles( hitboxToWorld, vecAngles.Base() ); C_BaseEntity *pEntity = GetMoveParent(); // Make a couple of tries at it int iTries = -1; Vector vecForward; trace_t tr; do { iTries++; // Some beams are deliberatly aimed around the point, the rest are random. if ( !bRandom ) { QAngle vecTemp = vecAngles; vecTemp[YAW] += flYawOffset; AngleVectors( vecTemp, &vecForward ); // Randomly angle it up or down vecForward.z = RandomFloat( -1, 1 ); } else { vecForward = RandomVector( -1, 1 ); } UTIL_TraceLine( vecOrigin, vecOrigin + (vecForward * 192), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr ); } while ( tr.fraction >= 1.0 && iTries < 3 ); Vector vecEnd = tr.endpos - (vecForward * 8); // Only spark & glow if we hit something if ( tr.fraction < 1.0 ) { if ( !EffectOccluded( tr.endpos ) ) { // Move it towards the camera Vector vecFlash = tr.endpos; Vector vecForward; AngleVectors( MainViewAngles(), &vecForward ); vecFlash -= (vecForward * 8); g_pEffects->EnergySplash( vecFlash, -vecForward, false ); // End glow CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" ); pSimple->SetSortOrigin( vecFlash ); SimpleParticle *pParticle; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = RandomFloat( 0.5, 1 ); pParticle->m_vecVelocity = vec3_origin; Vector color( 1,1,1 ); float colorRamp = RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = RandomFloat( 6,13 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 10; pParticle->m_flRoll = RandomFloat( 0,360 ); pParticle->m_flRollDelta = 0; } } } // Build the tesla FX_BuildTesla( pEntity, vecOrigin, tr.endpos ); }
//----------------------------------------------------------------------------- // Purpose: // Input : timeDelta - //----------------------------------------------------------------------------- void C_SignalFlare::Update( float timeDelta ) { 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; float fColor; float baseScale = m_flScale; //Account for fading out if ( ( m_flDuration != -1.0f ) && ( ( m_flDuration - gpGlobals->curtime ) <= 10.0f ) ) { baseScale *= ( ( m_flDuration - gpGlobals->curtime ) / 10.0f ); } //Clamp the scale if vanished if ( baseScale < 0.01f ) { baseScale = 0.0f; 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; } return; } // // Dynamic light // if ( m_bLight ) { dlight_t *dl= effects->CL_AllocDlight( index ); dl->origin = GetAbsOrigin(); dl->color.r = 255; dl->color.g = dl->color.b = random->RandomInt( 32, 64 ); dl->radius = baseScale * random->RandomFloat( 110.0f, 128.0f ); dl->die = gpGlobals->curtime; } // // Smoke // if ( m_bSmoke ) { Vector smokeOrg = GetAbsOrigin(); Vector flareScreenDir = ( smokeOrg - CurrentViewOrigin() ); 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 ); fColor = random->RandomInt( 64, 128 ); sParticle->m_uchColor[0] = fColor+64; sParticle->m_uchColor[1] = fColor; sParticle->m_uchColor[2] = fColor; sParticle->m_uchStartAlpha = random->RandomInt( 16, 32 ); sParticle->m_uchEndAlpha = 0; sParticle->m_uchStartSize = random->RandomInt( 2, 4 ); sParticle->m_uchEndSize = sParticle->m_uchStartSize * 6.0f; sParticle->m_flRoll = random->RandomInt( 0, 360 ); sParticle->m_flRollDelta = random->RandomFloat( -2.0f, 2.0f ); } //Check for LOS if ( EffectOccluded( GetAbsOrigin() ) ) { if ( m_pParticle[0] != NULL ) { m_pParticle[0]->m_uchColor[0] *= 0.5f; m_pParticle[0]->m_uchColor[1] *= 0.5f; m_pParticle[0]->m_uchColor[2] *= 0.5f; } if ( m_pParticle[1] != NULL ) { m_pParticle[1]->m_uchColor[0] *= 0.25f; m_pParticle[1]->m_uchColor[1] *= 0.25f; m_pParticle[1]->m_uchColor[2] *= 0.25f; } 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 ); 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; 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 ); } }
void FX_Tesla( const CTeslaInfo &teslaInfo ) { C_BaseEntity *pEntity = ClientEntityList().GetEnt( teslaInfo.m_nEntIndex ); // Send out beams around us int iNumBeamsAround = (teslaInfo.m_nBeams * 2) / 3; // (2/3 of the beams are placed around in a circle) int iNumRandomBeams = teslaInfo.m_nBeams - iNumBeamsAround; int iTotalBeams = iNumBeamsAround + iNumRandomBeams; float flYawOffset = RandomFloat(0,360); for ( int i = 0; i < iTotalBeams; i++ ) { // Make a couple of tries at it int iTries = -1; Vector vecForward; trace_t tr; do { iTries++; // Some beams are deliberatly aimed around the point, the rest are random. if ( i < iNumBeamsAround ) { QAngle vecTemp = teslaInfo.m_vAngles; vecTemp[YAW] += anglemod( flYawOffset + ((360 / iTotalBeams) * i) ); AngleVectors( vecTemp, &vecForward ); // Randomly angle it up or down vecForward.z = RandomFloat( -1, 1 ); } else { vecForward = RandomVector( -1, 1 ); } VectorNormalize( vecForward ); UTIL_TraceLine( teslaInfo.m_vPos, teslaInfo.m_vPos + (vecForward * teslaInfo.m_flRadius), MASK_SHOT, pEntity, COLLISION_GROUP_NONE, &tr ); } while ( tr.fraction >= 1.0 && iTries < 3 ); Vector vecEnd = tr.endpos - (vecForward * 8); // Only spark & glow if we hit something if ( tr.fraction < 1.0 ) { if ( !EffectOccluded( tr.endpos, 0 ) ) { // Move it towards the camera Vector vecFlash = tr.endpos; Vector vecForward; AngleVectors( MainViewAngles(), &vecForward ); vecFlash -= (vecForward * 8); g_pEffects->EnergySplash( vecFlash, -vecForward, false ); // End glow CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" ); pSimple->SetSortOrigin( vecFlash ); SimpleParticle *pParticle; pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/tesla_glow_noz" ), vecFlash ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = RandomFloat( 0.5, 1 ); pParticle->m_vecVelocity = vec3_origin; Vector color( 1,1,1 ); float colorRamp = RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = MIN( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = MIN( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = MIN( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = RandomFloat( 6,13 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize - 2; pParticle->m_uchStartAlpha = 255; pParticle->m_uchEndAlpha = 10; pParticle->m_flRoll = RandomFloat( 0,360 ); pParticle->m_flRollDelta = 0; } } } // Build the tesla FX_BuildTesla( pEntity, teslaInfo.m_vPos, tr.endpos, teslaInfo.m_pszSpriteName, teslaInfo.m_flBeamWidth, teslaInfo.m_vColor, FBEAM_ONLYNOISEONCE, teslaInfo.m_flTimeVisible ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void FX_BuildWarp( Vector &vecOrigin, QAngle &vecAngles, float flScale ) { if ( EffectOccluded( vecOrigin, 0 ) ) return; CSmartPtr<CSimpleEmitter> pSimple = CSimpleEmitter::Create( "dust" ); pSimple->SetSortOrigin( vecOrigin ); SimpleParticle *pParticle; Vector color( 1, 1, 1 ); float colorRamp; // Big flash pParticle = (SimpleParticle *) pSimple->AddParticle( sizeof( SimpleParticle ), pSimple->GetPMaterial( "effects/blueflare2" ), vecOrigin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 0.5; pParticle->m_vecVelocity = vec3_origin; colorRamp = RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = RandomFloat( 10,15 ); pParticle->m_uchEndSize = pParticle->m_uchStartSize * 8 * flScale; pParticle->m_uchStartAlpha = 48; pParticle->m_uchEndAlpha = 0; pParticle->m_flRoll = 0; pParticle->m_flRollDelta = 0; } // Bright light // Move it towards the camera Vector vecForward; AngleVectors( MainViewAngles(), &vecForward ); vecOrigin -= (vecForward * 8); CSmartPtr<CWarpParticleEmitter> pWarpEmitter = CWarpParticleEmitter::Create( "dust" ); pWarpEmitter->SetSortOrigin( vecOrigin ); pParticle = (SimpleParticle *) pWarpEmitter->AddParticle( sizeof( SimpleParticle ), pWarpEmitter->GetPMaterial( "effects/human_build_warp" ), vecOrigin ); if ( pParticle != NULL ) { pParticle->m_flLifetime = 0.0f; pParticle->m_flDieTime = 0.4; pParticle->m_vecVelocity = vec3_origin; colorRamp = RandomFloat( 0.75f, 1.25f ); pParticle->m_uchColor[0] = min( 1.0f, color[0] * colorRamp ) * 255.0f; pParticle->m_uchColor[1] = min( 1.0f, color[1] * colorRamp ) * 255.0f; pParticle->m_uchColor[2] = min( 1.0f, color[2] * colorRamp ) * 255.0f; pParticle->m_uchStartSize = RandomInt( 10,13 ) * flScale; pParticle->m_uchEndSize = pParticle->m_uchStartSize * 9; pParticle->m_uchStartAlpha = 32; pParticle->m_uchEndAlpha = 192; pParticle->m_flRoll = 0; pParticle->m_flRollDelta = 0; } }