From f56bb35301836e56582a575a75864392a0177875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20P=2E=20Tjern=C3=B8?= Date: Mon, 2 Dec 2013 19:31:46 -0800 Subject: Fix line endings. WHAMMY. --- mp/src/game/shared/Sprite.cpp | 1736 ++++++++++++++++++++--------------------- 1 file changed, 868 insertions(+), 868 deletions(-) (limited to 'mp/src/game/shared/Sprite.cpp') 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( 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( 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 -- cgit v1.2.3