//====================================================================================================================== // PARTICLE SYSTEM DISPATCH EFFECT //====================================================================================================================== //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void ParticleEffectCallback( const CEffectData &data ) { if ( SuppressingParticleEffects() ) return; // this needs to be before using data.m_nHitBox, since that may be a serialized value that's past the end of the current particle system string table const char *pszName = GetParticleSystemNameFromIndex( data.m_nHitBox ); if ( data.m_fFlags & PARTICLE_DISPATCH_FROM_ENTITY ) { if ( data.m_hEntity.Get() ) { C_BaseEntity *pEnt = C_BaseEntity::Instance( data.m_hEntity ); if ( pEnt && !pEnt->IsDormant() ) { if ( data.m_fFlags & PARTICLE_DISPATCH_RESET_PARTICLES ) { pEnt->ParticleProp()->StopEmission(); } CSmartPtr<CNewParticleEffect> pEffect = pEnt->ParticleProp()->Create( pszName, (ParticleAttachment_t)data.m_nDamageType, data.m_nAttachmentIndex ); AssertMsg2( pEffect.IsValid() && pEffect->IsValid(), "%s could not create particle effect %s", C_BaseEntity::Instance( data.m_hEntity )->GetDebugName(), pszName ); if ( pEffect.IsValid() && pEffect->IsValid() ) { if ( (ParticleAttachment_t)data.m_nDamageType == PATTACH_CUSTOMORIGIN ) { pEffect->SetSortOrigin( data.m_vOrigin ); pEffect->SetControlPoint( 0, data.m_vOrigin ); pEffect->SetControlPoint( 1, data.m_vStart ); Vector vecForward, vecRight, vecUp; AngleVectors( data.m_vAngles, &vecForward, &vecRight, &vecUp ); pEffect->SetControlPointOrientation( 0, vecForward, vecRight, vecUp ); } } } } } else { CSmartPtr<CNewParticleEffect> pEffect = CNewParticleEffect::Create( NULL, pszName ); if ( pEffect->IsValid() ) { pEffect->SetSortOrigin( data.m_vOrigin ); pEffect->SetControlPoint( 0, data.m_vOrigin ); pEffect->SetControlPoint( 1, data.m_vStart ); Vector vecForward, vecRight, vecUp; AngleVectors( data.m_vAngles, &vecForward, &vecRight, &vecUp ); pEffect->SetControlPointOrientation( 0, vecForward, vecRight, vecUp ); } } }
C_BaseEntity* C_BaseEntityIterator::Next() { // Skip dormant entities while ( m_CurBaseEntity != ClientEntityList().m_BaseEntities.InvalidIndex() ) { C_BaseEntity *pRet = ClientEntityList().m_BaseEntities[m_CurBaseEntity]; m_CurBaseEntity = ClientEntityList().m_BaseEntities.Next( m_CurBaseEntity ); if (!pRet->IsDormant()) return pRet; } return NULL; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- Vector GetTracerOrigin( const CEffectData &data ) { Vector vecStart = data.m_vStart; QAngle vecAngles; int iAttachment = data.m_nAttachmentIndex;; // Attachment? if ( data.m_fFlags & TRACER_FLAG_USEATTACHMENT ) { C_BaseViewModel *pViewModel = NULL; // If the entity specified is a weapon being carried by this player, use the viewmodel instead IClientRenderable *pRenderable = data.GetRenderable(); if ( !pRenderable ) return vecStart; C_BaseEntity *pEnt = data.GetEntity(); // This check should probably be for all multiplayer games, investigate later #if defined( HL2MP ) || defined( TF_CLIENT_DLL ) || defined( TF_CLASSIC_CLIENT ) if ( pEnt && pEnt->IsDormant() ) return vecStart; #endif C_BaseCombatWeapon *pWpn = dynamic_cast<C_BaseCombatWeapon *>( pEnt ); if ( pWpn && pWpn->ShouldDrawUsingViewModel() ) { C_BasePlayer *player = ToBasePlayer( pWpn->GetOwner() ); // Use GetRenderedWeaponModel() instead? pViewModel = player ? player->GetViewModel( 0 ) : NULL; if ( pViewModel ) { // Get the viewmodel and use it instead pRenderable = pViewModel; } } // Get the attachment origin if ( !pRenderable->GetAttachment( iAttachment, vecStart, vecAngles ) ) { DevMsg( "GetTracerOrigin: Couldn't find attachment %d on model %s\n", iAttachment, modelinfo->GetModelName( pRenderable->GetModel() ) ); } } return vecStart; }
//====================================================================================================================== // PARTICLE SYSTEM DISPATCH EFFECT //====================================================================================================================== //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void StartParticleEffect( const CEffectData &data, int nSplitScreenPlayerSlot /*= -1*/ ) { // this needs to be before using data.m_nHitBox, // since that may be a serialized value that's past the end of the current particle system string table if ( SuppressingParticleEffects() ) return; // Don't crash if we're passed an invalid particle system if ( data.m_nHitBox == 0 ) return; if ( data.m_fFlags & PARTICLE_DISPATCH_FROM_ENTITY ) { if ( data.m_hEntity.Get() ) { C_BaseEntity *pEnt = C_BaseEntity::Instance( data.m_hEntity ); // commented out assert. dormant entities have their particle system spawns stopped. //Assert( pEnt && !pEnt->IsDormant() ); if ( pEnt && !pEnt->IsDormant() ) { if ( data.m_fFlags & PARTICLE_DISPATCH_RESET_PARTICLES ) { pEnt->ParticleProp()->StopEmission(); } CUtlReference<CNewParticleEffect> pEffect = pEnt->ParticleProp()->CreatePrecached( data.m_nHitBox, (ParticleAttachment_t)data.m_nDamageType, data.m_nAttachmentIndex ); if ( pEffect.IsValid() && pEffect->IsValid() ) { if ( (ParticleAttachment_t)data.m_nDamageType == PATTACH_CUSTOMORIGIN || (ParticleAttachment_t)data.m_nDamageType == PATTACH_CUSTOMORIGIN_FOLLOW ) { pEffect->SetDrawOnlyForSplitScreenUser( nSplitScreenPlayerSlot ); pEffect->SetSortOrigin( data.m_vOrigin ); if ( (ParticleAttachment_t)data.m_nDamageType == PATTACH_CUSTOMORIGIN_FOLLOW ) { Vector vecCtrl1 = (data.m_vStart - pEnt->GetAbsOrigin() ); pEffect->SetControlPoint( 1, vecCtrl1 ); pEffect->SetControlPointEntity( 1, pEnt ); Vector vecCtrl0 = (data.m_vOrigin - pEnt->GetAbsOrigin() ); matrix3x4_t mat; AngleMatrix( data.m_vAngles, mat ); pEnt->ParticleProp()->AddControlPoint( pEffect, 0, pEnt, PATTACH_CUSTOMORIGIN_FOLLOW, NULL, vecCtrl0, &mat ); } else { pEffect->SetControlPoint( 0, data.m_vOrigin ); pEffect->SetControlPoint( 1, data.m_vStart ); Vector vecForward, vecRight, vecUp; AngleVectors( data.m_vAngles, &vecForward, &vecRight, &vecUp ); pEffect->SetControlPointOrientation( 0, vecForward, vecRight, vecUp ); } } else if ( data.m_nOtherEntIndex > 0 ) { C_BaseEntity *pOtherEnt = ClientEntityList().GetEnt( data.m_nOtherEntIndex ); if ( pOtherEnt ) { pEnt->ParticleProp()->AddControlPoint( pEffect, 1, pOtherEnt, PATTACH_ABSORIGIN_FOLLOW, NULL, Vector( 0, 0, 50 ) ); } } } } } } else { CParticleSystemDefinition *pDef = g_pParticleSystemMgr->FindPrecachedParticleSystem( data.m_nHitBox ); if ( pDef ) { CUtlReference<CNewParticleEffect> pEffect = CNewParticleEffect::CreateOrAggregate( NULL, pDef, data.m_vOrigin, NULL, nSplitScreenPlayerSlot ); if ( pEffect.IsValid() && pEffect->IsValid() ) { pEffect->SetSortOrigin( data.m_vOrigin ); pEffect->SetControlPoint( 0, data.m_vOrigin ); pEffect->SetControlPoint( 1, data.m_vStart ); Vector vecForward, vecRight, vecUp; AngleVectors( data.m_vAngles, &vecForward, &vecRight, &vecUp ); pEffect->SetControlPointOrientation( 0, vecForward, vecRight, vecUp ); } } else { Warning( "StartParticleEffect: Failed to find precached particle system for %d!!\n", data.m_nHitBox ); } } }