diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/shared/Sprite.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/shared/Sprite.cpp')
| -rw-r--r-- | mp/src/game/shared/Sprite.cpp | 1736 |
1 files changed, 868 insertions, 868 deletions
diff --git a/mp/src/game/shared/Sprite.cpp b/mp/src/game/shared/Sprite.cpp index 8b8ce38e..2393f148 100644 --- a/mp/src/game/shared/Sprite.cpp +++ b/mp/src/game/shared/Sprite.cpp @@ -1,868 +1,868 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Implements visual effects entities: sprites, beams, bubbles, etc.
-//
-// $NoKeywords: $
-//=============================================================================//
-#include "cbase.h"
-#include "Sprite.h"
-#include "model_types.h"
-#include "engine/ivmodelinfo.h"
-#include "tier0/vprof.h"
-#include "engine/ivdebugoverlay.h"
-
-#if defined( CLIENT_DLL )
- #include "enginesprite.h"
- #include "iclientmode.h"
- #include "c_baseviewmodel.h"
-# ifdef PORTAL
- #include "c_prop_portal.h"
-# endif //ifdef PORTAL
-#else
- #include "baseviewmodel.h"
-#endif
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-const float MAX_SPRITE_SCALE = 64.0f;
-const float MAX_GLOW_PROXY_SIZE = 64.0f;
-
-LINK_ENTITY_TO_CLASS( env_sprite, CSprite );
-LINK_ENTITY_TO_CLASS( env_sprite_oriented, CSpriteOriented );
-#if !defined( CLIENT_DLL )
-LINK_ENTITY_TO_CLASS( env_glow, CSprite ); // For backwards compatibility, remove when no longer needed.
-#endif
-
-#if !defined( CLIENT_DLL )
-BEGIN_DATADESC( CSprite )
-
- DEFINE_FIELD( m_flLastTime, FIELD_TIME ),
- DEFINE_FIELD( m_flMaxFrame, FIELD_FLOAT ),
- DEFINE_FIELD( m_hAttachedToEntity, FIELD_EHANDLE ),
- DEFINE_FIELD( m_nAttachment, FIELD_INTEGER ),
- DEFINE_FIELD( m_flDieTime, FIELD_TIME ),
-
- DEFINE_FIELD( m_nBrightness, FIELD_INTEGER ),
- DEFINE_FIELD( m_flBrightnessTime, FIELD_FLOAT ),
-
- DEFINE_KEYFIELD( m_flSpriteScale, FIELD_FLOAT, "scale" ),
- DEFINE_KEYFIELD( m_flSpriteFramerate, FIELD_FLOAT, "framerate" ),
- DEFINE_KEYFIELD( m_flFrame, FIELD_FLOAT, "frame" ),
-#ifdef PORTAL
- DEFINE_FIELD( m_bDrawInMainRender, FIELD_BOOLEAN ),
- DEFINE_FIELD( m_bDrawInPortalRender, FIELD_BOOLEAN ),
-#endif
- DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ),
-
- DEFINE_KEYFIELD( m_flGlowProxySize, FIELD_FLOAT, "GlowProxySize" ),
-
- DEFINE_FIELD( m_flScaleTime, FIELD_FLOAT ),
- DEFINE_FIELD( m_flStartScale, FIELD_FLOAT ),
- DEFINE_FIELD( m_flDestScale, FIELD_FLOAT ),
- DEFINE_FIELD( m_flScaleTimeStart, FIELD_TIME ),
- DEFINE_FIELD( m_nStartBrightness, FIELD_INTEGER ),
- DEFINE_FIELD( m_nDestBrightness, FIELD_INTEGER ),
- DEFINE_FIELD( m_flBrightnessTimeStart, FIELD_TIME ),
- DEFINE_FIELD( m_bWorldSpaceScale, FIELD_BOOLEAN ),
-
- // Function Pointers
- DEFINE_FUNCTION( AnimateThink ),
- DEFINE_FUNCTION( ExpandThink ),
- DEFINE_FUNCTION( AnimateUntilDead ),
- DEFINE_FUNCTION( BeginFadeOutThink ),
-
- // Inputs
- DEFINE_INPUT( m_flSpriteScale, FIELD_FLOAT, "SetScale" ),
- DEFINE_INPUTFUNC( FIELD_VOID, "HideSprite", InputHideSprite ),
- DEFINE_INPUTFUNC( FIELD_VOID, "ShowSprite", InputShowSprite ),
- DEFINE_INPUTFUNC( FIELD_VOID, "ToggleSprite", InputToggleSprite ),
- DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorRedValue", InputColorRedValue ),
- DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorGreenValue", InputColorGreenValue ),
- DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorBlueValue", InputColorBlueValue ),
-
-END_DATADESC()
-
-#else
-
-BEGIN_PREDICTION_DATA( CSprite )
-
- // Networked
- DEFINE_PRED_FIELD( m_hAttachedToEntity, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_nAttachment, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_flScaleTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_flSpriteScale, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_flSpriteFramerate, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_flFrame, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
-#ifdef PORTAL
- DEFINE_PRED_FIELD( m_bDrawInMainRender, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_bDrawInPortalRender, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
-#endif
- DEFINE_PRED_FIELD( m_flBrightnessTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ),
- DEFINE_PRED_FIELD( m_nBrightness, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ),
-
- DEFINE_FIELD( m_flLastTime, FIELD_FLOAT ),
- DEFINE_FIELD( m_flMaxFrame, FIELD_FLOAT ),
- DEFINE_FIELD( m_flDieTime, FIELD_FLOAT ),
-
-// DEFINE_FIELD( m_flHDRColorScale, FIELD_FLOAT ),
-// DEFINE_FIELD( m_flStartScale, FIELD_FLOAT ), //Starting scale
-// DEFINE_FIELD( m_flDestScale, FIELD_FLOAT ), //Destination scale
-// DEFINE_FIELD( m_flScaleTimeStart, FIELD_FLOAT ), //Real time for start of scale
-// DEFINE_FIELD( m_nStartBrightness, FIELD_INTEGER ), //Starting brightness
-// DEFINE_FIELD( m_nDestBrightness, FIELD_INTEGER ), //Destination brightness
-// DEFINE_FIELD( m_flBrightnessTimeStart, FIELD_FLOAT ), //Real time for brightness
-
-END_PREDICTION_DATA()
-
-#endif
-
-IMPLEMENT_NETWORKCLASS_ALIASED( Sprite, DT_Sprite );
-
-#if defined( CLIENT_DLL )
-
-static void RecvProxy_SpriteScale( const CRecvProxyData *pData, void *pStruct, void *pOut )
-{
- ((CSprite*)pStruct)->SetSpriteScale( pData->m_Value.m_Float );
-}
-
-#endif
-
-BEGIN_NETWORK_TABLE( CSprite, DT_Sprite )
-#if !defined( CLIENT_DLL )
- SendPropEHandle( SENDINFO(m_hAttachedToEntity )),
- SendPropInt( SENDINFO(m_nAttachment ), 8 ),
- SendPropFloat( SENDINFO(m_flScaleTime ), 0, SPROP_NOSCALE ),
-
-#ifdef HL2_DLL
- SendPropFloat( SENDINFO(m_flSpriteScale ), 0, SPROP_NOSCALE),
-#else
- SendPropFloat( SENDINFO(m_flSpriteScale ), 8, SPROP_ROUNDUP, 0.0f, MAX_SPRITE_SCALE),
-#endif
- SendPropFloat( SENDINFO(m_flGlowProxySize ), 6, SPROP_ROUNDUP, 0.0f, MAX_GLOW_PROXY_SIZE),
-
- SendPropFloat( SENDINFO(m_flHDRColorScale ), 0, SPROP_NOSCALE, 0.0f, 100.0f),
-
- SendPropFloat( SENDINFO(m_flSpriteFramerate ), 8, SPROP_ROUNDUP, 0, 60.0f),
- SendPropFloat( SENDINFO(m_flFrame), 20, SPROP_ROUNDDOWN, 0.0f, 256.0f),
-#ifdef PORTAL
- SendPropBool( SENDINFO(m_bDrawInMainRender) ),
- SendPropBool( SENDINFO(m_bDrawInPortalRender) ),
-#endif //#ifdef PORTAL
- SendPropFloat( SENDINFO(m_flBrightnessTime ), 0, SPROP_NOSCALE ),
- SendPropInt( SENDINFO(m_nBrightness), 8, SPROP_UNSIGNED ),
- SendPropBool( SENDINFO(m_bWorldSpaceScale) ),
-#else
- RecvPropEHandle(RECVINFO(m_hAttachedToEntity)),
- RecvPropInt(RECVINFO(m_nAttachment)),
- RecvPropFloat(RECVINFO(m_flScaleTime)),
- RecvPropFloat(RECVINFO(m_flSpriteScale), 0, RecvProxy_SpriteScale),
- RecvPropFloat(RECVINFO(m_flSpriteFramerate)),
- RecvPropFloat(RECVINFO(m_flGlowProxySize)),
-
- RecvPropFloat( RECVINFO(m_flHDRColorScale )),
-
- RecvPropFloat(RECVINFO(m_flFrame)),
-#ifdef PORTAL
- RecvPropBool( RECVINFO(m_bDrawInMainRender) ),
- RecvPropBool( RECVINFO(m_bDrawInPortalRender) ),
-#endif //#ifdef PORTAL
- RecvPropFloat(RECVINFO(m_flBrightnessTime)),
- RecvPropInt(RECVINFO(m_nBrightness)),
- RecvPropBool( RECVINFO(m_bWorldSpaceScale) ),
-#endif
-END_NETWORK_TABLE()
-
-
-CSprite::CSprite()
-{
- m_flGlowProxySize = 2.0f;
- m_flHDRColorScale = 1.0f;
-
-#ifdef PORTAL
- m_bDrawInMainRender = true;
- m_bDrawInPortalRender = true;
-#endif
-}
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::Spawn( void )
-{
- SetSolid( SOLID_NONE );
- SetMoveType( MOVETYPE_NONE );
- m_flFrame = 0;
-
- Precache();
- SetModel( STRING( GetModelName() ) );
- CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE );
-
- m_flMaxFrame = (float)modelinfo->GetModelFrameCount( GetModel() ) - 1;
- AddEffects( EF_NOSHADOW | EF_NORECEIVESHADOW );
-
-#if defined( CLIENT_DLL )
- SetNextClientThink( CLIENT_THINK_ALWAYS );
-#endif
-
-#if !defined( CLIENT_DLL )
- if ( GetEntityName() != NULL_STRING && !(m_spawnflags & SF_SPRITE_STARTON) )
- {
- TurnOff();
- }
- else
-#endif
- {
- TurnOn();
- }
-
- // Worldcraft only sets y rotation, copy to Z
- if ( GetLocalAngles().y != 0 && GetLocalAngles().z == 0 )
- {
- QAngle angles = GetLocalAngles();
-
- angles.z = angles.y;
- angles.y = 0;
-
- SetLocalAngles( angles );
- }
-
- // Clamp our scale if necessary
- float scale = m_flSpriteScale;
-
- if ( scale < 0 || scale > MAX_SPRITE_SCALE )
- {
-#if !defined( CLIENT_DLL )
- DevMsg( "LEVEL DESIGN ERROR: Sprite %s with bad scale %f [0..%f]\n", GetDebugName(), m_flSpriteScale.Get(), MAX_SPRITE_SCALE );
-#endif
- scale = clamp( (float) m_flSpriteScale, 0.f, MAX_SPRITE_SCALE );
- }
-
- //Set our state
- SetBrightness( m_clrRender->a );
- SetScale( scale );
-
-#if defined( CLIENT_DLL )
- m_flStartScale = m_flDestScale = m_flSpriteScale;
- m_nStartBrightness = m_nDestBrightness = m_nBrightness;
-#endif
-
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Initialize absmin & absmax to the appropriate box
-//-----------------------------------------------------------------------------
-void CSprite::EnableWorldSpaceScale( bool bEnable )
-{
- m_bWorldSpaceScale = bEnable;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Initialize absmin & absmax to the appropriate box
-//-----------------------------------------------------------------------------
-void CSprite::ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs )
-{
- float flScale = m_flSpriteScale * 0.5f;
-
- if ( m_bWorldSpaceScale == false )
- {
- // Find the height and width of the source of the sprite
- float width = modelinfo->GetModelSpriteWidth( GetModel() );
- float height = modelinfo->GetModelSpriteHeight( GetModel() );
- flScale *= MAX( width, height );
- }
-
- pVecWorldMins->Init( -flScale, -flScale, -flScale );
- pVecWorldMaxs->Init( flScale, flScale, flScale );
- *pVecWorldMins += GetAbsOrigin();
- *pVecWorldMaxs += GetAbsOrigin();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *szModelName -
-//-----------------------------------------------------------------------------
-void CSprite::SetModel( const char *szModelName )
-{
- int index = modelinfo->GetModelIndex( szModelName );
- const model_t *model = modelinfo->GetModel( index );
- if ( model && modelinfo->GetModelType( model ) != mod_sprite )
- {
- Msg( "Setting CSprite to non-sprite model %s\n", szModelName?szModelName:"NULL" );
- }
-
-#if !defined( CLIENT_DLL )
- UTIL_SetModel( this, szModelName );
-#else
- BaseClass::SetModel( szModelName );
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::Precache( void )
-{
- if ( GetModelName() != NULL_STRING )
- {
- PrecacheModel( STRING( GetModelName() ) );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pSpriteName -
-// &origin -
-//-----------------------------------------------------------------------------
-void CSprite::SpriteInit( const char *pSpriteName, const Vector &origin )
-{
- SetModelName( MAKE_STRING(pSpriteName) );
- SetLocalOrigin( origin );
- Spawn();
-}
-
-#if !defined( CLIENT_DLL )
-
-int CSprite::UpdateTransmitState( void )
-{
- if ( GetMoveParent() )
- {
- // we must call ShouldTransmit() if we have a move parent
- return SetTransmitState( FL_EDICT_FULLCHECK );
- }
- else
- {
- return SetTransmitState( FL_EDICT_ALWAYS );
- }
-}
-
-int CSprite::ShouldTransmit( const CCheckTransmitInfo *pInfo )
-{
- // Certain entities like sprites and ropes are strewn throughout the level and they rarely change.
- // For these entities, it's more efficient to transmit them once and then always leave them on
- // the client. Otherwise, the server will have to send big bursts of data with the entity states
- // as they come in and out of the PVS.
-
- if ( GetMoveParent() )
- {
- CBaseViewModel *pViewModel = dynamic_cast<CBaseViewModel *>( GetMoveParent() );
-
- if ( pViewModel )
- {
- return pViewModel->ShouldTransmit( pInfo );
- }
- }
-
- return FL_EDICT_ALWAYS;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Fixup parent after restore
-//-----------------------------------------------------------------------------
-void CSprite::OnRestore()
-{
- BaseClass::OnRestore();
-
- // Reset attachment after save/restore
- if ( GetFollowedEntity() )
- {
- SetAttachment( GetFollowedEntity(), m_nAttachment );
- }
- else
- {
- // Clear attachment
- m_hAttachedToEntity = NULL;
- m_nAttachment = 0;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pSpriteName -
-// &origin -
-// animate -
-// Output : CSprite
-//-----------------------------------------------------------------------------
-CSprite *CSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, bool animate )
-{
- CSprite *pSprite = CREATE_ENTITY( CSprite, "env_sprite" );
- pSprite->SpriteInit( pSpriteName, origin );
- pSprite->SetSolid( SOLID_NONE );
- UTIL_SetSize( pSprite, vec3_origin, vec3_origin );
- pSprite->SetMoveType( MOVETYPE_NONE );
- if ( animate )
- pSprite->TurnOn();
-
- return pSprite;
-}
-#endif
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pSpriteName -
-// &origin -
-// animate -
-// Output : CSprite
-//-----------------------------------------------------------------------------
-CSprite *CSprite::SpriteCreatePredictable( const char *module, int line, const char *pSpriteName, const Vector &origin, bool animate )
-{
- CSprite *pSprite = ( CSprite * )CBaseEntity::CreatePredictedEntityByName( "env_sprite", module, line );
- if ( pSprite )
- {
- pSprite->SpriteInit( pSpriteName, origin );
- pSprite->SetSolid( SOLID_NONE );
- pSprite->SetSize( vec3_origin, vec3_origin );
- pSprite->SetMoveType( MOVETYPE_NONE );
- if ( animate )
- pSprite->TurnOn();
- }
-
- return pSprite;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::AnimateThink( void )
-{
- Animate( m_flSpriteFramerate * (gpGlobals->curtime - m_flLastTime) );
-
- SetNextThink( gpGlobals->curtime );
- m_flLastTime = gpGlobals->curtime;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::AnimateUntilDead( void )
-{
- if ( gpGlobals->curtime > m_flDieTime )
- {
- Remove( );
- }
- else
- {
- AnimateThink();
- SetNextThink( gpGlobals->curtime );
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : scaleSpeed -
-// fadeSpeed -
-//-----------------------------------------------------------------------------
-void CSprite::Expand( float scaleSpeed, float fadeSpeed )
-{
- m_flSpeed = scaleSpeed;
- m_iHealth = fadeSpeed;
- SetThink( &CSprite::ExpandThink );
-
- SetNextThink( gpGlobals->curtime );
- m_flLastTime = gpGlobals->curtime;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::ExpandThink( void )
-{
- float frametime = gpGlobals->curtime - m_flLastTime;
- SetSpriteScale( m_flSpriteScale + m_flSpeed * frametime );
-
- int sub = (int)(m_iHealth * frametime);
- if ( sub > m_clrRender->a )
- {
- SetRenderColorA( 0 );
- Remove( );
- }
- else
- {
- SetRenderColorA( m_clrRender->a - sub );
- SetNextThink( gpGlobals->curtime );
- m_flLastTime = gpGlobals->curtime;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : frames -
-//-----------------------------------------------------------------------------
-void CSprite::Animate( float frames )
-{
- m_flFrame += frames;
- if ( m_flFrame > m_flMaxFrame )
- {
-#if !defined( CLIENT_DLL )
- if ( m_spawnflags & SF_SPRITE_ONCE )
- {
- TurnOff();
- }
- else
-#endif
- {
- if ( m_flMaxFrame > 0 )
- m_flFrame = fmod( m_flFrame, m_flMaxFrame );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::SetBrightness( int brightness, float time )
-{
- m_nBrightness = brightness; //Take our current position as our starting position
- m_flBrightnessTime = time;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::SetSpriteScale( float scale )
-{
- if ( scale != m_flSpriteScale )
- {
- m_flSpriteScale = scale; //Take our current position as our new starting position
- // The surrounding box is based on sprite scale... it changes, box is dirty
- CollisionProp()->MarkSurroundingBoundsDirty();
- }
-}
-
-void CSprite::SetScale( float scale, float time )
-{
- m_flScaleTime = time;
- SetSpriteScale( scale );
- // The surrounding box is based on sprite scale... it changes, box is dirty
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::TurnOff( void )
-{
- AddEffects( EF_NODRAW );
- SetNextThink( TICK_NEVER_THINK );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::TurnOn( void )
-{
- RemoveEffects( EF_NODRAW );
- if ( (m_flSpriteFramerate && m_flMaxFrame > 1.0)
-#if !defined( CLIENT_DLL )
- || (m_spawnflags & SF_SPRITE_ONCE)
-#endif
- )
- {
- SetThink( &CSprite::AnimateThink );
- SetNextThink( gpGlobals->curtime );
- m_flLastTime = gpGlobals->curtime;
- }
- m_flFrame = 0;
-}
-
-#if !defined( CLIENT_DLL )
-// DVS TODO: Obsolete Use handler
-void CSprite::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
-{
- int on = !IsEffectActive( EF_NODRAW );
- if ( ShouldToggle( useType, on ) )
- {
- if ( on )
- {
- TurnOff();
- }
- else
- {
- TurnOn();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Input handler that hides the sprite.
-//-----------------------------------------------------------------------------
-void CSprite::InputHideSprite( inputdata_t &inputdata )
-{
- TurnOff();
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose: Input handler that hides the sprite.
-//-----------------------------------------------------------------------------
-void CSprite::InputShowSprite( inputdata_t &inputdata )
-{
- TurnOn();
-}
-
-void CSprite::InputColorRedValue( inputdata_t &inputdata )
-{
- int nNewColor = clamp( FastFloatToSmallInt( inputdata.value.Float() ), 0, 255 );
- SetColor( nNewColor, m_clrRender->g, m_clrRender->b );
-}
-
-void CSprite::InputColorGreenValue( inputdata_t &inputdata )
-{
- int nNewColor = clamp( FastFloatToSmallInt( inputdata.value.Float() ), 0, 255 );
- SetColor( m_clrRender->r, nNewColor, m_clrRender->b );
-}
-
-void CSprite::InputColorBlueValue( inputdata_t &inputdata )
-{
- int nNewColor = clamp( FastFloatToSmallInt( inputdata.value.Float() ), 0, 255 );
- SetColor( m_clrRender->r, m_clrRender->g, nNewColor );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Input handler that toggles the sprite between hidden and shown.
-//-----------------------------------------------------------------------------
-void CSprite::InputToggleSprite( inputdata_t &inputdata )
-{
- if ( !IsEffectActive( EF_NODRAW ) )
- {
- TurnOff();
- }
- else
- {
- TurnOn();
- }
-}
-#endif
-
-#if defined( CLIENT_DLL )
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : float
-//-----------------------------------------------------------------------------
-float CSprite::GetRenderScale( void )
-{
- //See if we're done scaling
- if ( ( m_flScaleTime == 0 ) || ( (m_flScaleTimeStart+m_flScaleTime) < gpGlobals->curtime ) )
- return m_flSpriteScale;
-
- //Get our percentage
- float timeDelta = ( gpGlobals->curtime - m_flScaleTimeStart ) / m_flScaleTime;
-
- //Return the result
- return ( m_flStartScale + ( ( m_flDestScale - m_flStartScale ) * timeDelta ) );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Get the rendered extents of the sprite
-//-----------------------------------------------------------------------------
-void CSprite::GetRenderBounds( Vector &vecMins, Vector &vecMaxs )
-{
- float flScale = GetRenderScale() * 0.5f;
-
- // If our scale is normalized we need to convert that to actual world units
- if ( m_bWorldSpaceScale == false )
- {
- CEngineSprite *psprite = (CEngineSprite *) modelinfo->GetModelExtraData( GetModel() );
- if ( psprite )
- {
- float flSize = MAX( psprite->GetWidth(), psprite->GetHeight() );
- flScale *= flSize;
- }
- }
-
- vecMins.Init( -flScale, -flScale, -flScale );
- vecMaxs.Init( flScale, flScale, flScale );
-
-#if 0
- // Visualize the bounds
- debugoverlay->AddBoxOverlay( GetRenderOrigin(), vecMins, vecMaxs, GetRenderAngles(), 255, 255, 255, 0, 0.01f );
-#endif
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-int CSprite::GetRenderBrightness( void )
-{
- //See if we're done scaling
- if ( ( m_flBrightnessTime == 0 ) || ( (m_flBrightnessTimeStart+m_flBrightnessTime) < gpGlobals->curtime ) )
- {
- return m_nBrightness;
- }
-
- //Get our percentage
- float timeDelta = ( gpGlobals->curtime - m_flBrightnessTimeStart ) / m_flBrightnessTime;
-
- float brightness = ( (float) m_nStartBrightness + ( (float) ( m_nDestBrightness - m_nStartBrightness ) * timeDelta ) );
-
- //Return the result
- return (int) brightness;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CSprite::OnDataChanged( DataUpdateType_t updateType )
-{
- BaseClass::OnDataChanged( updateType );
-
- // Only think when sapping
- SetNextClientThink( CLIENT_THINK_ALWAYS );
- if ( updateType == DATA_UPDATE_CREATED )
- {
- m_flStartScale = m_flDestScale = m_flSpriteScale;
- m_nStartBrightness = m_nDestBrightness = m_nBrightness;
- }
-
- UpdateVisibility();
-}
-
-void CSprite::ClientThink( void )
-{
- BaseClass::ClientThink();
-
- // Module render colors over time
- if ( m_flSpriteScale != m_flDestScale )
- {
- m_flStartScale = m_flDestScale;
- m_flDestScale = m_flSpriteScale;
- m_flScaleTimeStart = gpGlobals->curtime;
- }
-
- if ( m_nBrightness != m_nDestBrightness )
- {
- m_nStartBrightness = m_nDestBrightness;
- m_nDestBrightness = m_nBrightness;
- m_flBrightnessTimeStart = gpGlobals->curtime;
- }
-}
-
-extern bool g_bRenderingScreenshot;
-extern ConVar r_drawviewmodel;
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : flags -
-// Output : int
-//-----------------------------------------------------------------------------
-int CSprite::DrawModel( int flags )
-{
- VPROF_BUDGET( "CSprite::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING );
- //See if we should draw
- if ( !IsVisible() || ( m_bReadyToDraw == false ) )
- return 0;
-
-#ifdef PORTAL
- if ( ( !g_pPortalRender->IsRenderingPortal() && !m_bDrawInMainRender ) ||
- ( g_pPortalRender->IsRenderingPortal() && !m_bDrawInPortalRender ) )
- {
- return 0;
- }
-#endif //#ifdef PORTAL
-
- // Tracker 16432: If rendering a savegame screenshot then don't draw sprites
- // who have viewmodels as their moveparent
- if ( g_bRenderingScreenshot || !r_drawviewmodel.GetBool() )
- {
- C_BaseViewModel *vm = dynamic_cast< C_BaseViewModel * >( GetMoveParent() );
- if ( vm )
- {
- return 0;
- }
- }
-
- //Must be a sprite
- if ( modelinfo->GetModelType( GetModel() ) != mod_sprite )
- {
- Assert( 0 );
- return 0;
- }
-
- float renderscale = GetRenderScale();
- if ( m_bWorldSpaceScale )
- {
- CEngineSprite *psprite = ( CEngineSprite * )modelinfo->GetModelExtraData( GetModel() );
- float flMinSize = MIN( psprite->GetWidth(), psprite->GetHeight() );
- renderscale /= flMinSize;
- }
-
- //Draw it
- int drawn = DrawSprite(
- this,
- GetModel(),
- GetAbsOrigin(),
- GetAbsAngles(),
- m_flFrame, // sprite frame to render
- m_hAttachedToEntity, // attach to
- m_nAttachment, // attachment point
- GetRenderMode(), // rendermode
- m_nRenderFX,
- GetRenderBrightness(), // alpha
- m_clrRender->r,
- m_clrRender->g,
- m_clrRender->b,
- renderscale, // sprite scale
- GetHDRColorScale() // HDR Color Scale
- );
-
- return drawn;
-}
-
-
-const Vector& CSprite::GetRenderOrigin()
-{
- 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;
-}
-
-#endif
-
-//-----------------------------------------------------------------------------
-// Purpose: oriented sprites
-// CSprites swap the roll and yaw angle inputs, and rotate the yaw 180 degrees
-//-----------------------------------------------------------------------------
-
-#if !defined( CLIENT_DLL )
-IMPLEMENT_SERVERCLASS_ST( CSpriteOriented, DT_SpriteOriented )
-END_SEND_TABLE()
-#else
-#undef CSpriteOriented
-IMPLEMENT_CLIENTCLASS_DT(C_SpriteOriented, DT_SpriteOriented, CSpriteOriented)
-#define CSpriteOriented C_SpriteOriented
-END_RECV_TABLE()
-#endif
-
-#if !defined( CLIENT_DLL )
-
-void CSpriteOriented::Spawn( void )
-{
- // save a copy of the angles, CSprite swaps the yaw and roll
- QAngle angles = GetAbsAngles();
- BaseClass::Spawn();
- // ORIENTED sprites "forward" vector points in the players "view" direction, not the direction "out" from the sprite (gah)
- angles.y = anglemod( angles.y + 180 );
- SetAbsAngles( angles );
-}
-
-#else
-
-bool CSpriteOriented::IsTransparent( void )
-{
- return true;
-}
-
-#endif
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Implements visual effects entities: sprites, beams, bubbles, etc. +// +// $NoKeywords: $ +//=============================================================================// +#include "cbase.h" +#include "Sprite.h" +#include "model_types.h" +#include "engine/ivmodelinfo.h" +#include "tier0/vprof.h" +#include "engine/ivdebugoverlay.h" + +#if defined( CLIENT_DLL ) + #include "enginesprite.h" + #include "iclientmode.h" + #include "c_baseviewmodel.h" +# ifdef PORTAL + #include "c_prop_portal.h" +# endif //ifdef PORTAL +#else + #include "baseviewmodel.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +const float MAX_SPRITE_SCALE = 64.0f; +const float MAX_GLOW_PROXY_SIZE = 64.0f; + +LINK_ENTITY_TO_CLASS( env_sprite, CSprite ); +LINK_ENTITY_TO_CLASS( env_sprite_oriented, CSpriteOriented ); +#if !defined( CLIENT_DLL ) +LINK_ENTITY_TO_CLASS( env_glow, CSprite ); // For backwards compatibility, remove when no longer needed. +#endif + +#if !defined( CLIENT_DLL ) +BEGIN_DATADESC( CSprite ) + + DEFINE_FIELD( m_flLastTime, FIELD_TIME ), + DEFINE_FIELD( m_flMaxFrame, FIELD_FLOAT ), + DEFINE_FIELD( m_hAttachedToEntity, FIELD_EHANDLE ), + DEFINE_FIELD( m_nAttachment, FIELD_INTEGER ), + DEFINE_FIELD( m_flDieTime, FIELD_TIME ), + + DEFINE_FIELD( m_nBrightness, FIELD_INTEGER ), + DEFINE_FIELD( m_flBrightnessTime, FIELD_FLOAT ), + + DEFINE_KEYFIELD( m_flSpriteScale, FIELD_FLOAT, "scale" ), + DEFINE_KEYFIELD( m_flSpriteFramerate, FIELD_FLOAT, "framerate" ), + DEFINE_KEYFIELD( m_flFrame, FIELD_FLOAT, "frame" ), +#ifdef PORTAL + DEFINE_FIELD( m_bDrawInMainRender, FIELD_BOOLEAN ), + DEFINE_FIELD( m_bDrawInPortalRender, FIELD_BOOLEAN ), +#endif + DEFINE_KEYFIELD( m_flHDRColorScale, FIELD_FLOAT, "HDRColorScale" ), + + DEFINE_KEYFIELD( m_flGlowProxySize, FIELD_FLOAT, "GlowProxySize" ), + + DEFINE_FIELD( m_flScaleTime, FIELD_FLOAT ), + DEFINE_FIELD( m_flStartScale, FIELD_FLOAT ), + DEFINE_FIELD( m_flDestScale, FIELD_FLOAT ), + DEFINE_FIELD( m_flScaleTimeStart, FIELD_TIME ), + DEFINE_FIELD( m_nStartBrightness, FIELD_INTEGER ), + DEFINE_FIELD( m_nDestBrightness, FIELD_INTEGER ), + DEFINE_FIELD( m_flBrightnessTimeStart, FIELD_TIME ), + DEFINE_FIELD( m_bWorldSpaceScale, FIELD_BOOLEAN ), + + // Function Pointers + DEFINE_FUNCTION( AnimateThink ), + DEFINE_FUNCTION( ExpandThink ), + DEFINE_FUNCTION( AnimateUntilDead ), + DEFINE_FUNCTION( BeginFadeOutThink ), + + // Inputs + DEFINE_INPUT( m_flSpriteScale, FIELD_FLOAT, "SetScale" ), + DEFINE_INPUTFUNC( FIELD_VOID, "HideSprite", InputHideSprite ), + DEFINE_INPUTFUNC( FIELD_VOID, "ShowSprite", InputShowSprite ), + DEFINE_INPUTFUNC( FIELD_VOID, "ToggleSprite", InputToggleSprite ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorRedValue", InputColorRedValue ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorGreenValue", InputColorGreenValue ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "ColorBlueValue", InputColorBlueValue ), + +END_DATADESC() + +#else + +BEGIN_PREDICTION_DATA( CSprite ) + + // Networked + DEFINE_PRED_FIELD( m_hAttachedToEntity, FIELD_EHANDLE, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_nAttachment, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_flScaleTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_flSpriteScale, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_flSpriteFramerate, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_flFrame, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), +#ifdef PORTAL + DEFINE_PRED_FIELD( m_bDrawInMainRender, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_bDrawInPortalRender, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), +#endif + DEFINE_PRED_FIELD( m_flBrightnessTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE ), + DEFINE_PRED_FIELD( m_nBrightness, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), + + DEFINE_FIELD( m_flLastTime, FIELD_FLOAT ), + DEFINE_FIELD( m_flMaxFrame, FIELD_FLOAT ), + DEFINE_FIELD( m_flDieTime, FIELD_FLOAT ), + +// DEFINE_FIELD( m_flHDRColorScale, FIELD_FLOAT ), +// DEFINE_FIELD( m_flStartScale, FIELD_FLOAT ), //Starting scale +// DEFINE_FIELD( m_flDestScale, FIELD_FLOAT ), //Destination scale +// DEFINE_FIELD( m_flScaleTimeStart, FIELD_FLOAT ), //Real time for start of scale +// DEFINE_FIELD( m_nStartBrightness, FIELD_INTEGER ), //Starting brightness +// DEFINE_FIELD( m_nDestBrightness, FIELD_INTEGER ), //Destination brightness +// DEFINE_FIELD( m_flBrightnessTimeStart, FIELD_FLOAT ), //Real time for brightness + +END_PREDICTION_DATA() + +#endif + +IMPLEMENT_NETWORKCLASS_ALIASED( Sprite, DT_Sprite ); + +#if defined( CLIENT_DLL ) + +static void RecvProxy_SpriteScale( const CRecvProxyData *pData, void *pStruct, void *pOut ) +{ + ((CSprite*)pStruct)->SetSpriteScale( pData->m_Value.m_Float ); +} + +#endif + +BEGIN_NETWORK_TABLE( CSprite, DT_Sprite ) +#if !defined( CLIENT_DLL ) + SendPropEHandle( SENDINFO(m_hAttachedToEntity )), + SendPropInt( SENDINFO(m_nAttachment ), 8 ), + SendPropFloat( SENDINFO(m_flScaleTime ), 0, SPROP_NOSCALE ), + +#ifdef HL2_DLL + SendPropFloat( SENDINFO(m_flSpriteScale ), 0, SPROP_NOSCALE), +#else + SendPropFloat( SENDINFO(m_flSpriteScale ), 8, SPROP_ROUNDUP, 0.0f, MAX_SPRITE_SCALE), +#endif + SendPropFloat( SENDINFO(m_flGlowProxySize ), 6, SPROP_ROUNDUP, 0.0f, MAX_GLOW_PROXY_SIZE), + + SendPropFloat( SENDINFO(m_flHDRColorScale ), 0, SPROP_NOSCALE, 0.0f, 100.0f), + + SendPropFloat( SENDINFO(m_flSpriteFramerate ), 8, SPROP_ROUNDUP, 0, 60.0f), + SendPropFloat( SENDINFO(m_flFrame), 20, SPROP_ROUNDDOWN, 0.0f, 256.0f), +#ifdef PORTAL + SendPropBool( SENDINFO(m_bDrawInMainRender) ), + SendPropBool( SENDINFO(m_bDrawInPortalRender) ), +#endif //#ifdef PORTAL + SendPropFloat( SENDINFO(m_flBrightnessTime ), 0, SPROP_NOSCALE ), + SendPropInt( SENDINFO(m_nBrightness), 8, SPROP_UNSIGNED ), + SendPropBool( SENDINFO(m_bWorldSpaceScale) ), +#else + RecvPropEHandle(RECVINFO(m_hAttachedToEntity)), + RecvPropInt(RECVINFO(m_nAttachment)), + RecvPropFloat(RECVINFO(m_flScaleTime)), + RecvPropFloat(RECVINFO(m_flSpriteScale), 0, RecvProxy_SpriteScale), + RecvPropFloat(RECVINFO(m_flSpriteFramerate)), + RecvPropFloat(RECVINFO(m_flGlowProxySize)), + + RecvPropFloat( RECVINFO(m_flHDRColorScale )), + + RecvPropFloat(RECVINFO(m_flFrame)), +#ifdef PORTAL + RecvPropBool( RECVINFO(m_bDrawInMainRender) ), + RecvPropBool( RECVINFO(m_bDrawInPortalRender) ), +#endif //#ifdef PORTAL + RecvPropFloat(RECVINFO(m_flBrightnessTime)), + RecvPropInt(RECVINFO(m_nBrightness)), + RecvPropBool( RECVINFO(m_bWorldSpaceScale) ), +#endif +END_NETWORK_TABLE() + + +CSprite::CSprite() +{ + m_flGlowProxySize = 2.0f; + m_flHDRColorScale = 1.0f; + +#ifdef PORTAL + m_bDrawInMainRender = true; + m_bDrawInPortalRender = true; +#endif +} +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::Spawn( void ) +{ + SetSolid( SOLID_NONE ); + SetMoveType( MOVETYPE_NONE ); + m_flFrame = 0; + + Precache(); + SetModel( STRING( GetModelName() ) ); + CollisionProp()->SetSurroundingBoundsType( USE_GAME_CODE ); + + m_flMaxFrame = (float)modelinfo->GetModelFrameCount( GetModel() ) - 1; + AddEffects( EF_NOSHADOW | EF_NORECEIVESHADOW ); + +#if defined( CLIENT_DLL ) + SetNextClientThink( CLIENT_THINK_ALWAYS ); +#endif + +#if !defined( CLIENT_DLL ) + if ( GetEntityName() != NULL_STRING && !(m_spawnflags & SF_SPRITE_STARTON) ) + { + TurnOff(); + } + else +#endif + { + TurnOn(); + } + + // Worldcraft only sets y rotation, copy to Z + if ( GetLocalAngles().y != 0 && GetLocalAngles().z == 0 ) + { + QAngle angles = GetLocalAngles(); + + angles.z = angles.y; + angles.y = 0; + + SetLocalAngles( angles ); + } + + // Clamp our scale if necessary + float scale = m_flSpriteScale; + + if ( scale < 0 || scale > MAX_SPRITE_SCALE ) + { +#if !defined( CLIENT_DLL ) + DevMsg( "LEVEL DESIGN ERROR: Sprite %s with bad scale %f [0..%f]\n", GetDebugName(), m_flSpriteScale.Get(), MAX_SPRITE_SCALE ); +#endif + scale = clamp( (float) m_flSpriteScale, 0.f, MAX_SPRITE_SCALE ); + } + + //Set our state + SetBrightness( m_clrRender->a ); + SetScale( scale ); + +#if defined( CLIENT_DLL ) + m_flStartScale = m_flDestScale = m_flSpriteScale; + m_nStartBrightness = m_nDestBrightness = m_nBrightness; +#endif + +} + + +//----------------------------------------------------------------------------- +// Purpose: Initialize absmin & absmax to the appropriate box +//----------------------------------------------------------------------------- +void CSprite::EnableWorldSpaceScale( bool bEnable ) +{ + m_bWorldSpaceScale = bEnable; +} + +//----------------------------------------------------------------------------- +// Purpose: Initialize absmin & absmax to the appropriate box +//----------------------------------------------------------------------------- +void CSprite::ComputeWorldSpaceSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) +{ + float flScale = m_flSpriteScale * 0.5f; + + if ( m_bWorldSpaceScale == false ) + { + // Find the height and width of the source of the sprite + float width = modelinfo->GetModelSpriteWidth( GetModel() ); + float height = modelinfo->GetModelSpriteHeight( GetModel() ); + flScale *= MAX( width, height ); + } + + pVecWorldMins->Init( -flScale, -flScale, -flScale ); + pVecWorldMaxs->Init( flScale, flScale, flScale ); + *pVecWorldMins += GetAbsOrigin(); + *pVecWorldMaxs += GetAbsOrigin(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *szModelName - +//----------------------------------------------------------------------------- +void CSprite::SetModel( const char *szModelName ) +{ + int index = modelinfo->GetModelIndex( szModelName ); + const model_t *model = modelinfo->GetModel( index ); + if ( model && modelinfo->GetModelType( model ) != mod_sprite ) + { + Msg( "Setting CSprite to non-sprite model %s\n", szModelName?szModelName:"NULL" ); + } + +#if !defined( CLIENT_DLL ) + UTIL_SetModel( this, szModelName ); +#else + BaseClass::SetModel( szModelName ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::Precache( void ) +{ + if ( GetModelName() != NULL_STRING ) + { + PrecacheModel( STRING( GetModelName() ) ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pSpriteName - +// &origin - +//----------------------------------------------------------------------------- +void CSprite::SpriteInit( const char *pSpriteName, const Vector &origin ) +{ + SetModelName( MAKE_STRING(pSpriteName) ); + SetLocalOrigin( origin ); + Spawn(); +} + +#if !defined( CLIENT_DLL ) + +int CSprite::UpdateTransmitState( void ) +{ + if ( GetMoveParent() ) + { + // we must call ShouldTransmit() if we have a move parent + return SetTransmitState( FL_EDICT_FULLCHECK ); + } + else + { + return SetTransmitState( FL_EDICT_ALWAYS ); + } +} + +int CSprite::ShouldTransmit( const CCheckTransmitInfo *pInfo ) +{ + // Certain entities like sprites and ropes are strewn throughout the level and they rarely change. + // For these entities, it's more efficient to transmit them once and then always leave them on + // the client. Otherwise, the server will have to send big bursts of data with the entity states + // as they come in and out of the PVS. + + if ( GetMoveParent() ) + { + CBaseViewModel *pViewModel = dynamic_cast<CBaseViewModel *>( GetMoveParent() ); + + if ( pViewModel ) + { + return pViewModel->ShouldTransmit( pInfo ); + } + } + + return FL_EDICT_ALWAYS; +} + +//----------------------------------------------------------------------------- +// Purpose: Fixup parent after restore +//----------------------------------------------------------------------------- +void CSprite::OnRestore() +{ + BaseClass::OnRestore(); + + // Reset attachment after save/restore + if ( GetFollowedEntity() ) + { + SetAttachment( GetFollowedEntity(), m_nAttachment ); + } + else + { + // Clear attachment + m_hAttachedToEntity = NULL; + m_nAttachment = 0; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pSpriteName - +// &origin - +// animate - +// Output : CSprite +//----------------------------------------------------------------------------- +CSprite *CSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, bool animate ) +{ + CSprite *pSprite = CREATE_ENTITY( CSprite, "env_sprite" ); + pSprite->SpriteInit( pSpriteName, origin ); + pSprite->SetSolid( SOLID_NONE ); + UTIL_SetSize( pSprite, vec3_origin, vec3_origin ); + pSprite->SetMoveType( MOVETYPE_NONE ); + if ( animate ) + pSprite->TurnOn(); + + return pSprite; +} +#endif + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pSpriteName - +// &origin - +// animate - +// Output : CSprite +//----------------------------------------------------------------------------- +CSprite *CSprite::SpriteCreatePredictable( const char *module, int line, const char *pSpriteName, const Vector &origin, bool animate ) +{ + CSprite *pSprite = ( CSprite * )CBaseEntity::CreatePredictedEntityByName( "env_sprite", module, line ); + if ( pSprite ) + { + pSprite->SpriteInit( pSpriteName, origin ); + pSprite->SetSolid( SOLID_NONE ); + pSprite->SetSize( vec3_origin, vec3_origin ); + pSprite->SetMoveType( MOVETYPE_NONE ); + if ( animate ) + pSprite->TurnOn(); + } + + return pSprite; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::AnimateThink( void ) +{ + Animate( m_flSpriteFramerate * (gpGlobals->curtime - m_flLastTime) ); + + SetNextThink( gpGlobals->curtime ); + m_flLastTime = gpGlobals->curtime; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::AnimateUntilDead( void ) +{ + if ( gpGlobals->curtime > m_flDieTime ) + { + Remove( ); + } + else + { + AnimateThink(); + SetNextThink( gpGlobals->curtime ); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : scaleSpeed - +// fadeSpeed - +//----------------------------------------------------------------------------- +void CSprite::Expand( float scaleSpeed, float fadeSpeed ) +{ + m_flSpeed = scaleSpeed; + m_iHealth = fadeSpeed; + SetThink( &CSprite::ExpandThink ); + + SetNextThink( gpGlobals->curtime ); + m_flLastTime = gpGlobals->curtime; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::ExpandThink( void ) +{ + float frametime = gpGlobals->curtime - m_flLastTime; + SetSpriteScale( m_flSpriteScale + m_flSpeed * frametime ); + + int sub = (int)(m_iHealth * frametime); + if ( sub > m_clrRender->a ) + { + SetRenderColorA( 0 ); + Remove( ); + } + else + { + SetRenderColorA( m_clrRender->a - sub ); + SetNextThink( gpGlobals->curtime ); + m_flLastTime = gpGlobals->curtime; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : frames - +//----------------------------------------------------------------------------- +void CSprite::Animate( float frames ) +{ + m_flFrame += frames; + if ( m_flFrame > m_flMaxFrame ) + { +#if !defined( CLIENT_DLL ) + if ( m_spawnflags & SF_SPRITE_ONCE ) + { + TurnOff(); + } + else +#endif + { + if ( m_flMaxFrame > 0 ) + m_flFrame = fmod( m_flFrame, m_flMaxFrame ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::SetBrightness( int brightness, float time ) +{ + m_nBrightness = brightness; //Take our current position as our starting position + m_flBrightnessTime = time; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::SetSpriteScale( float scale ) +{ + if ( scale != m_flSpriteScale ) + { + m_flSpriteScale = scale; //Take our current position as our new starting position + // The surrounding box is based on sprite scale... it changes, box is dirty + CollisionProp()->MarkSurroundingBoundsDirty(); + } +} + +void CSprite::SetScale( float scale, float time ) +{ + m_flScaleTime = time; + SetSpriteScale( scale ); + // The surrounding box is based on sprite scale... it changes, box is dirty +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::TurnOff( void ) +{ + AddEffects( EF_NODRAW ); + SetNextThink( TICK_NEVER_THINK ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::TurnOn( void ) +{ + RemoveEffects( EF_NODRAW ); + if ( (m_flSpriteFramerate && m_flMaxFrame > 1.0) +#if !defined( CLIENT_DLL ) + || (m_spawnflags & SF_SPRITE_ONCE) +#endif + ) + { + SetThink( &CSprite::AnimateThink ); + SetNextThink( gpGlobals->curtime ); + m_flLastTime = gpGlobals->curtime; + } + m_flFrame = 0; +} + +#if !defined( CLIENT_DLL ) +// DVS TODO: Obsolete Use handler +void CSprite::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) +{ + int on = !IsEffectActive( EF_NODRAW ); + if ( ShouldToggle( useType, on ) ) + { + if ( on ) + { + TurnOff(); + } + else + { + TurnOn(); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that hides the sprite. +//----------------------------------------------------------------------------- +void CSprite::InputHideSprite( inputdata_t &inputdata ) +{ + TurnOff(); +} + + +//----------------------------------------------------------------------------- +// Purpose: Input handler that hides the sprite. +//----------------------------------------------------------------------------- +void CSprite::InputShowSprite( inputdata_t &inputdata ) +{ + TurnOn(); +} + +void CSprite::InputColorRedValue( inputdata_t &inputdata ) +{ + int nNewColor = clamp( FastFloatToSmallInt( inputdata.value.Float() ), 0, 255 ); + SetColor( nNewColor, m_clrRender->g, m_clrRender->b ); +} + +void CSprite::InputColorGreenValue( inputdata_t &inputdata ) +{ + int nNewColor = clamp( FastFloatToSmallInt( inputdata.value.Float() ), 0, 255 ); + SetColor( m_clrRender->r, nNewColor, m_clrRender->b ); +} + +void CSprite::InputColorBlueValue( inputdata_t &inputdata ) +{ + int nNewColor = clamp( FastFloatToSmallInt( inputdata.value.Float() ), 0, 255 ); + SetColor( m_clrRender->r, m_clrRender->g, nNewColor ); +} + +//----------------------------------------------------------------------------- +// Purpose: Input handler that toggles the sprite between hidden and shown. +//----------------------------------------------------------------------------- +void CSprite::InputToggleSprite( inputdata_t &inputdata ) +{ + if ( !IsEffectActive( EF_NODRAW ) ) + { + TurnOff(); + } + else + { + TurnOn(); + } +} +#endif + +#if defined( CLIENT_DLL ) + +//----------------------------------------------------------------------------- +// Purpose: +// Output : float +//----------------------------------------------------------------------------- +float CSprite::GetRenderScale( void ) +{ + //See if we're done scaling + if ( ( m_flScaleTime == 0 ) || ( (m_flScaleTimeStart+m_flScaleTime) < gpGlobals->curtime ) ) + return m_flSpriteScale; + + //Get our percentage + float timeDelta = ( gpGlobals->curtime - m_flScaleTimeStart ) / m_flScaleTime; + + //Return the result + return ( m_flStartScale + ( ( m_flDestScale - m_flStartScale ) * timeDelta ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: Get the rendered extents of the sprite +//----------------------------------------------------------------------------- +void CSprite::GetRenderBounds( Vector &vecMins, Vector &vecMaxs ) +{ + float flScale = GetRenderScale() * 0.5f; + + // If our scale is normalized we need to convert that to actual world units + if ( m_bWorldSpaceScale == false ) + { + CEngineSprite *psprite = (CEngineSprite *) modelinfo->GetModelExtraData( GetModel() ); + if ( psprite ) + { + float flSize = MAX( psprite->GetWidth(), psprite->GetHeight() ); + flScale *= flSize; + } + } + + vecMins.Init( -flScale, -flScale, -flScale ); + vecMaxs.Init( flScale, flScale, flScale ); + +#if 0 + // Visualize the bounds + debugoverlay->AddBoxOverlay( GetRenderOrigin(), vecMins, vecMaxs, GetRenderAngles(), 255, 255, 255, 0, 0.01f ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int CSprite::GetRenderBrightness( void ) +{ + //See if we're done scaling + if ( ( m_flBrightnessTime == 0 ) || ( (m_flBrightnessTimeStart+m_flBrightnessTime) < gpGlobals->curtime ) ) + { + return m_nBrightness; + } + + //Get our percentage + float timeDelta = ( gpGlobals->curtime - m_flBrightnessTimeStart ) / m_flBrightnessTime; + + float brightness = ( (float) m_nStartBrightness + ( (float) ( m_nDestBrightness - m_nStartBrightness ) * timeDelta ) ); + + //Return the result + return (int) brightness; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSprite::OnDataChanged( DataUpdateType_t updateType ) +{ + BaseClass::OnDataChanged( updateType ); + + // Only think when sapping + SetNextClientThink( CLIENT_THINK_ALWAYS ); + if ( updateType == DATA_UPDATE_CREATED ) + { + m_flStartScale = m_flDestScale = m_flSpriteScale; + m_nStartBrightness = m_nDestBrightness = m_nBrightness; + } + + UpdateVisibility(); +} + +void CSprite::ClientThink( void ) +{ + BaseClass::ClientThink(); + + // Module render colors over time + if ( m_flSpriteScale != m_flDestScale ) + { + m_flStartScale = m_flDestScale; + m_flDestScale = m_flSpriteScale; + m_flScaleTimeStart = gpGlobals->curtime; + } + + if ( m_nBrightness != m_nDestBrightness ) + { + m_nStartBrightness = m_nDestBrightness; + m_nDestBrightness = m_nBrightness; + m_flBrightnessTimeStart = gpGlobals->curtime; + } +} + +extern bool g_bRenderingScreenshot; +extern ConVar r_drawviewmodel; + +//----------------------------------------------------------------------------- +// Purpose: +// Input : flags - +// Output : int +//----------------------------------------------------------------------------- +int CSprite::DrawModel( int flags ) +{ + VPROF_BUDGET( "CSprite::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); + //See if we should draw + if ( !IsVisible() || ( m_bReadyToDraw == false ) ) + return 0; + +#ifdef PORTAL + if ( ( !g_pPortalRender->IsRenderingPortal() && !m_bDrawInMainRender ) || + ( g_pPortalRender->IsRenderingPortal() && !m_bDrawInPortalRender ) ) + { + return 0; + } +#endif //#ifdef PORTAL + + // Tracker 16432: If rendering a savegame screenshot then don't draw sprites + // who have viewmodels as their moveparent + if ( g_bRenderingScreenshot || !r_drawviewmodel.GetBool() ) + { + C_BaseViewModel *vm = dynamic_cast< C_BaseViewModel * >( GetMoveParent() ); + if ( vm ) + { + return 0; + } + } + + //Must be a sprite + if ( modelinfo->GetModelType( GetModel() ) != mod_sprite ) + { + Assert( 0 ); + return 0; + } + + float renderscale = GetRenderScale(); + if ( m_bWorldSpaceScale ) + { + CEngineSprite *psprite = ( CEngineSprite * )modelinfo->GetModelExtraData( GetModel() ); + float flMinSize = MIN( psprite->GetWidth(), psprite->GetHeight() ); + renderscale /= flMinSize; + } + + //Draw it + int drawn = DrawSprite( + this, + GetModel(), + GetAbsOrigin(), + GetAbsAngles(), + m_flFrame, // sprite frame to render + m_hAttachedToEntity, // attach to + m_nAttachment, // attachment point + GetRenderMode(), // rendermode + m_nRenderFX, + GetRenderBrightness(), // alpha + m_clrRender->r, + m_clrRender->g, + m_clrRender->b, + renderscale, // sprite scale + GetHDRColorScale() // HDR Color Scale + ); + + return drawn; +} + + +const Vector& CSprite::GetRenderOrigin() +{ + 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; +} + +#endif + +//----------------------------------------------------------------------------- +// Purpose: oriented sprites +// CSprites swap the roll and yaw angle inputs, and rotate the yaw 180 degrees +//----------------------------------------------------------------------------- + +#if !defined( CLIENT_DLL ) +IMPLEMENT_SERVERCLASS_ST( CSpriteOriented, DT_SpriteOriented ) +END_SEND_TABLE() +#else +#undef CSpriteOriented +IMPLEMENT_CLIENTCLASS_DT(C_SpriteOriented, DT_SpriteOriented, CSpriteOriented) +#define CSpriteOriented C_SpriteOriented +END_RECV_TABLE() +#endif + +#if !defined( CLIENT_DLL ) + +void CSpriteOriented::Spawn( void ) +{ + // save a copy of the angles, CSprite swaps the yaw and roll + QAngle angles = GetAbsAngles(); + BaseClass::Spawn(); + // ORIENTED sprites "forward" vector points in the players "view" direction, not the direction "out" from the sprite (gah) + angles.y = anglemod( angles.y + 180 ); + SetAbsAngles( angles ); +} + +#else + +bool CSpriteOriented::IsTransparent( void ) +{ + return true; +} + +#endif |