//----------------------------------------------------------------------------- // Bounding box //----------------------------------------------------------------------------- CNewParticleEffect* CNewParticleEffect::ReplaceWith( const char *pParticleSystemName ) { StopEmission( false, true, true ); if ( !pParticleSystemName || !pParticleSystemName[0] ) return NULL; CNewParticleEffect *pNewEffect = CNewParticleEffect::Create( GetOwner(), pParticleSystemName, pParticleSystemName ); if ( !pNewEffect ) return NULL; // Copy over the control point data for ( int i = 0; i < MAX_PARTICLE_CONTROL_POINTS; ++i ) { if ( !ReadsControlPoint( i ) ) continue; Vector vecForward, vecRight, vecUp; pNewEffect->SetControlPoint( i, GetControlPointAtCurrentTime( i ) ); GetControlPointOrientationAtCurrentTime( i, &vecForward, &vecRight, &vecUp ); pNewEffect->SetControlPointOrientation( i, vecForward, vecRight, vecUp ); pNewEffect->SetControlPointParent( i, GetControlPointParent( i ) ); } if ( m_hOwner ) { m_hOwner->ParticleProp()->ReplaceParticleEffect( this, pNewEffect ); } // fixup any other references to the old system, to point to the new system while( m_References.m_pHead ) { // this will remove the reference from m_References m_References.m_pHead->Set( pNewEffect ); } // At this point any references should have been redirected, // but we may still be running with some stray particles, so we // might not be flagged for removal - force the issue! Assert( m_RefCount == 0 ); SetRemoveFlag(); return pNewEffect; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_ParticleSystem::ClientThink( void ) { if ( m_bActive ) { const char *pszName = GetParticleSystemNameFromIndex( m_iEffectIndex ); if ( pszName && pszName[0] ) { CNewParticleEffect *pEffect = ParticleProp()->Create( pszName, PATTACH_ABSORIGIN_FOLLOW ); m_pEffect = pEffect; if (pEffect) { for ( int i = 0 ; i < kMAXCONTROLPOINTS ; ++i ) { CBaseEntity *pOnEntity = m_hControlPointEnts[i].Get(); if ( pOnEntity ) { ParticleProp()->AddControlPoint( pEffect, i + 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW ); } AssertMsg2( m_iControlPointParents[i] >= 0 && m_iControlPointParents[i] <= kMAXCONTROLPOINTS , "Particle system specified bogus control point parent (%d) for point %d.", m_iControlPointParents[i], i ); if (m_iControlPointParents[i] != 0) { pEffect->SetControlPointParent(i+1, m_iControlPointParents[i]); } } //server controlled control points (variables in particle effects instead of literal follow points) for( int i = 0; i != ARRAYSIZE( m_iServerControlPointAssignments ); ++i ) { if( m_iServerControlPointAssignments[i] != 255 ) { pEffect->SetControlPoint( m_iServerControlPointAssignments[i], m_vServerControlPoints[i] ); } else { break; } } // Attach our particle snapshot if we have one Assert( m_pSnapshot || !m_szSnapshotFileName[0] ); // m_szSnapshotFileName shouldn't change after the create update if ( m_pSnapshot ) { pEffect->SetControlPointSnapshot( 0, m_pSnapshot ); } // NOTE: What we really want here is to compare our lifetime and that of our children and see if this delta is // already past the end of it, denoting that we're finished. In that case, just destroy us and be done. -- jdw // TODO: This can go when the SkipToTime code below goes ParticleProp()->OnParticleSystemUpdated( pEffect, 0.0f ); // Skip the effect ahead if we're restarting it float flTimeDelta = gpGlobals->curtime - m_flStartTime; if ( flTimeDelta > 0.01f ) { VPROF_BUDGET( "C_ParticleSystem::ClientThink SkipToTime", "Particle Simulation" ); pEffect->SkipToTime( flTimeDelta ); } } } } }
//----------------------------------------------------------------------------- // Purpose: Message handler for ASWOrderUseItemFX message //----------------------------------------------------------------------------- void CASW_Hud_Squad_Hotbar::MsgFunc_ASWOrderUseItemFX( bf_read &msg ) { int iMarine = msg.ReadShort(); C_ASW_Marine *pMarine = dynamic_cast<C_ASW_Marine*>(ClientEntityList().GetEnt(iMarine)); // turn iMarine ent index into the marine if ( !pMarine ) return; int iOrderType = msg.ReadShort(); int iInventorySlot = msg.ReadShort(); Vector vecPosition; vecPosition.x = msg.ReadFloat(); vecPosition.y = msg.ReadFloat(); vecPosition.z = msg.ReadFloat(); // loops through to see if we already have an order effect for this marine StopItemFX( pMarine ); const char *pszClassName = NULL; switch( iOrderType ) { case ASW_USE_ORDER_WITH_ITEM: { // check we have an item in that slot CASW_Weapon* pWeapon = pMarine->GetASWWeapon( iInventorySlot ); if ( !pWeapon || !pWeapon->GetWeaponInfo() || !pWeapon->GetWeaponInfo()->m_bOffhandActivate ) return; pszClassName = pWeapon->GetClassname(); } break; case ASW_USE_ORDER_HACK: { pszClassName = "asw_weapon_t75"; // for now, we're using the t75 icon for hacking } break; default: { Assert( false ); // unspecified order type return; } break; } //CNewParticleEffect *pEffect = pMarine->ParticleProp()->Create( "order_use_item", PATTACH_CUSTOMORIGIN, -1, vecPosition - pMarine->GetAbsOrigin() ); CNewParticleEffect *pEffect = pMarine->ParticleProp()->Create( "order_use_item", PATTACH_ABSORIGIN ); if ( pEffect ) { pMarine->ParticleProp()->AddControlPoint( pEffect, 1, pMarine, PATTACH_CUSTOMORIGIN ); pEffect->SetControlPoint( 1, vecPosition );//vecPosition - pMarine->GetAbsOrigin() for ( int i = 0; i < NUM_USE_ITEM_ORDER_CLASSES; i++ ) { if ( pszUseItemOrderClasses[i] && !Q_strcmp ( pszUseItemOrderClasses[i] , pszClassName ) ) { pEffect->SetControlPoint( 2, Vector( i, 0, 0 ) ); break; } } HotbarOrderEffectsList_t::IndexLocalType_t iIndex = m_hHotbarOrderEffects.AddToTail(); m_hHotbarOrderEffects[iIndex].iEffectID = iMarine; m_hHotbarOrderEffects[iIndex].pEffect = pEffect; } }