diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/tf_fx_explosions.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/tf/tf_fx_explosions.cpp')
| -rw-r--r-- | game/client/tf/tf_fx_explosions.cpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/game/client/tf/tf_fx_explosions.cpp b/game/client/tf/tf_fx_explosions.cpp new file mode 100644 index 0000000..36d1365 --- /dev/null +++ b/game/client/tf/tf_fx_explosions.cpp @@ -0,0 +1,242 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Game-specific explosion effects +// +//=============================================================================// +#include "cbase.h" +#include "c_te_effect_dispatch.h" +#include "tempent.h" +#include "c_te_legacytempents.h" +#include "tf_shareddefs.h" +#include "engine/IEngineSound.h" +#include "tf_weapon_parse.h" +#include "c_basetempentity.h" +#include "tier0/vprof.h" +#include "c_tf_player.h" +#include "econ_item_system.h" +#include "c_tf_fx.h" +#include "networkstringtabledefs.h" + +//-------------------------------------------------------------------------------------------------------------- +CTFWeaponInfo *GetTFWeaponInfo( int iWeapon ) +{ + // Get the weapon information. + const char *pszWeaponAlias = WeaponIdToAlias( iWeapon ); + if ( !pszWeaponAlias ) + { + return NULL; + } + + WEAPON_FILE_INFO_HANDLE hWpnInfo = LookupWeaponInfoSlot( pszWeaponAlias ); + if ( hWpnInfo == GetInvalidWeaponInfoHandle() ) + { + return NULL; + } + + CTFWeaponInfo *pWeaponInfo = static_cast<CTFWeaponInfo*>( GetFileWeaponInfoFromHandle( hWpnInfo ) ); + return pWeaponInfo; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void TFExplosionCallback( const Vector &vecOrigin, const Vector &vecNormal, int iWeaponID, ClientEntityHandle_t hEntity, int nDefID, int nSound, int iCustomParticleIndex ) +{ + // Get the weapon information. + CTFWeaponInfo *pWeaponInfo = NULL; + switch( iWeaponID ) + { + case TF_WEAPON_GRENADE_PIPEBOMB: + case TF_WEAPON_GRENADE_DEMOMAN: + case TF_WEAPON_PUMPKIN_BOMB: + pWeaponInfo = GetTFWeaponInfo( TF_WEAPON_PIPEBOMBLAUNCHER ); + break; + case TF_WEAPON_FLAMETHROWER_ROCKET: + pWeaponInfo = GetTFWeaponInfo( TF_WEAPON_FLAMETHROWER ); + break; + default: + pWeaponInfo = GetTFWeaponInfo( iWeaponID ); + break; + } + + bool bIsPlayer = false; + if ( hEntity.Get() ) + { + C_BaseEntity *pEntity = C_BaseEntity::Instance( hEntity ); + if ( pEntity && pEntity->IsPlayer() ) + { + bIsPlayer = true; + } + } + + // Calculate the angles, given the normal. + bool bIsWater = ( UTIL_PointContents( vecOrigin ) & CONTENTS_WATER ); + bool bInAir = false; + QAngle angExplosion( 0.0f, 0.0f, 0.0f ); + + // Cannot use zeros here because we are sending the normal at a smaller bit size. + if ( fabs( vecNormal.x ) < 0.05f && fabs( vecNormal.y ) < 0.05f && fabs( vecNormal.z ) < 0.05f ) + { + bInAir = true; + angExplosion.Init(); + } + else + { + VectorAngles( vecNormal, angExplosion ); + bInAir = false; + } + + // Base explosion effect and sound. + const char *pszEffect = "ExplosionCore_wall"; + const char *pszSound = "BaseExplosionEffect.Sound"; + + // check for a custom particle effect + if ( iCustomParticleIndex != INVALID_STRING_INDEX ) + { + pszEffect = GetParticleSystemNameFromIndex( iCustomParticleIndex ); + } + + if ( pWeaponInfo ) + { + // Explosions. + if ( iCustomParticleIndex == INVALID_STRING_INDEX ) + { + if ( bIsWater ) + { + if ( Q_strlen( pWeaponInfo->m_szExplosionWaterEffect ) > 0 ) + { + pszEffect = pWeaponInfo->m_szExplosionWaterEffect; + } + } + else + { + if ( bIsPlayer || bInAir ) + { + if ( Q_strlen( pWeaponInfo->m_szExplosionPlayerEffect ) > 0 ) + { + pszEffect = pWeaponInfo->m_szExplosionPlayerEffect; + } + } + else + { + if ( Q_strlen( pWeaponInfo->m_szExplosionEffect ) > 0 ) + { + pszEffect = pWeaponInfo->m_szExplosionEffect; + } + } + } + } + + // Sound. + if ( Q_strlen( pWeaponInfo->m_szExplosionSound ) > 0 ) + { + // Check for a replacement sound in the itemdef first - defaults to SPECIAL1 + if ( nDefID >= 0 ) + { + C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); + if ( pLocalPlayer ) + { + CEconItemDefinition *pItemDef = ItemSystem()->GetStaticDataForItemByDefIndex( nDefID ); + if ( pItemDef ) + { + pszSound = (char *)pItemDef->GetWeaponReplacementSound( pLocalPlayer->GetTeamNumber(), (WeaponSound_t)nSound ); + if ( !pszSound || !pszSound[0] ) + { + pszSound = pWeaponInfo->m_szExplosionSound; + } + } + } + } + else + { + pszSound = pWeaponInfo->m_szExplosionSound; + } + } + } + + if ( iWeaponID == TF_WEAPON_PUMPKIN_BOMB ) + { + pszSound = "Halloween.PumpkinExplode"; + } + + CLocalPlayerFilter filter; + C_BaseEntity::EmitSound( filter, SOUND_FROM_WORLD, pszSound, &vecOrigin ); + + if ( GameRules() ) + { + pszEffect = GameRules()->TranslateEffectForVisionFilter( "particles", pszEffect ); + } + + DispatchParticleEffect( pszEffect, vecOrigin, angExplosion ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +class C_TETFExplosion : public C_BaseTempEntity +{ +public: + + DECLARE_CLASS( C_TETFExplosion, C_BaseTempEntity ); + DECLARE_CLIENTCLASS(); + + C_TETFExplosion( void ); + + virtual void PostDataUpdate( DataUpdateType_t updateType ); + +public: + + Vector m_vecOrigin; + Vector m_vecNormal; + int m_iWeaponID; + ClientEntityHandle_t m_hEntity; + int m_nDefID; + int m_nSound; + int m_iCustomParticleIndex; +}; + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +C_TETFExplosion::C_TETFExplosion( void ) +{ + m_vecOrigin.Init(); + m_vecNormal.Init(); + m_iWeaponID = TF_WEAPON_NONE; + m_hEntity = INVALID_EHANDLE_INDEX; + m_nDefID = -1; + m_nSound = SPECIAL1; + m_iCustomParticleIndex = INVALID_STRING_INDEX; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void C_TETFExplosion::PostDataUpdate( DataUpdateType_t updateType ) +{ + VPROF( "C_TETFExplosion::PostDataUpdate" ); + + TFExplosionCallback( m_vecOrigin, m_vecNormal, m_iWeaponID, m_hEntity, m_nDefID, m_nSound, m_iCustomParticleIndex ); +} + +static void RecvProxy_ExplosionEntIndex( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + int nEntIndex = pData->m_Value.m_Int; + // The 'new' encoding for INVALID_EHANDLE_INDEX is 2047, but the old encoding + // was -1. Old demos and replays will use the old encoding so we have to check + // for it. The field is now unsigned so -1 will not be created in new replays. + ((C_TETFExplosion*)pStruct)->m_hEntity = (nEntIndex == kInvalidEHandleExplosion || nEntIndex == -1) ? INVALID_EHANDLE_INDEX : ClientEntityList().EntIndexToHandle( nEntIndex ); +} + +IMPLEMENT_CLIENTCLASS_EVENT_DT( C_TETFExplosion, DT_TETFExplosion, CTETFExplosion ) + RecvPropFloat( RECVINFO( m_vecOrigin[0] ) ), + RecvPropFloat( RECVINFO( m_vecOrigin[1] ) ), + RecvPropFloat( RECVINFO( m_vecOrigin[2] ) ), + RecvPropVector( RECVINFO( m_vecNormal ) ), + RecvPropInt( RECVINFO( m_iWeaponID ) ), + RecvPropInt( "entindex", 0, SIZEOF_IGNORE, 0, RecvProxy_ExplosionEntIndex ), + RecvPropInt( RECVINFO( m_nDefID ) ), + RecvPropInt( RECVINFO( m_nSound ) ), + RecvPropInt( RECVINFO( m_iCustomParticleIndex ) ), +END_RECV_TABLE() + |