diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/shared/SpriteTrail.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/shared/SpriteTrail.cpp')
| -rw-r--r-- | mp/src/game/shared/SpriteTrail.cpp | 662 |
1 files changed, 662 insertions, 0 deletions
diff --git a/mp/src/game/shared/SpriteTrail.cpp b/mp/src/game/shared/SpriteTrail.cpp new file mode 100644 index 00000000..409a2770 --- /dev/null +++ b/mp/src/game/shared/SpriteTrail.cpp @@ -0,0 +1,662 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+
+#include "cbase.h"
+#include "SpriteTrail.h"
+
+#ifdef CLIENT_DLL
+
+#include "clientsideeffects.h"
+#include "materialsystem/imaterialsystem.h"
+#include "materialsystem/imesh.h"
+#include "mathlib/vmatrix.h"
+#include "view.h"
+#include "beamdraw.h"
+#include "enginesprite.h"
+#include "tier0/vprof.h"
+
+extern CEngineSprite *Draw_SetSpriteTexture( const model_t *pSpriteModel, int frame, int rendermode );
+
+#endif // CLIENT_DLL
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+#define SCREEN_SPACE_TRAILS 0
+
+
+//-----------------------------------------------------------------------------
+// Save/Restore
+//-----------------------------------------------------------------------------
+#if defined( CLIENT_DLL )
+
+BEGIN_SIMPLE_DATADESC( TrailPoint_t )
+#if SCREEN_SPACE_TRAILS
+ DEFINE_FIELD( m_vecScreenPos, FIELD_VECTOR ),
+#else
+ DEFINE_FIELD( m_vecScreenPos, FIELD_POSITION_VECTOR ),
+#endif
+
+ DEFINE_FIELD( m_flDieTime, FIELD_TIME ),
+ DEFINE_FIELD( m_flTexCoord, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flWidthVariance,FIELD_FLOAT ),
+END_DATADESC()
+
+#endif
+
+BEGIN_DATADESC( CSpriteTrail )
+
+ DEFINE_KEYFIELD( m_flLifeTime, FIELD_FLOAT, "lifetime" ),
+ DEFINE_KEYFIELD( m_flStartWidth, FIELD_FLOAT, "startwidth" ),
+ DEFINE_KEYFIELD( m_flEndWidth, FIELD_FLOAT, "endwidth" ),
+ DEFINE_KEYFIELD( m_iszSpriteName, FIELD_STRING, "spritename" ),
+ DEFINE_KEYFIELD( m_bAnimate, FIELD_BOOLEAN, "animate" ),
+ DEFINE_FIELD( m_flStartWidthVariance, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flTextureRes, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flMinFadeLength, FIELD_FLOAT ),
+ DEFINE_FIELD( m_vecSkyboxOrigin, FIELD_POSITION_VECTOR ),
+ DEFINE_FIELD( m_flSkyboxScale, FIELD_FLOAT ),
+
+ // These are client-only
+#if defined( CLIENT_DLL )
+ DEFINE_EMBEDDED_AUTO_ARRAY( m_vecSteps ),
+ DEFINE_FIELD( m_nFirstStep, FIELD_INTEGER ),
+ DEFINE_FIELD( m_nStepCount, FIELD_INTEGER ),
+ DEFINE_FIELD( m_flUpdateTime, FIELD_TIME ),
+ DEFINE_FIELD( m_vecPrevSkyboxOrigin, FIELD_POSITION_VECTOR ),
+ DEFINE_FIELD( m_flPrevSkyboxScale, FIELD_FLOAT ),
+ DEFINE_FIELD( m_vecRenderMins, FIELD_VECTOR ),
+ DEFINE_FIELD( m_vecRenderMaxs, FIELD_VECTOR ),
+#endif
+
+END_DATADESC()
+
+LINK_ENTITY_TO_CLASS( env_spritetrail, CSpriteTrail );
+
+
+//-----------------------------------------------------------------------------
+// Networking
+//-----------------------------------------------------------------------------
+IMPLEMENT_NETWORKCLASS_ALIASED( SpriteTrail, DT_SpriteTrail );
+
+BEGIN_NETWORK_TABLE( CSpriteTrail, DT_SpriteTrail )
+#if !defined( CLIENT_DLL )
+ SendPropFloat( SENDINFO(m_flLifeTime), 0, SPROP_NOSCALE ),
+ SendPropFloat( SENDINFO(m_flStartWidth), 0, SPROP_NOSCALE ),
+ SendPropFloat( SENDINFO(m_flEndWidth), 0, SPROP_NOSCALE ),
+ SendPropFloat( SENDINFO(m_flStartWidthVariance), 0, SPROP_NOSCALE ),
+ SendPropFloat( SENDINFO(m_flTextureRes), 0, SPROP_NOSCALE ),
+ SendPropFloat( SENDINFO(m_flMinFadeLength), 0, SPROP_NOSCALE ),
+ SendPropVector( SENDINFO(m_vecSkyboxOrigin),0, SPROP_NOSCALE ),
+ SendPropFloat( SENDINFO(m_flSkyboxScale), 0, SPROP_NOSCALE ),
+#else
+ RecvPropFloat( RECVINFO(m_flLifeTime)),
+ RecvPropFloat( RECVINFO(m_flStartWidth)),
+ RecvPropFloat( RECVINFO(m_flEndWidth)),
+ RecvPropFloat( RECVINFO(m_flStartWidthVariance)),
+ RecvPropFloat( RECVINFO(m_flTextureRes)),
+ RecvPropFloat( RECVINFO(m_flMinFadeLength)),
+ RecvPropVector( RECVINFO(m_vecSkyboxOrigin)),
+ RecvPropFloat( RECVINFO(m_flSkyboxScale)),
+#endif
+END_NETWORK_TABLE()
+
+//-----------------------------------------------------------------------------
+// Prediction
+//-----------------------------------------------------------------------------
+BEGIN_PREDICTION_DATA( CSpriteTrail )
+END_PREDICTION_DATA()
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CSpriteTrail::CSpriteTrail( void )
+{
+#ifdef CLIENT_DLL
+ m_nFirstStep = 0;
+ m_nStepCount = 0;
+#endif
+
+ m_flStartWidthVariance = 0;
+ m_vecSkyboxOrigin.Init( 0, 0, 0 );
+ m_flSkyboxScale = 1.0f;
+ m_flEndWidth = -1.0f;
+ m_bDrawForMoveParent = true;
+}
+
+void CSpriteTrail::Spawn( void )
+{
+#ifdef CLIENT_DLL
+ BaseClass::Spawn();
+#else
+
+ if ( GetModelName() != NULL_STRING )
+ {
+ BaseClass::Spawn();
+ return;
+ }
+
+ SetModelName( m_iszSpriteName );
+ BaseClass::Spawn();
+
+ SetSolid( SOLID_NONE );
+ SetMoveType( MOVETYPE_NOCLIP );
+
+ SetCollisionBounds( vec3_origin, vec3_origin );
+ TurnOn();
+
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Sets parameters of the sprite trail
+//-----------------------------------------------------------------------------
+void CSpriteTrail::Precache( void )
+{
+ BaseClass::Precache();
+
+ if ( m_iszSpriteName != NULL_STRING )
+ {
+ PrecacheModel( STRING(m_iszSpriteName) );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Sets parameters of the sprite trail
+//-----------------------------------------------------------------------------
+void CSpriteTrail::SetLifeTime( float time )
+{
+ m_flLifeTime = time;
+}
+
+void CSpriteTrail::SetStartWidth( float flStartWidth )
+{
+ m_flStartWidth = flStartWidth;
+ m_flStartWidth /= m_flSkyboxScale;
+}
+
+void CSpriteTrail::SetStartWidthVariance( float flStartWidthVariance )
+{
+ m_flStartWidthVariance = flStartWidthVariance;
+ m_flStartWidthVariance /= m_flSkyboxScale;
+}
+
+void CSpriteTrail::SetEndWidth( float flEndWidth )
+{
+ m_flEndWidth = flEndWidth;
+ m_flEndWidth /= m_flSkyboxScale;
+}
+
+void CSpriteTrail::SetTextureResolution( float flTexelsPerInch )
+{
+ m_flTextureRes = flTexelsPerInch;
+ m_flTextureRes *= m_flSkyboxScale;
+}
+
+void CSpriteTrail::SetMinFadeLength( float flMinFadeLength )
+{
+ m_flMinFadeLength = flMinFadeLength;
+ m_flMinFadeLength /= m_flSkyboxScale;
+}
+
+void CSpriteTrail::SetSkybox( const Vector &vecSkyboxOrigin, float flSkyboxScale )
+{
+ m_flTextureRes /= m_flSkyboxScale;
+ m_flMinFadeLength *= m_flSkyboxScale;
+ m_flStartWidth *= m_flSkyboxScale;
+ m_flEndWidth *= m_flSkyboxScale;
+ m_flStartWidthVariance *= m_flSkyboxScale;
+
+ m_vecSkyboxOrigin = vecSkyboxOrigin;
+ m_flSkyboxScale = flSkyboxScale;
+
+ m_flTextureRes *= m_flSkyboxScale;
+ m_flMinFadeLength /= m_flSkyboxScale;
+ m_flStartWidth /= m_flSkyboxScale;
+ m_flEndWidth /= m_flSkyboxScale;
+ m_flStartWidthVariance /= m_flSkyboxScale;
+
+ if ( IsInSkybox() )
+ {
+ AddEFlags( EFL_IN_SKYBOX );
+ }
+ else
+ {
+ RemoveEFlags( EFL_IN_SKYBOX );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Is the trail in the skybox?
+//-----------------------------------------------------------------------------
+bool CSpriteTrail::IsInSkybox() const
+{
+ return (m_flSkyboxScale != 1.0f) || (m_vecSkyboxOrigin != vec3_origin);
+}
+
+
+
+#ifdef CLIENT_DLL
+
+
+//-----------------------------------------------------------------------------
+// On data update
+//-----------------------------------------------------------------------------
+void CSpriteTrail::OnPreDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnPreDataChanged( updateType );
+ m_vecPrevSkyboxOrigin = m_vecSkyboxOrigin;
+ m_flPrevSkyboxScale = m_flSkyboxScale;
+}
+
+void CSpriteTrail::OnDataChanged( DataUpdateType_t updateType )
+{
+ BaseClass::OnDataChanged( updateType );
+ if ( updateType == DATA_UPDATE_CREATED )
+ {
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+ else
+ {
+ if ((m_flPrevSkyboxScale != m_flSkyboxScale) || (m_vecPrevSkyboxOrigin != m_vecSkyboxOrigin))
+ {
+ ConvertSkybox();
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Compute position + bounding box
+//-----------------------------------------------------------------------------
+void CSpriteTrail::ClientThink()
+{
+ // Update the trail + bounding box
+ UpdateTrail();
+ UpdateBoundingBox();
+}
+
+
+//-----------------------------------------------------------------------------
+// Render bounds
+//-----------------------------------------------------------------------------
+void CSpriteTrail::GetRenderBounds( Vector& mins, Vector& maxs )
+{
+ mins = m_vecRenderMins;
+ maxs = m_vecRenderMaxs;
+}
+
+
+//-----------------------------------------------------------------------------
+// Converts the trail when it changes skyboxes
+//-----------------------------------------------------------------------------
+void CSpriteTrail::ConvertSkybox()
+{
+ for ( int i = 0; i < m_nStepCount; ++i )
+ {
+ // This makes it so that we're always drawing to the current location
+ TrailPoint_t *pPoint = GetTrailPoint(i);
+
+ VectorSubtract( pPoint->m_vecScreenPos, m_vecPrevSkyboxOrigin, pPoint->m_vecScreenPos );
+ pPoint->m_vecScreenPos *= m_flPrevSkyboxScale / m_flSkyboxScale;
+ VectorSubtract( pPoint->m_vecScreenPos, m_vecSkyboxOrigin, pPoint->m_vecScreenPos );
+ pPoint->m_flWidthVariance *= m_flPrevSkyboxScale / m_flSkyboxScale;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Gets at the nth item in the list
+//-----------------------------------------------------------------------------
+TrailPoint_t *CSpriteTrail::GetTrailPoint( int n )
+{
+ Assert( n < MAX_SPRITE_TRAIL_POINTS );
+ COMPILE_TIME_ASSERT( (MAX_SPRITE_TRAIL_POINTS & (MAX_SPRITE_TRAIL_POINTS-1)) == 0 );
+ int nIndex = (n + m_nFirstStep) & MAX_SPRITE_TRAIL_MASK;
+ return &m_vecSteps[nIndex];
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CSpriteTrail::ComputeScreenPosition( Vector *pScreenPos )
+{
+#if SCREEN_SPACE_TRAILS
+ VMatrix viewMatrix;
+ materials->GetMatrix( MATERIAL_VIEW, &viewMatrix );
+ *pScreenPos = viewMatrix * GetRenderOrigin();
+#else
+ *pScreenPos = GetRenderOrigin();
+#endif
+}
+
+
+//-----------------------------------------------------------------------------
+// Compute position + bounding box
+//-----------------------------------------------------------------------------
+void CSpriteTrail::UpdateBoundingBox( void )
+{
+ Vector vecRenderOrigin = GetRenderOrigin();
+ m_vecRenderMins = vecRenderOrigin;
+ m_vecRenderMaxs = vecRenderOrigin;
+
+ float flMaxWidth = m_flStartWidth;
+ if (( m_flEndWidth >= 0.0f ) && ( m_flEndWidth > m_flStartWidth ))
+ {
+ flMaxWidth = m_flEndWidth;
+ }
+
+ Vector mins, maxs;
+ for ( int i = 0; i < m_nStepCount; ++i )
+ {
+ TrailPoint_t *pPoint = GetTrailPoint(i);
+
+ float flActualWidth = (flMaxWidth + pPoint->m_flWidthVariance) * 0.5f;
+ Vector size( flActualWidth, flActualWidth, flActualWidth );
+ VectorSubtract( pPoint->m_vecScreenPos, size, mins );
+ VectorAdd( pPoint->m_vecScreenPos, size, maxs );
+
+ VectorMin( m_vecRenderMins, mins, m_vecRenderMins );
+ VectorMax( m_vecRenderMaxs, maxs, m_vecRenderMaxs );
+ }
+
+ m_vecRenderMins -= vecRenderOrigin;
+ m_vecRenderMaxs -= vecRenderOrigin;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CSpriteTrail::UpdateTrail( void )
+{
+ // Can't update too quickly
+ if ( m_flUpdateTime > gpGlobals->curtime )
+ return;
+
+ Vector screenPos;
+ ComputeScreenPosition( &screenPos );
+ TrailPoint_t *pLast = m_nStepCount ? GetTrailPoint( m_nStepCount-1 ) : NULL;
+ if ( ( pLast == NULL ) || ( pLast->m_vecScreenPos.DistToSqr( screenPos ) > 4.0f ) )
+ {
+ // If we're over our limit, steal the last point and put it up front
+ if ( m_nStepCount >= MAX_SPRITE_TRAIL_POINTS )
+ {
+ --m_nStepCount;
+ ++m_nFirstStep;
+ }
+
+ // Save off its screen position, not its world position
+ TrailPoint_t *pNewPoint = GetTrailPoint( m_nStepCount );
+ pNewPoint->m_vecScreenPos = screenPos;
+ pNewPoint->m_flDieTime = gpGlobals->curtime + m_flLifeTime;
+ pNewPoint->m_flWidthVariance = random->RandomFloat( -m_flStartWidthVariance, m_flStartWidthVariance );
+ if (pLast)
+ {
+ pNewPoint->m_flTexCoord = pLast->m_flTexCoord + pLast->m_vecScreenPos.DistTo( screenPos ) * m_flTextureRes;
+ }
+ else
+ {
+ pNewPoint->m_flTexCoord = 0.0f;
+ }
+
+ ++m_nStepCount;
+ }
+
+ // Don't update again for a bit
+ m_flUpdateTime = gpGlobals->curtime + ( m_flLifeTime / (float) MAX_SPRITE_TRAIL_POINTS );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CSpriteTrail::DrawModel( int flags )
+{
+ VPROF_BUDGET( "CSpriteTrail::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
+
+ // Must have at least one point
+ if ( m_nStepCount < 1 )
+ return 1;
+
+ //See if we should draw
+ if ( !IsVisible() || ( m_bReadyToDraw == false ) )
+ return 0;
+
+ CEngineSprite *pSprite = Draw_SetSpriteTexture( GetModel(), m_flFrame, GetRenderMode() );
+ if ( pSprite == NULL )
+ return 0;
+
+ // Specify all the segments.
+ CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
+ CBeamSegDraw segDraw;
+ segDraw.Start( pRenderContext, m_nStepCount + 1, pSprite->GetMaterial( GetRenderMode() ) );
+
+ // Setup the first point, always emanating from the attachment point
+ TrailPoint_t *pLast = GetTrailPoint( m_nStepCount-1 );
+ TrailPoint_t currentPoint;
+ currentPoint.m_flDieTime = gpGlobals->curtime + m_flLifeTime;
+ ComputeScreenPosition( ¤tPoint.m_vecScreenPos );
+ currentPoint.m_flTexCoord = pLast->m_flTexCoord + currentPoint.m_vecScreenPos.DistTo(pLast->m_vecScreenPos) * m_flTextureRes;
+ currentPoint.m_flWidthVariance = 0.0f;
+
+#if SCREEN_SPACE_TRAILS
+ VMatrix viewMatrix;
+ materials->GetMatrix( MATERIAL_VIEW, &viewMatrix );
+ viewMatrix = viewMatrix.InverseTR();
+#endif
+
+ TrailPoint_t *pPrevPoint = NULL;
+ float flTailAlphaDist = m_flMinFadeLength;
+ for ( int i = 0; i <= m_nStepCount; ++i )
+ {
+ // This makes it so that we're always drawing to the current location
+ TrailPoint_t *pPoint = (i != m_nStepCount) ? GetTrailPoint(i) : ¤tPoint;
+
+ float flLifePerc = (pPoint->m_flDieTime - gpGlobals->curtime) / m_flLifeTime;
+ flLifePerc = clamp( flLifePerc, 0.0f, 1.0f );
+
+ BeamSeg_t curSeg;
+ curSeg.m_vColor.x = (float) m_clrRender->r / 255.0f;
+ curSeg.m_vColor.y = (float) m_clrRender->g / 255.0f;
+ curSeg.m_vColor.z = (float) m_clrRender->b / 255.0f;
+
+ float flAlphaFade = flLifePerc;
+ if ( flTailAlphaDist > 0.0f )
+ {
+ if ( pPrevPoint )
+ {
+ float flDist = pPoint->m_vecScreenPos.DistTo( pPrevPoint->m_vecScreenPos );
+ flTailAlphaDist -= flDist;
+ }
+
+ if ( flTailAlphaDist > 0.0f )
+ {
+ float flTailFade = Lerp( (m_flMinFadeLength - flTailAlphaDist) / m_flMinFadeLength, 0.0f, 1.0f );
+ if ( flTailFade < flAlphaFade )
+ {
+ flAlphaFade = flTailFade;
+ }
+ }
+ }
+ curSeg.m_flAlpha = ( (float) GetRenderBrightness() / 255.0f ) * flAlphaFade;
+
+#if SCREEN_SPACE_TRAILS
+ curSeg.m_vPos = viewMatrix * pPoint->m_vecScreenPos;
+#else
+ curSeg.m_vPos = pPoint->m_vecScreenPos;
+#endif
+
+ if ( m_flEndWidth >= 0.0f )
+ {
+ curSeg.m_flWidth = Lerp( flLifePerc, m_flEndWidth.Get(), m_flStartWidth.Get() );
+ }
+ else
+ {
+ curSeg.m_flWidth = m_flStartWidth.Get();
+ }
+ curSeg.m_flWidth += pPoint->m_flWidthVariance;
+ if ( curSeg.m_flWidth < 0.0f )
+ {
+ curSeg.m_flWidth = 0.0f;
+ }
+
+ curSeg.m_flTexCoord = pPoint->m_flTexCoord;
+
+ segDraw.NextSeg( &curSeg );
+
+ // See if we're done with this bad boy
+ if ( pPoint->m_flDieTime <= gpGlobals->curtime )
+ {
+ // Push this back onto the top for use
+ ++m_nFirstStep;
+ --i;
+ --m_nStepCount;
+ }
+
+ pPrevPoint = pPoint;
+ }
+
+ segDraw.End();
+
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Vector const&
+//-----------------------------------------------------------------------------
+const Vector &CSpriteTrail::GetRenderOrigin( void )
+{
+ static Vector vOrigin;
+ vOrigin = GetAbsOrigin();
+
+ if ( m_hAttachedToEntity )
+ {
+ C_BaseEntity *ent = m_hAttachedToEntity->GetBaseEntity();
+ if ( ent )
+ {
+ QAngle dummyAngles;
+ ent->GetAttachment( m_nAttachment, vOrigin, dummyAngles );
+ }
+ }
+
+ return vOrigin;
+}
+
+const QAngle &CSpriteTrail::GetRenderAngles( void )
+{
+ return vec3_angle;
+}
+
+#endif //CLIENT_DLL
+
+#if !defined( CLIENT_DLL )
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pSpriteName -
+// &origin -
+// animate -
+// Output : CSpriteTrail
+//-----------------------------------------------------------------------------
+CSpriteTrail *CSpriteTrail::SpriteTrailCreate( const char *pSpriteName, const Vector &origin, bool animate )
+{
+ CSpriteTrail *pSprite = CREATE_ENTITY( CSpriteTrail, "env_spritetrail" );
+
+ pSprite->SpriteInit( pSpriteName, origin );
+ pSprite->SetSolid( SOLID_NONE );
+ pSprite->SetMoveType( MOVETYPE_NOCLIP );
+
+ UTIL_SetSize( pSprite, vec3_origin, vec3_origin );
+
+ if ( animate )
+ {
+ pSprite->TurnOn();
+ }
+
+ return pSprite;
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+
+int CSpriteTrail::ShouldTransmit( const CCheckTransmitInfo *pInfo )
+{
+ CBaseEntity *pRecipientEntity = CBaseEntity::Instance( pInfo->m_pClientEnt );
+
+ Assert( pRecipientEntity->IsPlayer() );
+
+ CBasePlayer *pRecipientPlayer = static_cast<CBasePlayer*>( pRecipientEntity );
+
+ if ( !m_bDrawForMoveParent )
+ {
+ if ( GetMoveParent() && !GetMoveParent()->IsPlayer() )
+ {
+ if ( GetMoveParent()->GetMoveParent() == pRecipientPlayer )
+ {
+ return FL_EDICT_DONTSEND;
+ }
+ }
+ else if ( GetMoveParent() == pRecipientPlayer )
+ {
+ return FL_EDICT_DONTSEND;
+ }
+
+ }
+
+ return BaseClass::ShouldTransmit( pInfo );
+}
+
+#endif //CLIENT_DLL == false
+
+#if defined( CLIENT_DLL )
+// It's okay to draw attached entities with these sprites.
+const char* g_spriteWhiteList[] =
+{
+ "effects/beam001_white.vmt",
+ "effects/beam001_red.vmt",
+ "effects/beam001_blu.vmt",
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: TF prevents drawing of any entity attached to players that aren't items in the inventory of the player.
+// This is to prevent servers creating fake cosmetic items and attaching them to players.
+//-----------------------------------------------------------------------------
+bool CSpriteTrail::ValidateEntityAttachedToPlayer( bool &bShouldRetry )
+{
+ bShouldRetry = false;
+ return true;
+
+ /*
+#if defined( TF_CLIENT_DLL )
+
+ const char *pszModelName = modelinfo->GetModelName( GetModel() );
+ if ( pszModelName && pszModelName[0] )
+ {
+ // We attach sprites directly to players in some cases, such as phase trails on an evading scout
+ for ( int i=0; i<ARRAYSIZE( g_spriteWhiteList ); ++i )
+ {
+ if ( FStrEq( pszModelName, g_spriteWhiteList[i] ) )
+ return true;
+ }
+ }
+
+ return false;
+
+#else
+ return false;
+#endif
+ */
+}
+
+#endif
|