aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/shared/SpriteTrail.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/shared/SpriteTrail.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/shared/SpriteTrail.cpp')
-rw-r--r--mp/src/game/shared/SpriteTrail.cpp1324
1 files changed, 662 insertions, 662 deletions
diff --git a/mp/src/game/shared/SpriteTrail.cpp b/mp/src/game/shared/SpriteTrail.cpp
index 409a2770..217d64cd 100644
--- a/mp/src/game/shared/SpriteTrail.cpp
+++ b/mp/src/game/shared/SpriteTrail.cpp
@@ -1,662 +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( &currentPoint.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) : &currentPoint;
-
- 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
+//========= 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( &currentPoint.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) : &currentPoint;
+
+ 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