//========= Copyright Valve Corporation, All rights reserved. ============// // // // //============================================================================= #include "cbase.h" #include "basetempentity.h" #include "tf_fx.h" #include "tf_shareddefs.h" #include "coordsize.h" #define NUM_BULLET_SEED_BITS 8 //----------------------------------------------------------------------------- // Purpose: Display a blood sprite //----------------------------------------------------------------------------- class CTEFireBullets : public CBaseTempEntity { public: DECLARE_CLASS( CTEFireBullets, CBaseTempEntity ); DECLARE_SERVERCLASS(); CTEFireBullets( const char *name ); virtual ~CTEFireBullets( void ); public: CNetworkVar( int, m_iPlayer ); CNetworkVector( m_vecOrigin ); CNetworkQAngle( m_vecAngles ); CNetworkVar( int, m_iWeaponID ); CNetworkVar( int, m_iMode ); CNetworkVar( int, m_iSeed ); CNetworkVar( float, m_flSpread ); CNetworkVar( bool, m_bCritical ); }; //----------------------------------------------------------------------------- // Purpose: // Input : *name - //----------------------------------------------------------------------------- CTEFireBullets::CTEFireBullets( const char *name ) : CBaseTempEntity( name ) { } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CTEFireBullets::~CTEFireBullets( void ) { } IMPLEMENT_SERVERCLASS_ST_NOBASE( CTEFireBullets, DT_TEFireBullets ) SendPropVector( SENDINFO(m_vecOrigin), -1, SPROP_COORD_MP_INTEGRAL ), SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 0 ), 7, 0 ), SendPropAngle( SENDINFO_VECTORELEM( m_vecAngles, 1 ), 7, 0 ), SendPropInt( SENDINFO( m_iWeaponID ), Q_log2(TF_WEAPON_COUNT)+1, SPROP_UNSIGNED ), SendPropInt( SENDINFO( m_iMode ), 1, SPROP_UNSIGNED ), SendPropInt( SENDINFO( m_iSeed ), NUM_BULLET_SEED_BITS, SPROP_UNSIGNED ), SendPropInt( SENDINFO( m_iPlayer ), 6, SPROP_UNSIGNED ), // max 64 players, see MAX_PLAYERS SendPropFloat( SENDINFO( m_flSpread ), 8, 0, 0.0f, 1.0f ), SendPropBool( SENDINFO( m_bCritical ) ), END_SEND_TABLE() // Singleton static CTEFireBullets g_TEFireBullets( "Fire Bullets" ); //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void TE_FireBullets( int iPlayerIndex, const Vector &vOrigin, const QAngle &vAngles, int iWeaponID, int iMode, int iSeed, float flSpread, bool bCritical ) { CPASFilter filter( vOrigin ); filter.UsePredictionRules(); g_TEFireBullets.m_iPlayer = iPlayerIndex-1; g_TEFireBullets.m_vecOrigin = vOrigin; g_TEFireBullets.m_vecAngles = vAngles; g_TEFireBullets.m_iSeed = iSeed; g_TEFireBullets.m_flSpread = flSpread; g_TEFireBullets.m_iMode = iMode; g_TEFireBullets.m_iWeaponID = iWeaponID; g_TEFireBullets.m_bCritical = bCritical; Assert( iSeed < (1 << NUM_BULLET_SEED_BITS) ); g_TEFireBullets.Create( filter, 0 ); } //============================================================================= // // Explosions. // class CTETFExplosion : public CBaseTempEntity { public: DECLARE_CLASS( CTETFExplosion, CBaseTempEntity ); DECLARE_SERVERCLASS(); CTETFExplosion( const char *name ); public: Vector m_vecOrigin; Vector m_vecNormal; int m_iWeaponID; int m_nEntIndex; int m_nDefID; int m_nSound; int m_iCustomParticleIndex; }; // Singleton to fire explosion objects static CTETFExplosion g_TETFExplosion( "TFExplosion" ); //----------------------------------------------------------------------------- // Purpose: // Input : *name - //----------------------------------------------------------------------------- CTETFExplosion::CTETFExplosion( const char *name ) : CBaseTempEntity( name ) { m_vecOrigin.Init(); m_vecNormal.Init(); m_iWeaponID = TF_WEAPON_NONE; m_nEntIndex = kInvalidEHandleExplosion; m_nDefID = -1; m_nSound = SPECIAL1; m_iCustomParticleIndex = INVALID_STRING_INDEX; } IMPLEMENT_SERVERCLASS_ST( CTETFExplosion, DT_TETFExplosion ) SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[0] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[1] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[2] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropVector( SENDINFO_NOCHECK( m_vecNormal ), 6, 0, -1.0f, 1.0f ), SendPropInt( SENDINFO_NOCHECK( m_iWeaponID ), Q_log2( TF_WEAPON_COUNT )+1, SPROP_UNSIGNED ), SendPropInt( SENDINFO_NAME( m_nEntIndex, entindex ), MAX_EDICT_BITS, SPROP_UNSIGNED ), SendPropInt( SENDINFO_NOCHECK( m_nDefID ), -1 ), SendPropInt( SENDINFO_NOCHECK( m_nSound ), -1 ), SendPropInt( SENDINFO_NOCHECK( m_iCustomParticleIndex ), -1 ), END_SEND_TABLE() void TE_TFExplosion( IRecipientFilter &filter, float flDelay, const Vector &vecOrigin, const Vector &vecNormal, int iWeaponID, int nEntIndex, int nDefID, int nSound, int iCustomParticleIndex ) { VectorCopy( vecOrigin, g_TETFExplosion.m_vecOrigin ); VectorCopy( vecNormal, g_TETFExplosion.m_vecNormal ); g_TETFExplosion.m_iWeaponID = iWeaponID; g_TETFExplosion.m_nEntIndex = nEntIndex; g_TETFExplosion.m_nDefID = nDefID; g_TETFExplosion.m_nSound = nSound; g_TETFExplosion.m_iCustomParticleIndex = iCustomParticleIndex; // Send it over the wire g_TETFExplosion.Create( filter, flDelay ); } void TE_TFExplosion( IRecipientFilter &filter, float flDelay, const Vector &vecOrigin, const Vector &vecNormal, int iWeaponID, int nEntIndex, int nDefID, int nSound ) { TE_TFExplosion( filter, flDelay, vecOrigin, vecNormal, iWeaponID, nEntIndex, nDefID, nSound, INVALID_STRING_INDEX ); } //============================================================================= // // TF ParticleEffect // class CTETFParticleEffect : public CBaseTempEntity { public: DECLARE_CLASS( CTETFParticleEffect, CBaseTempEntity ); DECLARE_SERVERCLASS(); CTETFParticleEffect( const char *name ); void Init( void ); public: Vector m_vecOrigin; Vector m_vecStart; QAngle m_vecAngles; int m_iParticleSystemIndex; int m_nEntIndex; int m_iAttachType; int m_iAttachmentPointIndex; bool m_bResetParticles; bool m_bCustomColors; te_tf_particle_effects_colors_t m_CustomColors; bool m_bControlPoint1; te_tf_particle_effects_control_point_t m_ControlPoint1; }; // Singleton to fire explosion objects static CTETFParticleEffect g_TETFParticleEffect( "TFParticleEffect" ); //----------------------------------------------------------------------------- // Purpose: // Input : *name - //----------------------------------------------------------------------------- CTETFParticleEffect::CTETFParticleEffect( const char *name ) : CBaseTempEntity( name ) { Init(); } void CTETFParticleEffect::Init( void ) { m_vecOrigin.Init(); m_vecStart.Init(); m_vecAngles.Init(); m_iParticleSystemIndex = 0; m_nEntIndex = kInvalidEHandleParticleEffect; m_iAttachType = PATTACH_ABSORIGIN; m_iAttachmentPointIndex = 0; m_bResetParticles = false; m_bCustomColors = false; m_CustomColors.m_vecColor1.Init(); m_CustomColors.m_vecColor2.Init(); m_bControlPoint1 = false; m_ControlPoint1.m_eParticleAttachment = PATTACH_ABSORIGIN; m_ControlPoint1.m_vecOffset.Init(); } IMPLEMENT_SERVERCLASS_ST( CTETFParticleEffect, DT_TETFParticleEffect ) SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[0] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[1] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropFloat( SENDINFO_NOCHECK( m_vecOrigin[2] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropFloat( SENDINFO_NOCHECK( m_vecStart[0] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropFloat( SENDINFO_NOCHECK( m_vecStart[1] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropFloat( SENDINFO_NOCHECK( m_vecStart[2] ), -1, SPROP_COORD_MP_INTEGRAL ), SendPropQAngles( SENDINFO_NOCHECK( m_vecAngles ), 7 ), SendPropInt( SENDINFO_NOCHECK( m_iParticleSystemIndex ), 16, SPROP_UNSIGNED ), // probably way too high SendPropInt( SENDINFO_NAME( m_nEntIndex, entindex ), MAX_EDICT_BITS, SPROP_UNSIGNED ), SendPropInt( SENDINFO_NOCHECK( m_iAttachType ), 5, SPROP_UNSIGNED ), SendPropInt( SENDINFO_NOCHECK( m_iAttachmentPointIndex ), -1 ), SendPropBool( SENDINFO_NOCHECK( m_bResetParticles ) ), SendPropBool( SENDINFO_NOCHECK( m_bCustomColors) ), SendPropVector( SENDINFO_NOCHECK( m_CustomColors.m_vecColor1 ), 8, 0, 0, 1 ), SendPropVector( SENDINFO_NOCHECK( m_CustomColors.m_vecColor2 ), 8, 0, 0, 1 ), SendPropBool( SENDINFO_NOCHECK( m_bControlPoint1) ), SendPropInt( SENDINFO_NOCHECK( m_ControlPoint1.m_eParticleAttachment ), 5, SPROP_UNSIGNED ), SendPropFloat( SENDINFO_NOCHECK( m_ControlPoint1.m_vecOffset[0] ), -1, SPROP_COORD ), SendPropFloat( SENDINFO_NOCHECK( m_ControlPoint1.m_vecOffset[1] ), -1, SPROP_COORD ), SendPropFloat( SENDINFO_NOCHECK( m_ControlPoint1.m_vecOffset[2] ), -1, SPROP_COORD ), END_SEND_TABLE() //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, ParticleAttachment_t iAttachType, CBaseEntity *pEntity, const char *pszAttachmentName, bool bResetAllParticlesOnEntity ) { int iAttachment = -1; if ( pEntity && pEntity->GetBaseAnimating() ) { // Find the attachment point index iAttachment = pEntity->GetBaseAnimating()->LookupAttachment( pszAttachmentName ); if ( iAttachment <= 0 ) { Warning("Model '%s' doesn't have attachment '%s' to attach particle system '%s' to.\n", STRING(pEntity->GetBaseAnimating()->GetModelName()), pszAttachmentName, pszParticleName ); return; } } TE_TFParticleEffect( filter, flDelay, pszParticleName, iAttachType, pEntity, iAttachment, bResetAllParticlesOnEntity ); } //----------------------------------------------------------------------------- // Purpose: Yet another overload, lets us supply vecStart //----------------------------------------------------------------------------- void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, Vector vecOrigin, Vector vecStart, QAngle vecAngles, CBaseEntity *pEntity ) { int iIndex = GetParticleSystemIndex( pszParticleName ); TE_TFParticleEffect( filter, flDelay, iIndex, vecOrigin, vecStart, vecAngles, pEntity ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, ParticleAttachment_t iAttachType, CBaseEntity *pEntity, int iAttachmentPoint, bool bResetAllParticlesOnEntity ) { g_TETFParticleEffect.Init(); g_TETFParticleEffect.m_iParticleSystemIndex = GetParticleSystemIndex( pszParticleName ); if ( pEntity ) { g_TETFParticleEffect.m_nEntIndex = pEntity->entindex(); } g_TETFParticleEffect.m_iAttachType = iAttachType; g_TETFParticleEffect.m_iAttachmentPointIndex = iAttachmentPoint; if ( bResetAllParticlesOnEntity ) { g_TETFParticleEffect.m_bResetParticles = true; } // Send it over the wire g_TETFParticleEffect.Create( filter, flDelay ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, const char *pszParticleName, Vector vecOrigin, QAngle vecAngles, CBaseEntity *pEntity /*= NULL*/, ParticleAttachment_t eAttachType /*= PATTACH_CUSTOMORIGIN*/ ) { TE_TFParticleEffectComplex( filter, flDelay, pszParticleName, vecOrigin, vecAngles, NULL, NULL, pEntity, eAttachType ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void TE_TFParticleEffectComplex ( IRecipientFilter &filter, float flDelay, const char *pszParticleName, Vector vecOrigin, QAngle vecAngles, te_tf_particle_effects_colors_t *pOptionalColors /*= NULL*/, te_tf_particle_effects_control_point_t *pOptionalControlPoint1 /*= NULL*/, CBaseEntity *pEntity /*= NULL*/, ParticleAttachment_t eAttachType /*= PATTACH_CUSTOMORIGIN*/, Vector vecStart /* = vec3_origin */ ) { g_TETFParticleEffect.Init(); g_TETFParticleEffect.m_iParticleSystemIndex = GetParticleSystemIndex( pszParticleName ); VectorCopy( vecOrigin, g_TETFParticleEffect.m_vecOrigin ); VectorCopy( vecAngles, g_TETFParticleEffect.m_vecAngles ); VectorCopy( vecStart, g_TETFParticleEffect.m_vecStart ); if ( pEntity ) { g_TETFParticleEffect.m_nEntIndex = pEntity->entindex(); g_TETFParticleEffect.m_iAttachType = eAttachType; } if ( pOptionalColors ) { g_TETFParticleEffect.m_bCustomColors = true; g_TETFParticleEffect.m_CustomColors.m_vecColor1 = pOptionalColors->m_vecColor1; g_TETFParticleEffect.m_CustomColors.m_vecColor2 = pOptionalColors->m_vecColor2; } if ( pOptionalControlPoint1 ) { g_TETFParticleEffect.m_bControlPoint1 = true; g_TETFParticleEffect.m_ControlPoint1.m_eParticleAttachment = pOptionalControlPoint1->m_eParticleAttachment; g_TETFParticleEffect.m_ControlPoint1.m_vecOffset = pOptionalControlPoint1->m_vecOffset; } // Send it over the wire g_TETFParticleEffect.Create( filter, flDelay ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void TE_TFParticleEffect( IRecipientFilter &filter, float flDelay, int iEffectIndex, Vector vecOrigin, Vector vecStart, QAngle vecAngles, CBaseEntity *pEntity ) { g_TETFParticleEffect.Init(); g_TETFParticleEffect.m_iParticleSystemIndex = iEffectIndex; VectorCopy( vecOrigin, g_TETFParticleEffect.m_vecOrigin ); VectorCopy( vecStart, g_TETFParticleEffect.m_vecStart ); VectorCopy( vecAngles, g_TETFParticleEffect.m_vecAngles ); if ( pEntity ) { g_TETFParticleEffect.m_nEntIndex = pEntity->entindex(); g_TETFParticleEffect.m_iAttachType = PATTACH_CUSTOMORIGIN; } // Send it over the wire g_TETFParticleEffect.Create( filter, flDelay ); }