//----------------------------------------------------------------------------- // Creates the efficient spotlight //----------------------------------------------------------------------------- void CPointSpotlight::CreateEfficientSpotlight() { if ( m_hSpotlightTarget.Get() != NULL ) return; SpotlightCreate(); m_vSpotlightCurrentPos = SpotlightCurrentPos(); m_hSpotlightTarget->SetAbsOrigin( m_vSpotlightCurrentPos ); m_hSpotlightTarget->m_vSpotlightOrg = GetAbsOrigin(); VectorSubtract( m_hSpotlightTarget->GetAbsOrigin(), m_hSpotlightTarget->m_vSpotlightOrg, m_hSpotlightTarget->m_vSpotlightDir ); m_flSpotlightCurLength = VectorNormalize( m_hSpotlightTarget->m_vSpotlightDir ); m_hSpotlightTarget->SetMoveType( MOVETYPE_NONE ); ComputeRenderInfo(); }
//----------------------------------------------------------------------------- // Purpose: // Input : flags - // Output : int //----------------------------------------------------------------------------- int C_EntityDissolve::DrawModel( int flags ) { // See if we should draw if ( gpGlobals->frametime == 0 || m_bReadyToDraw == false ) return 0; C_BaseAnimating *pAnimating = GetMoveParent() ? GetMoveParent()->GetBaseAnimating() : NULL; if ( pAnimating == NULL ) return 0; matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) == false ) return 0; studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if ( pStudioHdr == NULL ) return false; mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); if ( set == NULL ) return false; // Make sure the emitter is setup properly SetupEmitter(); // Get fade percentages for the effect float fadeInPerc = GetFadeInPercentage(); float fadeOutPerc = GetFadeOutPercentage(); float fadePerc = ( fadeInPerc >= 1.0f ) ? fadeOutPerc : fadeInPerc; Vector vecSkew = vec3_origin; // Do extra effects under certain circumstances if ( ( fadePerc < 0.99f ) && ( (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL) || (m_nDissolveType == ENTITY_DISSOLVE_ELECTRICAL_LIGHT) ) ) { DoSparks( set, hitboxbones ); } // Skew the particles in front or in back of their targets vecSkew = CurrentViewForward() * ( 8.0f - ( ( 1.0f - fadePerc ) * 32.0f ) ); float spriteScale = ( ( gpGlobals->curtime - m_flStartTime ) / m_flFadeOutLength ); spriteScale = clamp( spriteScale, 0.75f, 1.0f ); // Cache off this material reference if ( g_Material_Spark == NULL ) { g_Material_Spark = ParticleMgr()->GetPMaterial( "effects/spark" ); } if ( g_Material_AR2Glow == NULL ) { g_Material_AR2Glow = ParticleMgr()->GetPMaterial( "effects/combinemuzzle2" ); } SimpleParticle *sParticle; for ( int i = 0; i < set->numhitboxes; ++i ) { Vector vecAbsOrigin, xvec, yvec; mstudiobbox_t *pBox = set->pHitbox(i); ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec ); Vector offset; Vector xDir, yDir; xDir = xvec; float xScale = VectorNormalize( xDir ) * 0.75f; yDir = yvec; float yScale = VectorNormalize( yDir ) * 0.75f; int numParticles = clamp( 3.0f * fadePerc, 0.f, 3.f ); int iTempParts = 2; if ( m_nDissolveType == ENTITY_DISSOLVE_CORE ) { if ( m_bCoreExplode == true ) { numParticles = 15; iTempParts = 20; } } for ( int j = 0; j < iTempParts; j++ ) { // Skew the origin offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f ); offset += vecSkew; if ( random->RandomInt( 0, 2 ) != 0 ) continue; sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_Spark, vecAbsOrigin + offset ); if ( sParticle == NULL ) return 1; sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( 16.0f, 64.0f ) ); if ( m_nDissolveType == ENTITY_DISSOLVE_CORE ) { if ( m_bCoreExplode == true ) { Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin; VectorNormalize( vDirection ); sParticle->m_vecVelocity = vDirection * m_nMagnitude; } } if ( sParticle->m_vecVelocity.z > 0 ) { sParticle->m_uchStartSize = random->RandomFloat( 4, 6 ) * spriteScale; } else { sParticle->m_uchStartSize = 2 * spriteScale; } sParticle->m_flDieTime = random->RandomFloat( 0.4f, 0.5f ); // If we're the last particles, last longer if ( numParticles == 0 ) { sParticle->m_flDieTime *= 2.0f; sParticle->m_uchStartSize = 2 * spriteScale; sParticle->m_flRollDelta = Helper_RandomFloat( -4.0f, 4.0f ); if ( m_nDissolveType == ENTITY_DISSOLVE_CORE ) { if ( m_bCoreExplode == true ) { sParticle->m_flDieTime *= 2.0f; sParticle->m_flRollDelta = Helper_RandomFloat( -1.0f, 1.0f ); } } } else { sParticle->m_flRollDelta = Helper_RandomFloat( -8.0f, 8.0f ); } sParticle->m_flLifetime = 0.0f; sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); float alpha = 255; sParticle->m_uchColor[0] = m_vEffectColor.x; sParticle->m_uchColor[1] = m_vEffectColor.y; sParticle->m_uchColor[2] = m_vEffectColor.z; sParticle->m_uchStartAlpha = alpha; sParticle->m_uchEndAlpha = 0; sParticle->m_uchEndSize = 0; } for ( int j = 0; j < numParticles; j++ ) { offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f ); offset += vecSkew; sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), g_Material_AR2Glow, vecAbsOrigin + offset ); if ( sParticle == NULL ) return 1; sParticle->m_vecVelocity = Vector( Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -4.0f, 4.0f ), Helper_RandomFloat( -64.0f, 128.0f ) ); sParticle->m_uchStartSize = random->RandomFloat( 8, 12 ) * spriteScale; sParticle->m_flDieTime = 0.1f; sParticle->m_flLifetime = 0.0f; sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f ); float alpha = 255; sParticle->m_uchColor[0] = m_vEffectColor.x; sParticle->m_uchColor[1] = m_vEffectColor.y; sParticle->m_uchColor[2] = m_vEffectColor.z; sParticle->m_uchStartAlpha = alpha; sParticle->m_uchEndAlpha = 0; sParticle->m_uchEndSize = 0; if ( m_nDissolveType == ENTITY_DISSOLVE_CORE ) { if ( m_bCoreExplode == true ) { Vector vDirection = (vecAbsOrigin + offset) - m_vDissolverOrigin; VectorNormalize( vDirection ); sParticle->m_vecVelocity = vDirection * m_nMagnitude; sParticle->m_flDieTime = 0.5f; } } } } return 1; }
//----------------------------------------------------------------------------- // Purpose: // Input : flags - // Output : int //----------------------------------------------------------------------------- int C_WeaponPhysCannon::DrawModel( int flags ) { // If we're not ugrading, don't do anything special if ( m_bIsCurrentlyUpgrading == false && m_bWasUpgraded == false ) return BaseClass::DrawModel( flags ); if ( gpGlobals->frametime == 0 ) return BaseClass::DrawModel( flags ); if ( !m_bReadyToDraw ) return 0; m_bWasUpgraded = true; // Create the particle emitter if it's not already if ( SetupEmitter() ) { // Add the power-up particles // See if we should draw if ( m_bReadyToDraw == false ) return 0; C_BaseAnimating *pAnimating = GetBaseAnimating(); if (!pAnimating) return 0; matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; if ( !pAnimating->HitboxToWorldTransforms( hitboxbones ) ) return 0; studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if (!pStudioHdr) return false; mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); if ( !set ) return false; int i; float fadePerc = 1.0f; if ( m_bIsCurrentlyUpgrading ) { Vector vecSkew = vec3_origin; // Skew the particles in front or in back of their targets vecSkew = CurrentViewForward() * 4.0f; float spriteScale = 1.0f; spriteScale = clamp( spriteScale, 0.75f, 1.0f ); SimpleParticle *sParticle; for ( i = 0; i < set->numhitboxes; ++i ) { Vector vecAbsOrigin, xvec, yvec; mstudiobbox_t *pBox = set->pHitbox(i); ComputeRenderInfo( pBox, *hitboxbones[pBox->bone], &vecAbsOrigin, &xvec, &yvec ); Vector offset; Vector xDir, yDir; xDir = xvec; float xScale = VectorNormalize( xDir ) * 0.75f; yDir = yvec; float yScale = VectorNormalize( yDir ) * 0.75f; int numParticles = clamp( 4.0f * fadePerc, 1, 3 ); for ( int j = 0; j < numParticles; j++ ) { offset = xDir * Helper_RandomFloat( -xScale*0.5f, xScale*0.5f ) + yDir * Helper_RandomFloat( -yScale*0.5f, yScale*0.5f ); offset += vecSkew; sParticle = (SimpleParticle *) m_pEmitter->AddParticle( sizeof(SimpleParticle), m_pEmitter->GetPMaterial( "effects/combinemuzzle1" ), vecAbsOrigin + offset ); if ( sParticle == NULL ) return 1; sParticle->m_vecVelocity = vec3_origin; sParticle->m_uchStartSize = 16.0f * spriteScale; sParticle->m_flDieTime = 0.2f; sParticle->m_flLifetime = 0.0f; sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); sParticle->m_flRollDelta = Helper_RandomFloat( -2.0f, 2.0f ); float alpha = 40; sParticle->m_uchColor[0] = alpha; sParticle->m_uchColor[1] = alpha; sParticle->m_uchColor[2] = alpha; sParticle->m_uchStartAlpha = alpha; sParticle->m_uchEndAlpha = 0; sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2; } } } } int attachment = LookupAttachment( "core" ); Vector coreOrigin; QAngle coreAngles; GetAttachment( attachment, coreOrigin, coreAngles ); SimpleParticle *sParticle; // Do the core effects for ( int i = 0; i < 4; i++ ) { sParticle = (SimpleParticle *) m_pLocalEmitter->AddParticle( sizeof(SimpleParticle), m_pLocalEmitter->GetPMaterial( "effects/strider_muzzle" ), vec3_origin ); if ( sParticle == NULL ) return 1; sParticle->m_vecVelocity = vec3_origin; sParticle->m_flDieTime = 0.1f; sParticle->m_flLifetime = 0.0f; sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); sParticle->m_flRollDelta = 0.0f; float alpha = 255; sParticle->m_uchColor[0] = alpha; sParticle->m_uchColor[1] = alpha; sParticle->m_uchColor[2] = alpha; sParticle->m_uchStartAlpha = alpha; sParticle->m_uchEndAlpha = 0; if ( i < 2 ) { sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1); sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f; } else { if ( random->RandomInt( 0, 20 ) == 0 ) { sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1); sParticle->m_uchEndSize = sParticle->m_uchStartSize * 4.0f; sParticle->m_flDieTime = 0.25f; } else { sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ) * (i+1); sParticle->m_uchEndSize = sParticle->m_uchStartSize * 2.0f; } } } if ( m_bWasUpgraded && m_bIsCurrentlyUpgrading ) { // Update our attractor point m_pAttractor->SetAttractorOrigin( coreOrigin ); Vector offset; for ( int i = 0; i < 4; i++ ) { offset = coreOrigin + RandomVector( -32.0f, 32.0f ); sParticle = (SimpleParticle *) m_pAttractor->AddParticle( sizeof(SimpleParticle), m_pAttractor->GetPMaterial( "effects/strider_muzzle" ), offset ); if ( sParticle == NULL ) return 1; sParticle->m_vecVelocity = Vector(0,0,8); sParticle->m_flDieTime = 0.5f; sParticle->m_flLifetime = 0.0f; sParticle->m_flRoll = Helper_RandomInt( 0, 360 ); sParticle->m_flRollDelta = 0.0f; float alpha = 255; sParticle->m_uchColor[0] = alpha; sParticle->m_uchColor[1] = alpha; sParticle->m_uchColor[2] = alpha; sParticle->m_uchStartAlpha = alpha; sParticle->m_uchEndAlpha = 0; sParticle->m_uchStartSize = random->RandomFloat( 1, 2 ); sParticle->m_uchEndSize = 0; } } return BaseClass::DrawModel( flags ); }
//------------------------------------------------------------------------------ // Purpose : Update the direction and position of my spotlight // Input : // Output : //------------------------------------------------------------------------------ void CPointSpotlight::SpotlightUpdate(void) { // --------------------------------------------------- // If I don't have a spotlight attempt to create one // --------------------------------------------------- if ( !m_hSpotlight ) { if ( m_bSpotlightOn ) { // Make the spotlight SpotlightCreate(); } else { return; } } else if ( !m_bSpotlightOn ) { SpotlightDestroy(); return; } if ( !m_hSpotlightTarget ) { DevWarning( "**Attempting to update point_spotlight but target ent is NULL\n" ); SpotlightDestroy(); SpotlightCreate(); if ( !m_hSpotlightTarget ) return; } m_vSpotlightCurrentPos = SpotlightCurrentPos(); // Update spotlight target velocity Vector vTargetDir; VectorSubtract( m_vSpotlightCurrentPos, m_hSpotlightTarget->GetAbsOrigin(), vTargetDir ); float vTargetDist = vTargetDir.Length(); // If we haven't moved at all, don't recompute if ( vTargetDist < 1 ) { m_hSpotlightTarget->SetAbsVelocity( vec3_origin ); return; } Vector vecNewVelocity = vTargetDir; VectorNormalize(vecNewVelocity); vecNewVelocity *= (10 * vTargetDist); // If a large move is requested, just jump to final spot as we probably hit a discontinuity if (vecNewVelocity.Length() > 200) { VectorNormalize(vecNewVelocity); vecNewVelocity *= 200; VectorNormalize(vTargetDir); m_hSpotlightTarget->SetAbsOrigin( m_vSpotlightCurrentPos ); } m_hSpotlightTarget->SetAbsVelocity( vecNewVelocity ); m_hSpotlightTarget->m_vSpotlightOrg = GetAbsOrigin(); // Avoid sudden change in where beam fades out when cross disconinuities VectorSubtract( m_hSpotlightTarget->GetAbsOrigin(), m_hSpotlightTarget->m_vSpotlightOrg, m_hSpotlightTarget->m_vSpotlightDir ); float flBeamLength = VectorNormalize( m_hSpotlightTarget->m_vSpotlightDir ); m_flSpotlightCurLength = (0.60*m_flSpotlightCurLength) + (0.4*flBeamLength); ComputeRenderInfo(); //NDebugOverlay::Cross3D(GetAbsOrigin(),Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1); //NDebugOverlay::Cross3D(m_vSpotlightCurrentPos,Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1); //NDebugOverlay::Cross3D(m_vSpotlightTargetPos,Vector(-5,-5,-5),Vector(5,5,5),255,0,0,true,0.1); }
//----------------------------------------------------------------------------- void C_BeamSpotLight::ClientThink( void ) { float dt = gpGlobals->curtime - m_lastTime; if ( !m_lastTime ) { dt = 0.0f; } m_lastTime = gpGlobals->curtime; // --------------------------------------------------- // If I don't have a spotlight attempt to create one // --------------------------------------------------- if ( !m_hSpotlight ) { if ( m_bSpotlightOn ) { // Make the spotlight SpotlightCreate(); } else { SetNextClientThink( CLIENT_THINK_NEVER ); return; } } else if ( !m_bSpotlightOn ) { SpotlightDestroy(); SetNextClientThink( CLIENT_THINK_NEVER ); return; } // update rotation if ( m_flRotationSpeed != 0.0f ) { QAngle angles = GetAbsAngles(); angles[m_nRotationAxis] += m_flRotationSpeed * dt; angles[m_nRotationAxis] = anglemod(angles[m_nRotationAxis]); if ( !m_pCache ) { m_pCache = new CSpotlightTraceCacheEntry[NUM_CACHE_ENTRIES]; } SetAbsAngles( angles ); } m_vSpotlightCurrentPos = SpotlightCurrentPos(); Assert( m_hSpotlight ); m_hSpotlight->SetStartPos( GetAbsOrigin() ); m_hSpotlight->SetEndPos( m_vSpotlightCurrentPos ); // Avoid sudden change in where beam fades out when cross disconinuities Vector dir = m_vSpotlightCurrentPos - GetAbsOrigin(); float flBeamLength = VectorNormalize( dir ); m_flSpotlightCurLength = (0.60*m_flSpotlightCurLength) + (0.4*flBeamLength); ComputeRenderInfo(); m_hSpotlight->RelinkBeam(); //NDebugOverlay::Cross3D(GetAbsOrigin(),Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1); //NDebugOverlay::Cross3D(m_vSpotlightCurrentPos,Vector(-5,-5,-5),Vector(5,5,5),0,255,0,true,0.1); //NDebugOverlay::Cross3D(m_vSpotlightTargetPos,Vector(-5,-5,-5),Vector(5,5,5),255,0,0,true,0.1); // Do we need to keep updating? if ( !GetMoveParent() && m_flRotationSpeed == 0 ) { // No reason to think again, we're not going to move unless there's a data change SetNextClientThink( CLIENT_THINK_NEVER ); } }