From 7f6e4cc4fc3a9f472c7742080ffa4706b7fb9af8 Mon Sep 17 00:00:00 2001 From: Horiuchi Date: Wed, 27 Aug 2025 18:57:25 -0400 Subject: [PATCH] Add "ParticleEffectStopAndDestroy" Client Effect and "DestroyImmediately" Input for info_particle_system --- src/game/client/c_particle_system.cpp | 38 ++++++++++++++++++++++++--- src/game/server/particle_system.cpp | 13 +++++++++ src/game/server/particle_system.h | 2 ++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/game/client/c_particle_system.cpp b/src/game/client/c_particle_system.cpp index e0aee808b1a..26d5bb35ab5 100644 --- a/src/game/client/c_particle_system.cpp +++ b/src/game/client/c_particle_system.cpp @@ -33,6 +33,7 @@ class C_ParticleSystem : public C_BaseEntity int m_iEffectIndex; bool m_bActive; bool m_bOldActive; + bool m_bDestroyImmediately; float m_flStartTime; // Time at which the effect started enum { kMAXCONTROLPOINTS = 63 }; ///< actually one less than the total number of cpoints since 0 is assumed to be me @@ -56,6 +57,7 @@ BEGIN_RECV_TABLE_NOBASE( C_ParticleSystem, DT_ParticleSystem ) RecvPropInt( RECVINFO( m_iEffectIndex ) ), RecvPropBool( RECVINFO( m_bActive ) ), + RecvPropBool( RECVINFO( m_bDestroyImmediately ) ), RecvPropFloat( RECVINFO( m_flStartTime ) ), RecvPropArray3( RECVINFO_ARRAY(m_hControlPointEnts), RecvPropEHandle( RECVINFO( m_hControlPointEnts[0] ) ) ), @@ -109,8 +111,15 @@ void C_ParticleSystem::PostDataUpdate( DataUpdateType_t updateType ) } else { - ParticleProp()->StopEmission(); - } + if ( m_bDestroyImmediately ) + { + ParticleProp()->StopEmissionAndDestroyImmediately(); + } + else + { + ParticleProp()->StopEmission(); + } + } } } } @@ -273,9 +282,30 @@ void ParticleEffectStopCallback( const CEffectData &data ) C_BaseEntity *pEnt = C_BaseEntity::Instance( data.m_hEntity ); if ( pEnt ) { - pEnt->ParticleProp()->StopEmission(); - } + pEnt->ParticleProp()->StopEmission(); } } +} DECLARE_CLIENT_EFFECT( "ParticleEffectStop", ParticleEffectStopCallback ); + + +//====================================================================================================================== +// PARTICLE SYSTEM STOP AND DESTROY EFFECT +//====================================================================================================================== +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void ParticleEffectDestroyImmediatelyCallback( const CEffectData& data ) +{ + if ( data.m_hEntity.Get() ) + { + C_BaseEntity* pEnt = C_BaseEntity::Instance( data.m_hEntity ); + if ( pEnt ) + { + pEnt->ParticleProp()->StopEmissionAndDestroyImmediately(); + } + } +} + +DECLARE_CLIENT_EFFECT( "ParticleEffectDestroyImmediately", ParticleEffectDestroyImmediatelyCallback ); diff --git a/src/game/server/particle_system.cpp b/src/game/server/particle_system.cpp index 33fcd32287d..655e67cc708 100644 --- a/src/game/server/particle_system.cpp +++ b/src/game/server/particle_system.cpp @@ -25,6 +25,7 @@ IMPLEMENT_SERVERCLASS_ST_NOBASE(CParticleSystem, DT_ParticleSystem) SendPropInt( SENDINFO(m_iEffectIndex), MAX_PARTICLESYSTEMS_STRING_BITS, SPROP_UNSIGNED ), SendPropBool( SENDINFO(m_bActive) ), + SendPropBool( SENDINFO(m_bDestroyImmediately) ), SendPropFloat( SENDINFO(m_flStartTime) ), SendPropArray3( SENDINFO_ARRAY3(m_hControlPointEnts), SendPropEHandle( SENDINFO_ARRAY(m_hControlPointEnts) ) ), @@ -38,6 +39,7 @@ BEGIN_DATADESC( CParticleSystem ) DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ), DEFINE_FIELD( m_flStartTime, FIELD_TIME ), DEFINE_KEYFIELD( m_iszEffectName, FIELD_STRING, "effect_name" ), + DEFINE_FIELD( m_bDestroyImmediately, FIELD_BOOLEAN ), //DEFINE_FIELD( m_iEffectIndex, FIELD_INTEGER ), // Don't save. Refind after loading. DEFINE_KEYFIELD( m_iszControlPointNames[0], FIELD_STRING, "cpoint1" ), @@ -116,6 +118,7 @@ BEGIN_DATADESC( CParticleSystem ) DEFINE_INPUTFUNC( FIELD_VOID, "Start", InputStart ), DEFINE_INPUTFUNC( FIELD_VOID, "Stop", InputStop ), + DEFINE_INPUTFUNC( FIELD_VOID, "DestroyImmediately", InputDestroyImmediately ), DEFINE_THINKFUNC( StartParticleSystemThink ), @@ -199,6 +202,7 @@ void CParticleSystem::StartParticleSystem( void ) { m_flStartTime = gpGlobals->curtime; m_bActive = true; + m_bDestroyImmediately = false; // Setup our control points at this time (in case our targets weren't around at spawn time) ReadControlPointEnts(); @@ -229,6 +233,15 @@ void CParticleSystem::InputStop( inputdata_t &inputdata ) StopParticleSystem(); } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CParticleSystem::InputDestroyImmediately( inputdata_t& inputdata ) +{ + StopParticleSystem(); + m_bDestroyImmediately = true; +} + //----------------------------------------------------------------------------- // Purpose: Find each entity referred to by m_iszControlPointNames and // resolve it into the corresponding slot in m_hControlPointEnts diff --git a/src/game/server/particle_system.h b/src/game/server/particle_system.h index ecf758c201a..4e50a7cab91 100644 --- a/src/game/server/particle_system.h +++ b/src/game/server/particle_system.h @@ -34,6 +34,7 @@ class CParticleSystem : public CBaseEntity void InputStart( inputdata_t &inputdata ); void InputStop( inputdata_t &inputdata ); + void InputDestroyImmediately( inputdata_t& inputdata ); void StartParticleSystemThink( void ); enum { kMAXCONTROLPOINTS = 63 }; ///< actually one less than the total number of cpoints since 0 is assumed to be me @@ -47,6 +48,7 @@ class CParticleSystem : public CBaseEntity string_t m_iszEffectName; CNetworkVar( bool, m_bActive ); + CNetworkVar( bool, m_bDestroyImmediately ); CNetworkVar( int, m_iEffectIndex ) CNetworkVar( float, m_flStartTime ); // Time at which this effect was started. This is used after restoring an active effect.