You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
662 lines
18 KiB
662 lines
18 KiB
//========= 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
|
|
|